radeon_bo_gem.c revision 6281cf1b4310ff0b7670677cb4113a89ebf0b619
16bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse/* 22fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Copyright © 2008 Dave Airlie 32fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Copyright © 2008 Jérôme Glisse 42fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * All Rights Reserved. 56bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse * 62fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Permission is hereby granted, free of charge, to any person obtaining 72fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * a copy of this software and associated documentation files (the 82fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * "Software"), to deal in the Software without restriction, including 92fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * without limitation the rights to use, copy, modify, merge, publish, 102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * distribute, sub license, and/or sell copies of the Software, and to 112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * permit persons to whom the Software is furnished to do so, subject to 122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * the following conditions: 136bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse * 142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 206bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 212fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * USE OR OTHER DEALINGS IN THE SOFTWARE. 222fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * 232fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * The above copyright notice and this permission notice (including the 242fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * next paragraph) shall be included in all copies or substantial portions 252fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * of the Software. 262fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie */ 272fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie/* 282fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Authors: 292fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Dave Airlie 302fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie * Jérôme Glisse <glisse@freedesktop.org> 312fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie */ 322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#ifdef HAVE_CONFIG_H 332fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <config.h> 342fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#endif 352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdio.h> 362fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdint.h> 372fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <stdlib.h> 382fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <string.h> 392fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <errno.h> 4058ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst#include "libdrm.h" 412fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "xf86drm.h" 42966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen#include "xf86atomic.h" 432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "drm.h" 442fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_drm.h" 452fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo.h" 46125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie#include "radeon_bo_int.h" 472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo_gem.h" 483163cfe4db925429760407e77140e2d595338bc2Dave Airlie#include <fcntl.h> 492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct radeon_bo_gem { 500980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse struct radeon_bo_int base; 510980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse uint32_t name; 520980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse int map_count; 530980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse atomic_t reloc_in_cs; 540980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse void *priv_ptr; 552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}; 562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct bo_manager_gem { 582fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct radeon_bo_manager base; 592fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}; 602fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 61125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi); 62125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie 632fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestatic struct radeon_bo *bo_open(struct radeon_bo_manager *bom, 642fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie uint32_t handle, 652fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie uint32_t size, 662fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie uint32_t alignment, 672fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie uint32_t domains, 682fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie uint32_t flags) 692fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct radeon_bo_gem *bo; 712fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie int r; 722fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem)); 742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (bo == NULL) { 752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return NULL; 762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 782fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.bom = bom; 792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.handle = 0; 802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.size = size; 812fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.alignment = alignment; 822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.domains = domains; 832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.flags = flags; 842fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.ptr = NULL; 85966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen atomic_set(&bo->reloc_in_cs, 0); 862fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->map_count = 0; 872fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (handle) { 882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_gem_open open_arg; 892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie memset(&open_arg, 0, sizeof(open_arg)); 912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie open_arg.name = handle; 92b84314a86ea4ad30e0f57a71b4ef0fa138fb24c6Jerome Glisse r = drmIoctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg); 932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (r != 0) { 942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie free(bo); 952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return NULL; 962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.handle = open_arg.handle; 982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.size = open_arg.size; 992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->name = handle; 1002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } else { 1012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_radeon_gem_create args; 1022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 1032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.size = size; 1042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.alignment = alignment; 1052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.initial_domain = bo->base.domains; 1062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.flags = 0; 1072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.handle = 0; 1082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE, 1092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie &args, sizeof(args)); 1102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo->base.handle = args.handle; 1112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (r) { 1122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie fprintf(stderr, "Failed to allocate :\n"); 1132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie fprintf(stderr, " size : %d bytes\n", size); 1142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie fprintf(stderr, " alignment : %d bytes\n", alignment); 1152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie fprintf(stderr, " domains : %d\n", bo->base.domains); 1162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie free(bo); 1172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return NULL; 1182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 1192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 1202fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie radeon_bo_ref((struct radeon_bo*)bo); 1212fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return (struct radeon_bo*)bo; 1222fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 1232fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 124125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic void bo_ref(struct radeon_bo_int *boi) 1252fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 1262fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 1272fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 128125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic struct radeon_bo *bo_unref(struct radeon_bo_int *boi) 1292fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 130125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi; 1312fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_gem_close args; 1322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 133125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie if (boi->cref) { 134125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie return (struct radeon_bo *)boi; 1352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 136322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie if (bo_gem->priv_ptr) { 1376281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov drm_munmap(bo_gem->priv_ptr, boi->size); 1382fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 1392fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 140a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle /* Zero out args to make valgrind happy */ 141a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle memset(&args, 0, sizeof(args)); 142a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle 1432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie /* close object */ 144125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 145125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_CLOSE, &args); 1462fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie memset(bo_gem, 0, sizeof(struct radeon_bo_gem)); 1472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie free(bo_gem); 1482fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return NULL; 1492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 1502fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 151125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_map(struct radeon_bo_int *boi, int write) 1522fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 153125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi; 1542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_radeon_gem_mmap args; 1552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie int r; 1562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie void *ptr; 1572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 15819d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer if (bo_gem->map_count++ != 0) { 15919d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer return 0; 16019d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer } 16119d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer if (bo_gem->priv_ptr) { 1626bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse goto wait; 163322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie } 164322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie 165125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie boi->ptr = NULL; 166a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle 167a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle /* Zero out args to make valgrind happy */ 168a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle memset(&args, 0, sizeof(args)); 169125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 1702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.offset = 0; 171125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.size = (uint64_t)boi->size; 172125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = drmCommandWriteRead(boi->bom->fd, 1732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie DRM_RADEON_GEM_MMAP, 1742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie &args, 1752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie sizeof(args)); 1762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (r) { 1772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n", 178125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie boi, boi->handle, r); 1792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return r; 1802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 1816281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov ptr = drm_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr); 1822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (ptr == MAP_FAILED) 1832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return -errno; 184322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie bo_gem->priv_ptr = ptr; 1851978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airliewait: 186125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie boi->ptr = bo_gem->priv_ptr; 187125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = bo_wait(boi); 1881978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie if (r) 189125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie return r; 1901978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie return 0; 1912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 1922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 193125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_unmap(struct radeon_bo_int *boi) 1942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 195125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi; 1962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 1972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (--bo_gem->map_count > 0) { 1982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return 0; 1992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 2006281cf1b4310ff0b7670677cb4113a89ebf0b619Emil Velikov //drm_munmap(bo->ptr, bo->size); 201125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie boi->ptr = NULL; 2022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return 0; 2032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 2042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 205125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi) 2062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 2072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_radeon_gem_wait_idle args; 2082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie int ret; 2092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 210a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle /* Zero out args to make valgrind happy */ 211a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle memset(&args, 0, sizeof(args)); 212125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 2132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie do { 214a0178c00c70f4b47e09ed7564fc2ccde611231a0Mark Kettenis ret = drmCommandWrite(boi->bom->fd, DRM_RADEON_GEM_WAIT_IDLE, 215a0178c00c70f4b47e09ed7564fc2ccde611231a0Mark Kettenis &args, sizeof(args)); 2162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } while (ret == -EBUSY); 2172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return ret; 2182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 2192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 220125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_is_busy(struct radeon_bo_int *boi, uint32_t *domain) 221caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen{ 222caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen struct drm_radeon_gem_busy args; 223caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen int ret; 224caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen 225125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 226caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen args.domain = 0; 227caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen 228125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie ret = drmCommandWriteRead(boi->bom->fd, DRM_RADEON_GEM_BUSY, 2296bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse &args, sizeof(args)); 230caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen 231caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen *domain = args.domain; 232caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen return ret; 233caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen} 234caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen 235125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_set_tiling(struct radeon_bo_int *boi, uint32_t tiling_flags, 2366bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse uint32_t pitch) 2374507863058a10d00c982975daf396f83caee0fe2Dave Airlie{ 2384507863058a10d00c982975daf396f83caee0fe2Dave Airlie struct drm_radeon_gem_set_tiling args; 2394507863058a10d00c982975daf396f83caee0fe2Dave Airlie int r; 2404507863058a10d00c982975daf396f83caee0fe2Dave Airlie 241125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 2424507863058a10d00c982975daf396f83caee0fe2Dave Airlie args.tiling_flags = tiling_flags; 2434507863058a10d00c982975daf396f83caee0fe2Dave Airlie args.pitch = pitch; 2444507863058a10d00c982975daf396f83caee0fe2Dave Airlie 245125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = drmCommandWriteRead(boi->bom->fd, 2466bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse DRM_RADEON_GEM_SET_TILING, 2476bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse &args, 2486bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse sizeof(args)); 2494507863058a10d00c982975daf396f83caee0fe2Dave Airlie return r; 2504507863058a10d00c982975daf396f83caee0fe2Dave Airlie} 2514507863058a10d00c982975daf396f83caee0fe2Dave Airlie 252125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags, 2536bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse uint32_t *pitch) 2544507863058a10d00c982975daf396f83caee0fe2Dave Airlie{ 2558420743301a36dc1316fadf53bf8e1478068400aMarek Olšák struct drm_radeon_gem_set_tiling args = {}; 2564507863058a10d00c982975daf396f83caee0fe2Dave Airlie int r; 2574507863058a10d00c982975daf396f83caee0fe2Dave Airlie 258125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie args.handle = boi->handle; 2594507863058a10d00c982975daf396f83caee0fe2Dave Airlie 260125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = drmCommandWriteRead(boi->bom->fd, 2616bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse DRM_RADEON_GEM_GET_TILING, 2626bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse &args, 2636bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse sizeof(args)); 2644507863058a10d00c982975daf396f83caee0fe2Dave Airlie 2654507863058a10d00c982975daf396f83caee0fe2Dave Airlie if (r) 2666bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse return r; 2674507863058a10d00c982975daf396f83caee0fe2Dave Airlie 2684507863058a10d00c982975daf396f83caee0fe2Dave Airlie *tiling_flags = args.tiling_flags; 2694507863058a10d00c982975daf396f83caee0fe2Dave Airlie *pitch = args.pitch; 2704507863058a10d00c982975daf396f83caee0fe2Dave Airlie return r; 2714507863058a10d00c982975daf396f83caee0fe2Dave Airlie} 2724507863058a10d00c982975daf396f83caee0fe2Dave Airlie 2732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestatic struct radeon_bo_funcs bo_gem_funcs = { 2742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo_open, 2752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo_ref, 2762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo_unref, 2772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo_map, 2782fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bo_unmap, 27939970c67b77014caac9a4c3a33765ac7a312b54eDave Airlie bo_wait, 28039970c67b77014caac9a4c3a33765ac7a312b54eDave Airlie NULL, 2814507863058a10d00c982975daf396f83caee0fe2Dave Airlie bo_set_tiling, 2824507863058a10d00c982975daf396f83caee0fe2Dave Airlie bo_get_tiling, 283caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen bo_is_busy, 2842fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}; 2852fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 28658ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd) 2872fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 2882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct bo_manager_gem *bomg; 2892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 2902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem)); 2912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (bomg == NULL) { 2922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return NULL; 2932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 2942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bomg->base.funcs = &bo_gem_funcs; 2952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie bomg->base.fd = fd; 2962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return (struct radeon_bo_manager*)bomg; 2972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 2982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 29958ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom) 3002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 3012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom; 3022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 3032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie if (bom == NULL) { 3042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return; 3052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie } 3062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie free(bomg); 3072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 3082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 30958ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public uint32_t 31058ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_name_bo(struct radeon_bo *bo) 3112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 3122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 3132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return bo_gem->name; 3142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 3152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 31658ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public void * 31758ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_get_reloc_in_cs(struct radeon_bo *bo) 318966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen{ 319966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 320966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen return &bo_gem->reloc_in_cs; 321966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen} 322966c9907c040b4fe4b288b4a9d82598797aee743Pauli Nieminen 32358ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public int 32458ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name) 325fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie{ 3260980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 327125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 328fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie struct drm_gem_flink flink; 329fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie int r; 330fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie 3310980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse if (bo_gem->name) { 3320980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse *name = bo_gem->name; 3330980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse return 0; 3340980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse } 335fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie flink.handle = bo->handle; 336125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_FLINK, &flink); 337fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie if (r) { 3386bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse return r; 339fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie } 3400980633afd9c7eecc0c75ef3bea4d3c6b7aa1898Jerome Glisse bo_gem->name = flink.name; 341fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie *name = flink.name; 342fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie return 0; 343fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie} 344fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie 34558ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public int 34658ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain) 3472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{ 348125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie struct radeon_bo_int *boi = (struct radeon_bo_int *)bo; 3492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie struct drm_radeon_gem_set_domain args; 3502fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie int r; 3512fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 3522fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.handle = bo->handle; 3532fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.read_domains = read_domains; 3542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie args.write_domain = write_domain; 3552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie 356125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie r = drmCommandWriteRead(boi->bom->fd, 3572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie DRM_RADEON_GEM_SET_DOMAIN, 3582fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie &args, 3592fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie sizeof(args)); 3602fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie return r; 3612fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie} 3623163cfe4db925429760407e77140e2d595338bc2Dave Airlie 36358ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public int radeon_gem_prime_share_bo(struct radeon_bo *bo, int *handle) 3643163cfe4db925429760407e77140e2d595338bc2Dave Airlie{ 3653163cfe4db925429760407e77140e2d595338bc2Dave Airlie struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; 3663163cfe4db925429760407e77140e2d595338bc2Dave Airlie int ret; 3673163cfe4db925429760407e77140e2d595338bc2Dave Airlie 3683163cfe4db925429760407e77140e2d595338bc2Dave Airlie ret = drmPrimeHandleToFD(bo_gem->base.bom->fd, bo->handle, DRM_CLOEXEC, handle); 3693163cfe4db925429760407e77140e2d595338bc2Dave Airlie return ret; 3703163cfe4db925429760407e77140e2d595338bc2Dave Airlie} 3713163cfe4db925429760407e77140e2d595338bc2Dave Airlie 37258ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstdrm_public struct radeon_bo * 37358ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_gem_bo_open_prime(struct radeon_bo_manager *bom, int fd_handle, uint32_t size) 3743163cfe4db925429760407e77140e2d595338bc2Dave Airlie{ 3753163cfe4db925429760407e77140e2d595338bc2Dave Airlie struct radeon_bo_gem *bo; 3763163cfe4db925429760407e77140e2d595338bc2Dave Airlie int r; 3773163cfe4db925429760407e77140e2d595338bc2Dave Airlie uint32_t handle; 3783163cfe4db925429760407e77140e2d595338bc2Dave Airlie 3793163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem)); 3803163cfe4db925429760407e77140e2d595338bc2Dave Airlie if (bo == NULL) { 3813163cfe4db925429760407e77140e2d595338bc2Dave Airlie return NULL; 3823163cfe4db925429760407e77140e2d595338bc2Dave Airlie } 3833163cfe4db925429760407e77140e2d595338bc2Dave Airlie 3843163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.bom = bom; 3853163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.handle = 0; 3863163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.size = size; 3873163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.alignment = 0; 3883163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.domains = RADEON_GEM_DOMAIN_GTT; 3893163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.flags = 0; 3903163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.ptr = NULL; 3913163cfe4db925429760407e77140e2d595338bc2Dave Airlie atomic_set(&bo->reloc_in_cs, 0); 3923163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->map_count = 0; 3933163cfe4db925429760407e77140e2d595338bc2Dave Airlie 3943163cfe4db925429760407e77140e2d595338bc2Dave Airlie r = drmPrimeFDToHandle(bom->fd, fd_handle, &handle); 3953163cfe4db925429760407e77140e2d595338bc2Dave Airlie if (r != 0) { 3963163cfe4db925429760407e77140e2d595338bc2Dave Airlie free(bo); 3973163cfe4db925429760407e77140e2d595338bc2Dave Airlie return NULL; 3983163cfe4db925429760407e77140e2d595338bc2Dave Airlie } 3993163cfe4db925429760407e77140e2d595338bc2Dave Airlie 4003163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->base.handle = handle; 4013163cfe4db925429760407e77140e2d595338bc2Dave Airlie bo->name = handle; 4023163cfe4db925429760407e77140e2d595338bc2Dave Airlie 4033163cfe4db925429760407e77140e2d595338bc2Dave Airlie radeon_bo_ref((struct radeon_bo *)bo); 4043163cfe4db925429760407e77140e2d595338bc2Dave Airlie return (struct radeon_bo *)bo; 4053163cfe4db925429760407e77140e2d595338bc2Dave Airlie 4063163cfe4db925429760407e77140e2d595338bc2Dave Airlie} 407