177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/**************************************************************************
277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * All Rights Reserved.
577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * copy of this software and associated documentation files (the
877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * "Software"), to deal in the Software without restriction, including
977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * without limitation the rights to use, copy, modify, merge, publish,
1077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * distribute, sub license, and/or sell copies of the Software, and to
1177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * permit persons to whom the Software is furnished to do so, subject to
1277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * the following conditions:
1377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
1477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * The above copyright notice and this permission notice (including the
1577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * next paragraph) shall be included in all copies or substantial portions
1677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * of the Software.
1777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
1877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
2677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt **************************************************************************/
2777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
2877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/* Provide additional functionality on top of bufmgr buffers:
2977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *   - 2d semantics and blit operations
3077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *   - refcounting of buffers for multiple images in a buffer.
3177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *   - refcounting of buffer mappings.
3277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *   - some logic for moving the buffers to the best memory pools for
3377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *     given operations.
3477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt *
3577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * Most of this is to make it easier to implement the fixed-layout
3677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * mipmap tree required by intel hardware in the face of GL's
3777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * programming interface where each image can be specifed in random
3877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * order and it isn't clear what layout the tree should have until the
3977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * last moment.
4077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
4177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
42f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include <sys/ioctl.h>
43f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include <errno.h>
44f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
450aa610571162eafc8c31c3d26c3676b6aead82dfKristian Høgsberg#include "main/hash.h"
4677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_context.h"
4777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_regions.h"
4877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_blit.h"
4977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_buffer_objects.h"
50f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include "intel_bufmgr.h"
5177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#include "intel_batchbuffer.h"
5277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
5377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt#define FILE_DEBUG_FLAG DEBUG_REGION
5477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
551d112207716774b32c0cc846304c2c50bf40e812Robert Ellison/* This should be set to the maximum backtrace size desired.
561d112207716774b32c0cc846304c2c50bf40e812Robert Ellison * Set it to 0 to disable backtrace debugging.
571d112207716774b32c0cc846304c2c50bf40e812Robert Ellison */
581d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#define DEBUG_BACKTRACE_SIZE 0
591d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
601d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#if DEBUG_BACKTRACE_SIZE == 0
611d112207716774b32c0cc846304c2c50bf40e812Robert Ellison/* Use the standard debug output */
621d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#define _DBG(...) DBG(__VA_ARGS__)
631d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#else
641d112207716774b32c0cc846304c2c50bf40e812Robert Ellison/* Use backtracing debug output */
651d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);}
661d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
671d112207716774b32c0cc846304c2c50bf40e812Robert Ellison/* Backtracing debug support */
681d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#include <execinfo.h>
691d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
701d112207716774b32c0cc846304c2c50bf40e812Robert Ellisonstatic void
711d112207716774b32c0cc846304c2c50bf40e812Robert Ellisondebug_backtrace(void)
721d112207716774b32c0cc846304c2c50bf40e812Robert Ellison{
731d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   void *trace[DEBUG_BACKTRACE_SIZE];
741d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   char **strings = NULL;
751d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   int traceSize;
761d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   register int i;
771d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
781d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE);
791d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   strings = backtrace_symbols(trace, traceSize);
801d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   if (strings == NULL) {
811d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      DBG("no backtrace:");
821d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      return;
831d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   }
841d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
851d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   /* Spit out all the strings with a colon separator.  Ignore
861d112207716774b32c0cc846304c2c50bf40e812Robert Ellison    * the first, since we don't really care about the call
871d112207716774b32c0cc846304c2c50bf40e812Robert Ellison    * to debug_backtrace() itself.  Skip until the final "/" in
881d112207716774b32c0cc846304c2c50bf40e812Robert Ellison    * the trace to avoid really long lines.
891d112207716774b32c0cc846304c2c50bf40e812Robert Ellison    */
901d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   for (i = 1; i < traceSize; i++) {
911d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      char *p = strings[i], *slash = strings[i];
921d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      while (*p) {
931d112207716774b32c0cc846304c2c50bf40e812Robert Ellison         if (*p++ == '/') {
941d112207716774b32c0cc846304c2c50bf40e812Robert Ellison            slash = p;
951d112207716774b32c0cc846304c2c50bf40e812Robert Ellison         }
961d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      }
971d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
981d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      DBG("%s:", slash);
991d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   }
1001d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
1011d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   /* Free up the memory, and we're done */
1021d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   free(strings);
1031d112207716774b32c0cc846304c2c50bf40e812Robert Ellison}
1041d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
1051d112207716774b32c0cc846304c2c50bf40e812Robert Ellison#endif
1061d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
1071d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
1081d112207716774b32c0cc846304c2c50bf40e812Robert Ellison
10977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/* XXX: Thread safety?
11077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
1114cb1d6a25e4749ec5e0389ca3da468adbbe5299eEric Anholtvoid *
112f8377b411dfe3c879eaab11bb86f509178796bd1Chad Versaceintel_region_map(struct intel_context *intel, struct intel_region *region,
113f8377b411dfe3c879eaab11bb86f509178796bd1Chad Versace                 GLbitfield mode)
11477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
115e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace   /* We have the region->map_refcount controlling mapping of the BO because
116e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * in software fallbacks we may end up mapping the same buffer multiple
117e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * times on Mesa's behalf, so we refcount our mappings to make sure that
118e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * the pointer stays valid until the end of the unmap chain.  However, we
119e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * must not emit any batchbuffers between the start of mapping and the end
120e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * of unmapping, or further use of the map will be incoherent with the GPU
121e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * rendering done by that batchbuffer. Hence we assert in
122e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * intel_batchbuffer_flush() that that doesn't happen, which means that the
123e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    * flush is only needed on first map of the buffer.
124e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace    */
125ae1bfb6427cc10a851c80e020cbdc210fe238d85Eric Anholt
1260e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt   if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
1270e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt      if (drm_intel_bo_busy(region->bo)) {
1280e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt         perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
1290e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt      }
1300e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt   }
1310e723b135bfd59868c92c3ae243f1adaedaec3a5Eric Anholt
1321d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   _DBG("%s %p\n", __FUNCTION__, region);
133cdcfd5d1d60179e60e3a0a47dda71bfe91083105Anuj Phogat   if (!region->map_refcount) {
134e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace      intel_flush(&intel->ctx);
135e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace
136bb35000b4b6dfe60048b2f5d60bc102c4a7fd791Eric Anholt      if (region->tiling != I915_TILING_NONE)
1378004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt	 drm_intel_gem_bo_map_gtt(region->bo);
1381ba96651e12b3c74fb9c8f5a61b183ef36a27b1eEric Anholt      else
1392e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke	 drm_intel_bo_map(region->bo, true);
140e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace
1418004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt      region->map = region->bo->virtual;
1429cb777eb71dde895ca0ad3454a9b44252e9b402eYuanhan Liu   }
1439cb777eb71dde895ca0ad3454a9b44252e9b402eYuanhan Liu   if (region->map) {
1449cb777eb71dde895ca0ad3454a9b44252e9b402eYuanhan Liu      intel->num_mapped_regions++;
1459cb777eb71dde895ca0ad3454a9b44252e9b402eYuanhan Liu      region->map_refcount++;
14677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
14777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
14877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   return region->map;
14977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
15077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
15177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtvoid
1527c71ef3a3d0cf2620525f468960cdc76a0fb0d33Eric Anholtintel_region_unmap(struct intel_context *intel, struct intel_region *region)
15377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
1541d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   _DBG("%s %p\n", __FUNCTION__, region);
15577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (!--region->map_refcount) {
156bb35000b4b6dfe60048b2f5d60bc102c4a7fd791Eric Anholt      if (region->tiling != I915_TILING_NONE)
1578004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt	 drm_intel_gem_bo_unmap_gtt(region->bo);
1581ba96651e12b3c74fb9c8f5a61b183ef36a27b1eEric Anholt      else
1598004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt	 drm_intel_bo_unmap(region->bo);
160e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace
16177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      region->map = NULL;
162e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace      --intel->num_mapped_regions;
163e9adfa2ba1af9c3579b25327335c47118b6c7c3fChad Versace      assert(intel->num_mapped_regions >= 0);
16477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
16577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
16677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
167c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsbergstatic struct intel_region *
1689087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsbergintel_region_alloc_internal(struct intel_screen *screen,
1698db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt			    GLuint cpp,
1708db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt			    GLuint width, GLuint height, GLuint pitch,
1719087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg			    uint32_t tiling, drm_intel_bo *buffer)
17277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
173c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg   struct intel_region *region;
17477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
175c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg   region = calloc(sizeof(*region), 1);
17685cfe321805264686ef8989e45a911a999ed928aChris Wilson   if (region == NULL)
17785cfe321805264686ef8989e45a911a999ed928aChris Wilson      return region;
17885cfe321805264686ef8989e45a911a999ed928aChris Wilson
17977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   region->cpp = cpp;
1808db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt   region->width = width;
1818db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt   region->height = height;
18277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   region->pitch = pitch;
18377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   region->refcount = 1;
1848004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt   region->bo = buffer;
1859087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   region->tiling = tiling;
1869087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   region->screen = screen;
187f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
1881d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   _DBG("%s <-- %p\n", __FUNCTION__, region);
18977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   return region;
19077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
19177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
192c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsbergstruct intel_region *
1939087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsbergintel_region_alloc(struct intel_screen *screen,
1941ba96651e12b3c74fb9c8f5a61b183ef36a27b1eEric Anholt		   uint32_t tiling,
195da011faf48155a5c02ebc1fe1fa20a4f54b8c657Eric Anholt                   GLuint cpp, GLuint width, GLuint height,
1962e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke		   bool expect_accelerated_upload)
197c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg{
19834474fa4119378ef9fbb9fb557cc19c0a1ca1f7eEric Anholt   drm_intel_bo *buffer;
199179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt   unsigned long flags = 0;
200179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt   unsigned long aligned_pitch;
201f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   struct intel_region *region;
202c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg
203179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt   if (expect_accelerated_upload)
204179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt      flags |= BO_ALLOC_FOR_RENDER;
205179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt
2069087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "region",
207179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt				     width, height, cpp,
208179d2c0e0bcf96fc40107882ccab909af8c89853Eric Anholt				     &tiling, &aligned_pitch, flags);
209f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   if (buffer == NULL)
210f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson      return NULL;
211c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg
212f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   region = intel_region_alloc_internal(screen, cpp, width, height,
213f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson                                        aligned_pitch / cpp, tiling, buffer);
214f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   if (region == NULL) {
215f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson      drm_intel_bo_unreference(buffer);
216f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson      return NULL;
217f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   }
218f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson
219f627d429bda8196fd20f2023374ad6d34e4becb6Chris Wilson   return region;
220c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg}
221c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg
2222e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkebool
223f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsbergintel_region_flink(struct intel_region *region, uint32_t *name)
224f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg{
225f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg   if (region->name == 0) {
2268004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt      if (drm_intel_bo_flink(region->bo, &region->name))
2272e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke	 return false;
228f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg
229f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg      _mesa_HashInsert(region->screen->named_regions,
230f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg		       region->name, region);
231f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg   }
232f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg
233f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg   *name = region->name;
234f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg
2352e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke   return true;
236f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg}
237f301932dba4cc75e810e0c051e39247128a899fcKristian Høgsberg
238c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsbergstruct intel_region *
2399087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsbergintel_region_alloc_for_handle(struct intel_screen *screen,
2408db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt			      GLuint cpp,
2418db761409dadc2e899d4e7107eff3aa07b07aa11Eric Anholt			      GLuint width, GLuint height, GLuint pitch,
242f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg			      GLuint handle, const char *name)
243c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg{
2442d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg   struct intel_region *region, *dummy;
24534474fa4119378ef9fbb9fb557cc19c0a1ca1f7eEric Anholt   drm_intel_bo *buffer;
246dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt   int ret;
2479087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   uint32_t bit_6_swizzle, tiling;
248c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg
2499087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   region = _mesa_HashLookup(screen->named_regions, handle);
2502d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg   if (region != NULL) {
2512d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      dummy = NULL;
2522d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      if (region->width != width || region->height != height ||
2532d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg	  region->cpp != cpp || region->pitch != pitch) {
2542d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg	 fprintf(stderr,
2552d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg		 "Region for name %d already exists but is not compatible\n",
2562d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg		 handle);
2572d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg	 return NULL;
2582d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      }
2592d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      intel_region_reference(&dummy, region);
2602d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      return dummy;
2612d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg   }
2622d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg
2639087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   buffer = intel_bo_gem_create_from_name(screen->bufmgr, name, handle);
2649087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   if (buffer == NULL)
2659087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg      return NULL;
2669087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
267dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt   if (ret != 0) {
268dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt      fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
269dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt	      handle, name, strerror(-ret));
2709087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg      drm_intel_bo_unreference(buffer);
2719087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg      return NULL;
2729087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   }
2739087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg
2749087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   region = intel_region_alloc_internal(screen, cpp,
2759087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg					width, height, pitch, tiling, buffer);
2769087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   if (region == NULL) {
2779087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg      drm_intel_bo_unreference(buffer);
278dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt      return NULL;
279dd17cd600a25ad916185eaeec968563adbab76f9Eric Anholt   }
280f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
2812d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg   region->name = handle;
2829087ba128089ed0dc00e6eb38f37126fb7557d3bKristian Høgsberg   _mesa_HashInsert(screen->named_regions, handle, region);
2832d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg
284f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   return region;
285c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg}
286c5c73c1b605611faf0f06df9b5d08d8984388238Kristian Høgsberg
28777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtvoid
28877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtintel_region_reference(struct intel_region **dst, struct intel_region *src)
28977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
290036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt   _DBG("%s: %p(%d) -> %p(%d)\n", __FUNCTION__,
291036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt	*dst, *dst ? (*dst)->refcount : 0, src, src ? src->refcount : 0);
292036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt
293036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt   if (src != *dst) {
294036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt      if (*dst)
295036b74a7f8adc745c7af089129f070b8e5b8f4bdEric Anholt	 intel_region_release(dst);
296f56b569e9af356c11869ee49a4669bb01b75397eKristian Høgsberg
297d8f65c07e9f3a5948c8bee95482bcab651b33c01Brian Paul      if (src)
298d8f65c07e9f3a5948c8bee95482bcab651b33c01Brian Paul         src->refcount++;
29977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      *dst = src;
30077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
30177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
30277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
30377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholtvoid
304f75843a517bd188639e6866db2a7b04de3524e16Dave Airlieintel_region_release(struct intel_region **region_handle)
30577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
306f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   struct intel_region *region = *region_handle;
307f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
3081d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   if (region == NULL) {
3091d112207716774b32c0cc846304c2c50bf40e812Robert Ellison      _DBG("%s NULL\n", __FUNCTION__);
31077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      return;
3111d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   }
31277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3131d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
314f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
315f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   ASSERT(region->refcount > 0);
316f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   region->refcount--;
31777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
318f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   if (region->refcount == 0) {
319f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie      assert(region->map_refcount == 0);
32077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
3218004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt      drm_intel_bo_unreference(region->bo);
322f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
3232d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg      if (region->name > 0)
3242d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg	 _mesa_HashRemove(region->screen->named_regions, region->name);
3252d99588b3556928a0879b4160210ac771dbf1f0bKristian Høgsberg
326f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie      free(region);
32777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
328f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   *region_handle = NULL;
32977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
33077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
33177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/*
33277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * XXX Move this into core Mesa?
33377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
334a9a483b43ec090408148d069bc184c0a21323654Zou Nan haivoid
33577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt_mesa_copy_rect(GLubyte * dst,
33677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint cpp,
33777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint dst_pitch,
33877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint dst_x,
33977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint dst_y,
34077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint width,
34177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint height,
34277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                const GLubyte * src,
34377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                GLuint src_pitch, GLuint src_x, GLuint src_y)
34477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
34577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   GLuint i;
34677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
34777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   dst_pitch *= cpp;
34877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   src_pitch *= cpp;
34977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   dst += dst_x * cpp;
35077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   src += src_x * cpp;
35177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   dst += dst_y * dst_pitch;
352e1e48ea15c1fe448f0b69e086b66c1123dc98bb7Eric Anholt   src += src_y * src_pitch;
35377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   width *= cpp;
35477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
35577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (width == dst_pitch && width == src_pitch)
35677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      memcpy(dst, src, height * width);
35777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   else {
35877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      for (i = 0; i < height; i++) {
35977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         memcpy(dst, src, width);
36077a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         dst += dst_pitch;
36177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt         src += src_pitch;
36277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt      }
36377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   }
36477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
36577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
36677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt/* Copy rectangular sub-regions. Need better logic about when to
36777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt * push buffers into AGP - will currently do so whenever possible.
36877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt */
3692e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkebool
3707c71ef3a3d0cf2620525f468960cdc76a0fb0d33Eric Anholtintel_region_copy(struct intel_context *intel,
37177a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                  struct intel_region *dst,
37277a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                  GLuint dst_offset,
37377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                  GLuint dstx, GLuint dsty,
37477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                  struct intel_region *src,
37577a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt                  GLuint src_offset,
376246d59c29e3e5a57dcf2f60ad429eb1606193ef0Eric Anholt                  GLuint srcx, GLuint srcy, GLuint width, GLuint height,
3772e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke		  bool flip,
378246d59c29e3e5a57dcf2f60ad429eb1606193ef0Eric Anholt		  GLenum logicop)
37977a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt{
380a589da14dee0c2a32e6e529f1a390b01a3ee4001Eric Anholt   uint32_t src_pitch = src->pitch;
381a589da14dee0c2a32e6e529f1a390b01a3ee4001Eric Anholt
3821d112207716774b32c0cc846304c2c50bf40e812Robert Ellison   _DBG("%s\n", __FUNCTION__);
38377a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
38477a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   if (intel == NULL)
3852e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunke      return false;
38677a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
38777a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt   assert(src->cpp == dst->cpp);
38877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt
389a589da14dee0c2a32e6e529f1a390b01a3ee4001Eric Anholt   if (flip)
390a589da14dee0c2a32e6e529f1a390b01a3ee4001Eric Anholt      src_pitch = -src_pitch;
391a589da14dee0c2a32e6e529f1a390b01a3ee4001Eric Anholt
3928f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt   return intelEmitCopyBlit(intel,
3938f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt			    dst->cpp,
3948004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt			    src_pitch, src->bo, src_offset, src->tiling,
3958004a1cb95b8a195f3f4bbaa8d39d2f3297167deEric Anholt			    dst->pitch, dst->bo, dst_offset, dst->tiling,
3968f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt			    srcx, srcy, dstx, dsty, width, height,
3978f81a6468fdbc7320800ea497791e3e1b8f782caEric Anholt			    logicop);
39877a5bcaff43df8d54e0e0ef833726e4b41d7eb36Eric Anholt}
3993ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
4003ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry/**
4013ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * This function computes masks that may be used to select the bits of the X
4023ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * and Y coordinates that indicate the offset within a tile.  If the region is
4033ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * untiled, the masks are set to 0.
4043ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry */
4053ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berryvoid
4063ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berryintel_region_get_tile_masks(struct intel_region *region,
40796fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry                            uint32_t *mask_x, uint32_t *mask_y,
40896fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry                            bool map_stencil_as_y_tiled)
4093ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry{
4103ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   int cpp = region->cpp;
41196fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry   uint32_t tiling = region->tiling;
4123ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
41396fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry   if (map_stencil_as_y_tiled)
41496fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry      tiling = I915_TILING_Y;
41596fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry
41696fd94ba9421c7c3072988f999ee869534f2bc2aPaul Berry   switch (tiling) {
4173ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   default:
4183ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert(false);
4193ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_NONE:
4203ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      *mask_x = *mask_y = 0;
4213ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      break;
4223ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_X:
4233ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      *mask_x = 512 / cpp - 1;
4243ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      *mask_y = 7;
4253ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      break;
4263ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_Y:
4273ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      *mask_x = 128 / cpp - 1;
4283ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      *mask_y = 31;
4293ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      break;
4303ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   }
4313ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry}
4323ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
4333ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry/**
4343ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * Compute the offset (in bytes) from the start of the region to the given x
4353ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * and y coordinate.  For tiled regions, caller must ensure that x and y are
4363ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry * multiples of the tile size.
4373ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry */
4383ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berryuint32_t
4393ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berryintel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
44068da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry                                uint32_t y, bool map_stencil_as_y_tiled)
4413ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry{
4423ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   int cpp = region->cpp;
4433ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   uint32_t pitch = region->pitch * cpp;
44468da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry   uint32_t tiling = region->tiling;
44568da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry
44668da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry   if (map_stencil_as_y_tiled) {
44768da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry      tiling = I915_TILING_Y;
4483ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry
44968da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry      /* When mapping a W-tiled stencil buffer as Y-tiled, each 64-high W-tile
45068da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       * gets transformed into a 32-high Y-tile.  Accordingly, the pitch of
45168da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       * the resulting region is twice the pitch of the original region, since
45268da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       * each row in the Y-tiled view corresponds to two rows in the actual
45368da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       * W-tiled surface.  So we need to correct the pitch before computing
45468da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       * the offsets.
45568da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry       */
45668da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry      pitch *= 2;
45768da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry   }
45868da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry
45968da5dfc2c2e9c0aca47431076be0cd43406d4aaPaul Berry   switch (tiling) {
4603ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   default:
4613ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert(false);
4623ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_NONE:
4633ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      return y * pitch + x * cpp;
4643ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_X:
4653ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert((x % (512 / cpp)) == 0);
4663ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert((y % 8) == 0);
4673ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      return y * pitch + x / (512 / cpp) * 4096;
4683ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   case I915_TILING_Y:
4693ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert((x % (128 / cpp)) == 0);
4703ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      assert((y % 32) == 0);
4713ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry      return y * pitch + x / (128 / cpp) * 4096;
4723ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry   }
4733ec0e55b63db3c1067f3bbf4563beb3b98a19288Paul Berry}
474