intel_regions.c revision 2d57e9640819c7889304d1de9dd5500a1a0f66de
1036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim/**************************************************************************
240b9f96587c191269a41b20bd2bd5000fc9db259Jaegeuk Kim *
3036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
4036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * All Rights Reserved.
5036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
6036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * Permission is hereby granted, free of charge, to any person obtaining a
7036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * copy of this software and associated documentation files (the
8036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * "Software"), to deal in the Software without restriction, including
9036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * without limitation the rights to use, copy, modify, merge, publish,
10036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * distribute, sub license, and/or sell copies of the Software, and to
1140b9f96587c191269a41b20bd2bd5000fc9db259Jaegeuk Kim * permit persons to whom the Software is furnished to do so, subject to
1240b9f96587c191269a41b20bd2bd5000fc9db259Jaegeuk Kim * the following conditions:
13036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
14e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim * The above copyright notice and this permission notice (including the
15036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * next paragraph) shall be included in all copies or substantial portions
16e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim * of the Software.
17036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
18036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20dd1ba078fae270c4174a221a873026fea85aae32Sven-Göran Bergh * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21dd1ba078fae270c4174a221a873026fea85aae32Sven-Göran Bergh * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22dd1ba078fae270c4174a221a873026fea85aae32Sven-Göran Bergh * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23dd1ba078fae270c4174a221a873026fea85aae32Sven-Göran Bergh * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
26036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim **************************************************************************/
27036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
28036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim/* Provide additional functionality on top of bufmgr buffers:
29036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *   - 2d semantics and blit operations
30036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *   - refcounting of buffers for multiple images in a buffer.
31036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *   - refcounting of buffer mappings.
32036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *   - some logic for moving the buffers to the best memory pools for
33036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *     given operations.
34036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
35036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * Most of this is to make it easier to implement the fixed-layout
36036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * mipmap tree required by intel hardware in the face of GL's
37036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * programming interface where each image can be specifed in random
38036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * order and it isn't clear what layout the tree should have until the
39036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * last moment.
40e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim */
41e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
42e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include <sys/ioctl.h>
43e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include <errno.h>
44e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
45e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_context.h"
46e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_regions.h"
47e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_blit.h"
48e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_buffer_objects.h"
49e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_bufmgr.h"
50e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_batchbuffer.h"
51e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include "intel_chipset.h"
52e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
53e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#define FILE_DEBUG_FLAG DEBUG_REGION
54e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
55e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim/* This should be set to the maximum backtrace size desired.
56e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim * Set it to 0 to disable backtrace debugging.
57e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim */
58e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#define DEBUG_BACKTRACE_SIZE 0
59e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
60e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#if DEBUG_BACKTRACE_SIZE == 0
61e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim/* Use the standard debug output */
62e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#define _DBG(...) DBG(__VA_ARGS__)
63e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#else
64e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim/* Use backtracing debug output */
65e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);}
66e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
67e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim/* Backtracing debug support */
68e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#include <execinfo.h>
69e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
70e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kimstatic void
71e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kimdebug_backtrace(void)
72e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim{
73e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   void *trace[DEBUG_BACKTRACE_SIZE];
74e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   char **strings = NULL;
75e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   int traceSize;
76e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   register int i;
77e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
78e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE);
79e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   strings = backtrace_symbols(trace, traceSize);
80e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   if (strings == NULL) {
81e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      DBG("no backtrace:");
82e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      return;
83e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   }
84e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
85e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   /* Spit out all the strings with a colon separator.  Ignore
86e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim    * the first, since we don't really care about the call
87e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim    * to debug_backtrace() itself.  Skip until the final "/" in
88e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim    * the trace to avoid really long lines.
89e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim    */
90e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   for (i = 1; i < traceSize; i++) {
91e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      char *p = strings[i], *slash = strings[i];
92e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      while (*p) {
93e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim         if (*p++ == '/') {
94e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim            slash = p;
95e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim         }
96e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      }
97e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
98e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      DBG("%s:", slash);
99e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   }
100e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
101e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   /* Free up the memory, and we're done */
102e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   free(strings);
103e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim}
104e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
105e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim#endif
106e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
107e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
108e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
109e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim/* XXX: Thread safety?
110e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim */
111e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk KimGLubyte *
112e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kimintel_region_map(struct intel_context *intel, struct intel_region *region)
113e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim{
114e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   _DBG("%s %p\n", __FUNCTION__, region);
115e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim   if (!region->map_refcount++) {
116e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      if (region->pbo)
117e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim         intel_region_cow(intel, region);
118e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
119e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      if (intel->intelScreen->kernel_exec_fencing)
120e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim	 drm_intel_gem_bo_map_gtt(region->buffer);
121e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      else
122036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 dri_bo_map(region->buffer, GL_TRUE);
123036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      region->map = region->buffer->virtual;
124036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
125036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
1262784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   return region->map;
127036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
128036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
129036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
130036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimintel_region_unmap(struct intel_context *intel, struct intel_region *region)
131036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
132036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s %p\n", __FUNCTION__, region);
133036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (!--region->map_refcount) {
134036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (intel->intelScreen->kernel_exec_fencing)
135036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 drm_intel_gem_bo_unmap_gtt(region->buffer);
136e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      else
1372784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim	 dri_bo_unmap(region->buffer);
1382784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      region->map = NULL;
1392784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   }
1402784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim}
1412784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1422784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimstatic struct intel_region *
1432784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimintel_region_alloc_internal(struct intel_context *intel,
1442784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			    GLuint cpp,
1452784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			    GLuint width, GLuint height, GLuint pitch,
1462784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			    dri_bo *buffer)
1479799d6364dc93e1fd259d812d4a50ed984a6456bMike Fleetwood{
1482784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   struct intel_region *region;
1492784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1502784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (buffer == NULL) {
1512784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      _DBG("%s <-- NULL\n", __FUNCTION__);
152e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      return NULL;
153fef98ebdf3a7728017cb3d0ae4ffedc5405e531dChangman Lee   }
154036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
155036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region = calloc(sizeof(*region), 1);
156036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->cpp = cpp;
157036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->width = width;
158036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->height = height;
159036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->pitch = pitch;
160036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->refcount = 1;
161036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->buffer = buffer;
1622784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1632784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   /* Default to no tiling */
164036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->tiling = I915_TILING_NONE;
165036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE;
1662784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
167036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s <-- %p\n", __FUNCTION__, region);
1682784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   return region;
1692784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim}
1702784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1712784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimstruct intel_region *
1722784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimintel_region_alloc(struct intel_context *intel,
1732784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim		   uint32_t tiling,
1742784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                   GLuint cpp, GLuint width, GLuint height, GLuint pitch,
1752784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim		   GLboolean expect_accelerated_upload)
1762784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim{
1772784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   dri_bo *buffer;
1782784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   struct intel_region *region;
1792784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1802784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (expect_accelerated_upload) {
1812784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
1822784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim					     pitch * cpp * height, 64);
1832784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   } else {
1842784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      buffer = drm_intel_bo_alloc(intel->bufmgr, "region",
1852784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim				  pitch * cpp * height, 64);
1862784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   }
1872784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1882784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   region = intel_region_alloc_internal(intel, cpp, width, height,
1892784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim					pitch, buffer);
1902784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1912784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (tiling != I915_TILING_NONE) {
1922784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      assert(((pitch * cpp) & 511) == 0);
1932784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      drm_intel_bo_set_tiling(buffer, &tiling, pitch * cpp);
1942784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      drm_intel_bo_get_tiling(buffer, &region->tiling, &region->bit_6_swizzle);
1952784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   }
1962784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
1972784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   return region;
1982784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim}
1992784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
2002784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimstruct intel_region *
2012784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimintel_region_alloc_for_handle(struct intel_context *intel,
2022784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			      GLuint cpp,
2032784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			      GLuint width, GLuint height, GLuint pitch,
2042784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			      GLuint handle, const char *name)
2052784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim{
206036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   struct intel_region *region;
2072784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   dri_bo *buffer;
2082784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   int ret;
2092784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
2102784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
2112784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
2122784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   region = intel_region_alloc_internal(intel, cpp,
2132784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim					width, height, pitch, buffer);
2142784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (region == NULL)
2152784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      return region;
2162784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
2172784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   ret = dri_bo_get_tiling(region->buffer, &region->tiling,
2182784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim			   &region->bit_6_swizzle);
2192784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (ret != 0) {
220036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
221bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim	      handle, name, strerror(-ret));
222bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      intel_region_release(&region);
223bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      return NULL;
224bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   }
225bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
226bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   return region;
227bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim}
228bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
229bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimvoid
230bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimintel_region_reference(struct intel_region **dst, struct intel_region *src)
231bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim{
232bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (src)
233bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      _DBG("%s %p %d\n", __FUNCTION__, src, src->refcount);
234bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
235bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   assert(*dst == NULL);
236bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (src) {
237bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      src->refcount++;
238bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      *dst = src;
239bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   }
240bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim}
241bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
242bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimvoid
243bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimintel_region_release(struct intel_region **region_handle)
244bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim{
245bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   struct intel_region *region = *region_handle;
246bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
247bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (region == NULL) {
248bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      _DBG("%s NULL\n", __FUNCTION__);
249bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      return;
250bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   }
251bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
252036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
253036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
254036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   ASSERT(region->refcount > 0);
255036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->refcount--;
256036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
25722a75edd47adea7d466ecd245c62b75fd1866628Jaegeuk Kim   if (region->refcount == 0) {
25822a75edd47adea7d466ecd245c62b75fd1866628Jaegeuk Kim      assert(region->map_refcount == 0);
25922a75edd47adea7d466ecd245c62b75fd1866628Jaegeuk Kim
26022a75edd47adea7d466ecd245c62b75fd1866628Jaegeuk Kim      if (region->pbo)
26122a75edd47adea7d466ecd245c62b75fd1866628Jaegeuk Kim	 region->pbo->region = NULL;
262036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      region->pbo = NULL;
263bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      dri_bo_unreference(region->buffer);
264036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
265bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      if (region->classic_map != NULL) {
266036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 drmUnmap(region->classic_map,
267036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim			region->pitch * region->cpp * region->height);
268bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      }
269036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
270036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      free(region);
271036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
272036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   *region_handle = NULL;
273036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
274036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
275036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim/*
276036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * XXX Move this into core Mesa?
277bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim */
278036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
279036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim_mesa_copy_rect(GLubyte * dst,
280036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                GLuint cpp,
281036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                GLuint dst_pitch,
282036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                GLuint dst_x,
283036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                GLuint dst_y,
284bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                GLuint width,
285bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                GLuint height,
286036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                const GLubyte * src,
287036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                GLuint src_pitch, GLuint src_x, GLuint src_y)
288036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
289bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   GLuint i;
290036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
291036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   dst_pitch *= cpp;
292036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   src_pitch *= cpp;
293036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   dst += dst_x * cpp;
2942784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   src += src_x * cpp;
2952784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   dst += dst_y * dst_pitch;
2962784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   src += src_y * dst_pitch;
2972784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   width *= cpp;
2982784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
2992784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (width == dst_pitch && width == src_pitch)
3002784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      memcpy(dst, src, height * width);
3012784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   else {
3022784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      for (i = 0; i < height; i++) {
3032784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim         memcpy(dst, src, width);
3042784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim         dst += dst_pitch;
3052784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim         src += src_pitch;
3062784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      }
3072784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   }
308036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
309036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
310036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
311bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim/* Upload data to a rectangular sub-region.  Lots of choices how to do this:
312bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim *
313bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim * - memcpy by span to current destination
314036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * - upload data as new buffer and blit
315036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim *
316f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim * Currently always memcpy.
317b5af7953f81018c9edd844bd1bc9f4f6752a756aJaegeuk Kim */
318036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
319036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimintel_region_data(struct intel_context *intel,
320036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  struct intel_region *dst,
321036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  GLuint dst_offset,
322bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                  GLuint dstx, GLuint dsty,
323bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                  const void *src, GLuint src_pitch,
324bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                  GLuint srcx, GLuint srcy, GLuint width, GLuint height)
325bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim{
326bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   GLboolean locked = GL_FALSE;
327bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
328bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   _DBG("%s\n", __FUNCTION__);
329bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
330bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (intel == NULL)
331bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      return;
332bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
333bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (dst->pbo) {
334bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      if (dstx == 0 &&
335bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim          dsty == 0 && width == dst->pitch && height == dst->height)
336bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim         intel_region_release_pbo(intel, dst);
337b5af7953f81018c9edd844bd1bc9f4f6752a756aJaegeuk Kim      else
338bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim         intel_region_cow(intel, dst);
339036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
340036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
341036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (!intel->locked) {
342f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim      LOCK_HARDWARE(intel);
343f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim      locked = GL_TRUE;
344036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
345036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
346036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
347036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                   dst->cpp,
348036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                   dst->pitch,
349036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                   dstx, dsty, width, height, src, src_pitch, srcx, srcy);
350036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
351036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   intel_region_unmap(intel, dst);
352036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
353036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (locked)
3542784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      UNLOCK_HARDWARE(intel);
355036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
356036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
357036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
3582784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim/* Copy rectangular sub-regions. Need better logic about when to
359036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * push buffers into AGP - will currently do so whenever possible.
360036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim */
3612784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimvoid
3622784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kimintel_region_copy(struct intel_context *intel,
3632784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                  struct intel_region *dst,
3642784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                  GLuint dst_offset,
3652784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                  GLuint dstx, GLuint dsty,
3662784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                  struct intel_region *src,
3672784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                  GLuint src_offset,
368036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  GLuint srcx, GLuint srcy, GLuint width, GLuint height)
369bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim{
370bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   _DBG("%s\n", __FUNCTION__);
371036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
372036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (intel == NULL)
373036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      return;
374036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
375036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (dst->pbo) {
376036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (dstx == 0 &&
377bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim          dsty == 0 && width == dst->pitch && height == dst->height)
378036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim         intel_region_release_pbo(intel, dst);
379036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      else
380036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim         intel_region_cow(intel, dst);
381036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
382036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
383036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   assert(src->cpp == dst->cpp);
384036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
385036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   intelEmitCopyBlit(intel,
386036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                     dst->cpp,
387036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                     src->pitch, src->buffer, src_offset, src->tiling,
388036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                     dst->pitch, dst->buffer, dst_offset, dst->tiling,
3892784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                     srcx, srcy, dstx, dsty, width, height,
390036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		     GL_COPY);
391036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
392bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
393bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim/* Fill a rectangular sub-region.  Need better logic about when to
394bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim * push buffers into AGP - will currently do so whenever possible.
395036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim */
396036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
397036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimintel_region_fill(struct intel_context *intel,
398036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  struct intel_region *dst,
399036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  GLuint dst_offset,
400036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  GLuint dstx, GLuint dsty,
401036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                  GLuint width, GLuint height, GLuint color)
402036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
403bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   _DBG("%s\n", __FUNCTION__);
404bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
405bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (intel == NULL)
406bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      return;
407036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
4082784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (dst->pbo) {
409036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (dstx == 0 &&
410036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim          dsty == 0 && width == dst->pitch && height == dst->height)
41199b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim         intel_region_release_pbo(intel, dst);
41299b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      else
41399b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim         intel_region_cow(intel, dst);
41499b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   }
41599b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim
4162784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   intelEmitFillBlit(intel,
4172784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                     dst->cpp,
4182784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                     dst->pitch, dst->buffer, dst_offset, dst->tiling,
4192784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim                     dstx, dsty, width, height, color);
4202784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim}
4212784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
4222784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim/* Attach to a pbo, discarding our data.  Effectively zero-copy upload
423bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim * the pbo's data.
424036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim */
425bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimvoid
426bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimintel_region_attach_pbo(struct intel_context *intel,
427bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim                        struct intel_region *region,
428036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                        struct intel_buffer_object *pbo)
429036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
430036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (region->pbo == pbo)
431036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      return;
432036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
433036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s %p %p\n", __FUNCTION__, region, pbo);
4342784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
43599b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   /* If there is already a pbo attached, break the cow tie now.
43699b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim    * Don't call intel_region_release_pbo() as that would
437bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim    * unnecessarily allocate a new buffer we would have to immediately
438bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim    * discard.
439bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim    */
4402784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (region->pbo) {
44199b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      region->pbo->region = NULL;
44299b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      region->pbo = NULL;
44399b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   }
44499b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim
44599b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   if (region->buffer) {
44699b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      dri_bo_unreference(region->buffer);
44799b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      region->buffer = NULL;
44899b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   }
449bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
4502784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   region->pbo = pbo;
4512784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   region->pbo->region = region;
452bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   dri_bo_reference(pbo->buffer);
453bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   region->buffer = pbo->buffer;
454bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim}
455036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
456036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
457036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim/* Break the COW tie to the pbo and allocate a new buffer.
458036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * The pbo gets to keep the data.
459036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim */
460036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
46199b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kimintel_region_release_pbo(struct intel_context *intel,
462036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                         struct intel_region *region)
463036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
464036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s %p\n", __FUNCTION__, region);
465036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   assert(region->buffer == region->pbo->buffer);
466bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   region->pbo->region = NULL;
467bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   region->pbo = NULL;
468bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   dri_bo_unreference(region->buffer);
469036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->buffer = NULL;
470bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
471bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   region->buffer = dri_bo_alloc(intel->bufmgr, "region",
472bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim				 region->pitch * region->cpp * region->height,
473036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim				 64);
474036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
4752784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
476bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim/* Break the COW tie to the pbo.  Both the pbo and the region end up
477036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim * with a copy of the data.
478036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim */
479036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimvoid
480036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimintel_region_cow(struct intel_context *intel, struct intel_region *region)
481036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
482036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   struct intel_buffer_object *pbo = region->pbo;
483036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   GLboolean was_locked = intel->locked;
484036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
485bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (intel == NULL)
486bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      return;
487bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
488bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   intel_region_release_pbo(intel, region);
489036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
490036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   assert(region->cpp * region->pitch * region->height == pbo->Base.Size);
491036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
492036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   _DBG("%s %p (%d bytes)\n", __FUNCTION__, region, pbo->Base.Size);
493036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
494bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   /* Now blit from the texture buffer to the new buffer:
495bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim    */
496bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
497bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   was_locked = intel->locked;
498bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim   if (!was_locked)
499036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      LOCK_HARDWARE(intel);
500036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
501036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   intelEmitCopyBlit(intel,
502036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		     region->cpp,
503036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		     region->pitch, region->buffer, 0, region->tiling,
504bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		     region->pitch, pbo->buffer, 0, region->tiling,
505bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		     0, 0, 0, 0,
506bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		     region->pitch, region->height,
507bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		     GL_COPY);
508bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
509036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (!was_locked)
510036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      UNLOCK_HARDWARE(intel);
511036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
512036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
513036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimdri_bo *
514bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kimintel_region_buffer(struct intel_context *intel,
515036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim                    struct intel_region *region, GLuint flag)
516036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim{
517036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   if (region->pbo) {
518036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (flag == INTEL_WRITE_PART)
519036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim         intel_region_cow(intel, region);
520036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      else if (flag == INTEL_WRITE_FULL)
521bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim         intel_region_release_pbo(intel, region);
522036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
523036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
524036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   return region->buffer;
525036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim}
526036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
527036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimstatic struct intel_region *
528036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kimintel_recreate_static(struct intel_context *intel,
529036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		      const char *name,
530036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		      struct intel_region *region,
531036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		      intelRegion *region_desc)
5322784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim{
5332784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   intelScreenPrivate *intelScreen = intel->intelScreen;
5342784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   int ret;
5352784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim
5362784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (region == NULL) {
5372784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      region = calloc(sizeof(*region), 1);
5382784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      region->refcount = 1;
53999b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      _DBG("%s creating new region %p\n", __FUNCTION__, region);
540f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim   }
541f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim   else {
5422784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim      _DBG("%s %p\n", __FUNCTION__, region);
543f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim   }
54499b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim
54599b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   if (intel->ctx.Visual.rgbBits == 24)
54699b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      region->cpp = 4;
54799b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   else
54899b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim      region->cpp = intel->ctx.Visual.rgbBits / 8;
54999b74393403aab847587d6c37cd1aaf1d935a81dJaegeuk Kim   region->pitch = intelScreen->pitch;
550036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->width = intelScreen->width;
551036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   region->height = intelScreen->height;
552036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
5532784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim   if (region->buffer != NULL) {
554036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      dri_bo_unreference(region->buffer);
555f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim      region->buffer = NULL;
556036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim   }
557036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
558f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim   if (intel->ttm) {
559036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      assert(region_desc->bo_handle != -1);
560036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      region->buffer = intel_bo_gem_create_from_name(intel->bufmgr,
561bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim						     name,
562bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim						     region_desc->bo_handle);
563bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim
564036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      ret = dri_bo_get_tiling(region->buffer, &region->tiling,
565036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim			      &region->bit_6_swizzle);
566bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim      if (ret != 0) {
567036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
568bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		 region_desc->bo_handle, name, strerror(-ret));
569036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 intel_region_release(&region);
570036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 return NULL;
571036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      }
572f5f440f08643f6b35ad0dd70a54805a5383c4a62Jaegeuk Kim   } else {
573036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (region->classic_map != NULL) {
574036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 drmUnmap(region->classic_map,
575bbf6e62360d8eae415dc7d19325b7d70079db0e1Jaegeuk Kim		  region->pitch * region->cpp * region->height);
576036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 region->classic_map = NULL;
577036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      }
578036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      ret = drmMap(intel->driFd, region_desc->handle,
579036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		   region->pitch * region->cpp * region->height,
580036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim		   &region->classic_map);
581036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      if (ret != 0) {
582036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 fprintf(stderr, "Failed to drmMap %s buffer\n", name);
583036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 free(region);
584036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim	 return NULL;
585036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      }
586036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim
587036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim      region->buffer = intel_bo_fake_alloc_static(intel->bufmgr,
588e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim						  name,
589e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim						  region_desc->offset,
590e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim						  region->pitch * region->cpp *
591e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim						  region->height,
592e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim						  region->classic_map);
593e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
594e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      /* The sarea just gives us a boolean for whether it's tiled or not,
595e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim       * instead of which tiling mode it is.  Guess.
596e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim       */
597e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      if (region_desc->tiled) {
598e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim	 if (IS_965(intel->intelScreen->deviceID) &&
599e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim	     region_desc == &intelScreen->depth)
600e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim	    region->tiling = I915_TILING_Y;
6015043dffbd1d2b89c71966dde31780b0ca313b5c9Jaegeuk Kim	 else
6025043dffbd1d2b89c71966dde31780b0ca313b5c9Jaegeuk Kim	    region->tiling = I915_TILING_X;
603e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim      } else {
6045043dffbd1d2b89c71966dde31780b0ca313b5c9Jaegeuk Kim	 region->tiling = I915_TILING_NONE;
6055043dffbd1d2b89c71966dde31780b0ca313b5c9Jaegeuk Kim      }
606e69e4378500b836863dfb7f6e88e39935f23ae80Jaegeuk Kim
6075043dffbd1d2b89c71966dde31780b0ca313b5c9Jaegeuk Kim      region->bit_6_swizzle = I915_BIT_6_SWIZZLE_NONE;
608   }
609
610   assert(region->buffer != NULL);
611
612   return region;
613}
614
615/**
616 * Create intel_region structs to describe the static front, back, and depth
617 * buffers created by the xserver.
618 *
619 * Although FBO's mean we now no longer use these as render targets in
620 * all circumstances, they won't go away until the back and depth
621 * buffers become private, and the front buffer will remain even then.
622 *
623 * Note that these don't allocate video memory, just describe
624 * allocations alread made by the X server.
625 */
626void
627intel_recreate_static_regions(struct intel_context *intel)
628{
629   intelScreenPrivate *intelScreen = intel->intelScreen;
630
631   intel->front_region =
632      intel_recreate_static(intel, "front",
633			    intel->front_region,
634			    &intelScreen->front);
635
636   intel->back_region =
637      intel_recreate_static(intel, "back",
638			    intel->back_region,
639			    &intelScreen->back);
640
641   /* Still assumes front.cpp == depth.cpp.  We can kill this when we move to
642    * private buffers.
643    */
644   intel->depth_region =
645      intel_recreate_static(intel, "depth",
646			    intel->depth_region,
647			    &intelScreen->depth);
648}
649