radeon_bo_gem.c revision 6bf1ed2979ca56d3e8dd8938fc08e3810887ae8a
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 <sys/mman.h>
402fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include <errno.h>
412fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "xf86drm.h"
422fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "drm.h"
432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_drm.h"
442fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo.h"
45125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie#include "radeon_bo_int.h"
462fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie#include "radeon_bo_gem.h"
472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
482fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct radeon_bo_gem {
49125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_int base;
502fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    uint32_t            name;
512fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int                 map_count;
52322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    void *priv_ptr;
532fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
552fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct bo_manager_gem {
562fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_manager    base;
572fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
582fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
59125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi);
60125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie
612fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestatic struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
622fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t handle,
632fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t size,
642fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t alignment,
652fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t domains,
662fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                 uint32_t flags)
672fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
682fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_gem *bo;
692fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
712fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
722fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bo == NULL) {
732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return NULL;
742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.bom = bom;
772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.handle = 0;
782fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.size = size;
792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.alignment = alignment;
802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.domains = domains;
812fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.flags = flags;
822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->base.ptr = NULL;
832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo->map_count = 0;
842fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (handle) {
852fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        struct drm_gem_open open_arg;
862fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
872fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        memset(&open_arg, 0, sizeof(open_arg));
882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        open_arg.name = handle;
89b84314a86ea4ad30e0f57a71b4ef0fa138fb24c6Jerome Glisse        r = drmIoctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        if (r != 0) {
912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            free(bo);
922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            return NULL;
932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        }
942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.handle = open_arg.handle;
952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.size = open_arg.size;
962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->name = handle;
972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    } else {
982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        struct drm_radeon_gem_create args;
992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
1002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.size = size;
1012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.alignment = alignment;
1022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.initial_domain = bo->base.domains;
1032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.flags = 0;
1042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        args.handle = 0;
1052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
1062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                &args, sizeof(args));
1072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        bo->base.handle = args.handle;
1082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        if (r) {
1092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "Failed to allocate :\n");
1102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   size      : %d bytes\n", size);
1112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   alignment : %d bytes\n", alignment);
1122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            fprintf(stderr, "   domains   : %d\n", bo->base.domains);
1132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            free(bo);
1142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie            return NULL;
1152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        }
1162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
1172fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    radeon_bo_ref((struct radeon_bo*)bo);
1182fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return (struct radeon_bo*)bo;
1192fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1202fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
121125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic void bo_ref(struct radeon_bo_int *boi)
1222fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
1232fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1242fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
125125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic struct radeon_bo *bo_unref(struct radeon_bo_int *boi)
1262fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
127125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1282fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_gem_close args;
1292fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
130125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    if (boi->cref) {
131125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        return (struct radeon_bo *)boi;
1322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
133322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    if (bo_gem->priv_ptr) {
134125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        munmap(bo_gem->priv_ptr, boi->size);
1352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
1362fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
137a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
138a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
139a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle
1402fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    /* close object */
141125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
142125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_CLOSE, &args);
1432fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
1442fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    free(bo_gem);
1452fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return NULL;
1462fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1472fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
148125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_map(struct radeon_bo_int *boi, int write)
1492fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
150125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1512fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_mmap args;
1522fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
1532fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    void *ptr;
1542fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
15519d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    if (bo_gem->map_count++ != 0) {
15619d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer        return 0;
15719d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    }
15819d6fadfa29993b261ebac2869b2289f6d3091c3Michel Dänzer    if (bo_gem->priv_ptr) {
1596bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        goto wait;
160322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    }
161322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie
162125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = NULL;
163a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle
164a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
165a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
166125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
1672fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.offset = 0;
168125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.size = (uint64_t)boi->size;
169125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
1702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            DRM_RADEON_GEM_MMAP,
1712fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            &args,
1722fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            sizeof(args));
1732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (r) {
1742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
175125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie                boi, boi->handle, r);
1762fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return r;
1772fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
178125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, boi->bom->fd, args.addr_ptr);
1792fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (ptr == MAP_FAILED)
1802fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return -errno;
181322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    bo_gem->priv_ptr = ptr;
1821978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airliewait:
183125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = bo_gem->priv_ptr;
184125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = bo_wait(boi);
1851978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie    if (r)
186125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        return r;
1871978f6d8d1215a9501882eb074901bcd0dfc0775Dave Airlie    return 0;
1882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
1892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
190125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_unmap(struct radeon_bo_int *boi)
1912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
192125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)boi;
1932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
1942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (--bo_gem->map_count > 0) {
1952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return 0;
1962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
197322cf6cf736b22b62656ac0431936b3cdb784038Dave Airlie    //munmap(bo->ptr, bo->size);
198125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    boi->ptr = NULL;
1992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return 0;
2002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
202125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_wait(struct radeon_bo_int *boi)
2032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
2042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_wait_idle args;
2052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int ret;
2062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
207a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    /* Zero out args to make valgrind happy */
208a5fb264257651d50afe84be7e20f91df41242aa8Nicolai Hähnle    memset(&args, 0, sizeof(args));
209125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    do {
211125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie        ret = drmCommandWriteRead(boi->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
2122fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                                  &args, sizeof(args));
2132fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    } while (ret == -EBUSY);
2142fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return ret;
2152fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2162fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
217125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_is_busy(struct radeon_bo_int *boi, uint32_t *domain)
218caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen{
219caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    struct drm_radeon_gem_busy args;
220caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    int ret;
221caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
222125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
223caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    args.domain = 0;
224caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
225125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    ret = drmCommandWriteRead(boi->bom->fd, DRM_RADEON_GEM_BUSY,
2266bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                              &args, sizeof(args));
227caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
228caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    *domain = args.domain;
229caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    return ret;
230caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen}
231caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen
232125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_set_tiling(struct radeon_bo_int *boi, uint32_t tiling_flags,
2336bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                         uint32_t pitch)
2344507863058a10d00c982975daf396f83caee0fe2Dave Airlie{
2354507863058a10d00c982975daf396f83caee0fe2Dave Airlie    struct drm_radeon_gem_set_tiling args;
2364507863058a10d00c982975daf396f83caee0fe2Dave Airlie    int r;
2374507863058a10d00c982975daf396f83caee0fe2Dave Airlie
238125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2394507863058a10d00c982975daf396f83caee0fe2Dave Airlie    args.tiling_flags = tiling_flags;
2404507863058a10d00c982975daf396f83caee0fe2Dave Airlie    args.pitch = pitch;
2414507863058a10d00c982975daf396f83caee0fe2Dave Airlie
242125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
2436bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            DRM_RADEON_GEM_SET_TILING,
2446bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            &args,
2456bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            sizeof(args));
2464507863058a10d00c982975daf396f83caee0fe2Dave Airlie    return r;
2474507863058a10d00c982975daf396f83caee0fe2Dave Airlie}
2484507863058a10d00c982975daf396f83caee0fe2Dave Airlie
249125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airliestatic int bo_get_tiling(struct radeon_bo_int *boi, uint32_t *tiling_flags,
2506bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                         uint32_t *pitch)
2514507863058a10d00c982975daf396f83caee0fe2Dave Airlie{
2524507863058a10d00c982975daf396f83caee0fe2Dave Airlie    struct drm_radeon_gem_set_tiling args;
2534507863058a10d00c982975daf396f83caee0fe2Dave Airlie    int r;
2544507863058a10d00c982975daf396f83caee0fe2Dave Airlie
255125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    args.handle = boi->handle;
2564507863058a10d00c982975daf396f83caee0fe2Dave Airlie
257125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
2586bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            DRM_RADEON_GEM_GET_TILING,
2596bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            &args,
2606bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse                            sizeof(args));
2614507863058a10d00c982975daf396f83caee0fe2Dave Airlie
2624507863058a10d00c982975daf396f83caee0fe2Dave Airlie    if (r)
2636bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        return r;
2644507863058a10d00c982975daf396f83caee0fe2Dave Airlie
2654507863058a10d00c982975daf396f83caee0fe2Dave Airlie    *tiling_flags = args.tiling_flags;
2664507863058a10d00c982975daf396f83caee0fe2Dave Airlie    *pitch = args.pitch;
2674507863058a10d00c982975daf396f83caee0fe2Dave Airlie    return r;
2684507863058a10d00c982975daf396f83caee0fe2Dave Airlie}
2694507863058a10d00c982975daf396f83caee0fe2Dave Airlie
2702fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestatic struct radeon_bo_funcs bo_gem_funcs = {
2712fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo_open,
2722fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo_ref,
2732fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo_unref,
2742fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo_map,
2752fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bo_unmap,
27639970c67b77014caac9a4c3a33765ac7a312b54eDave Airlie    bo_wait,
27739970c67b77014caac9a4c3a33765ac7a312b54eDave Airlie    NULL,
2784507863058a10d00c982975daf396f83caee0fe2Dave Airlie    bo_set_tiling,
2794507863058a10d00c982975daf396f83caee0fe2Dave Airlie    bo_get_tiling,
280caad8d85559709301c00760b9e8707d57f8c6c67Pauli Nieminen    bo_is_busy,
2812fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie};
2822fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
2832fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airliestruct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
2842fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
2852fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct bo_manager_gem *bomg;
2862fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
2872fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem));
2882fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bomg == NULL) {
2892fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return NULL;
2902fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
2912fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg->base.funcs = &bo_gem_funcs;
2922fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    bomg->base.fd = fd;
2932fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return (struct radeon_bo_manager*)bomg;
2942fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
2952fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
2962fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlievoid radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
2972fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
2982fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
2992fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3002fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    if (bom == NULL) {
3012fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie        return;
3022fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    }
3032fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    free(bomg);
3042fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
3052fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3062fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlieuint32_t radeon_gem_name_bo(struct radeon_bo *bo)
3072fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
3082fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
3092fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return bo_gem->name;
3102fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
3112fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
312fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlieint radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
313fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie{
314125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
315fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    struct drm_gem_flink flink;
316fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    int r;
317fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie
318fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    flink.handle = bo->handle;
319125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_FLINK, &flink);
320fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    if (r) {
3216bf1ed2979ca56d3e8dd8938fc08e3810887ae8aJerome Glisse        return r;
322fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    }
323fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    *name = flink.name;
324fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie    return 0;
325fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie}
326fbac5891b91c795de61f4d7cbc1a6799474364adDave Airlie
3272fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlieint radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
3282fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie{
329125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
3302fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    struct drm_radeon_gem_set_domain args;
3312fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    int r;
3322fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
3332fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.handle = bo->handle;
3342fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.read_domains = read_domains;
3352fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    args.write_domain = write_domain;
3362fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie
337125994ab30d4f0f126c62fa741ec62a52d69d7a8Dave Airlie    r = drmCommandWriteRead(boi->bom->fd,
3382fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            DRM_RADEON_GEM_SET_DOMAIN,
3392fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            &args,
3402fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie                            sizeof(args));
3412fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie    return r;
3422fa2db138ba989bfa1a8cd9ab66d83fb7369249eDave Airlie}
343