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, ®ion->tiling, ®ion->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, ®ion->tiling, 2182784bd55dd9730f3a5d2126c82094990fad053c1Jaegeuk Kim ®ion->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(®ion); 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, ®ion->tiling, 565036d45e551ca5405c726f8ccb51f446620cd4afJaegeuk Kim ®ion->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(®ion); 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 ®ion->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