radeon_drm_bo.c revision 1e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4
1de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák/*
2de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
3de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * All Rights Reserved.
4de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák *
5de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining
6de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * a copy of this software and associated documentation files (the
7de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * "Software"), to deal in the Software without restriction, including
8de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * without limitation the rights to use, copy, modify, merge, publish,
9de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * distribute, sub license, and/or sell copies of the Software, and to
10de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * permit persons to whom the Software is furnished to do so, subject to
11de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * the following conditions:
12de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák *
13de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * USE OR OTHER DEALINGS IN THE SOFTWARE.
21de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák *
22de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * The above copyright notice and this permission notice (including the
23de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * next paragraph) shall be included in all copies or substantial portions
24de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák * of the Software.
25de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák */
26de22d8f1eebd3245acccdb4098526ee1bf616c06Marek Olšák
276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#define _FILE_OFFSET_BITS 64
286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "radeon_drm_cs.h"
296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "util/u_hash_table.h"
316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "util/u_memory.h"
326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "util/u_simple_list.h"
336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "os/os_thread.h"
346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "state_tracker/drm_driver.h"
366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include <sys/ioctl.h>
386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include <sys/mman.h>
396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include <xf86drm.h>
406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include <errno.h>
416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#define RADEON_BO_FLAGS_MACRO_TILE  1
436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#define RADEON_BO_FLAGS_MICRO_TILE  2
446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#define RADEON_BO_FLAGS_MICRO_TILE_SQUARE 0x20
456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
461e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#ifndef DRM_RADEON_GEM_WAIT
471e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#define DRM_RADEON_GEM_WAIT		0x2b
481e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák
491e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#define RADEON_GEM_NO_WAIT	0x1
501e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#define RADEON_GEM_USAGE_READ	0x2
511e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#define RADEON_GEM_USAGE_WRITE	0x4
521e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák
531e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšákstruct drm_radeon_gem_wait {
541e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák	uint32_t	handle;
551e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák	uint32_t        flags;  /* one of RADEON_GEM_* */
561e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák};
571e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák
581e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák#endif
591e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák
601e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák
616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákextern const struct pb_vtbl radeon_bo_vtbl;
626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic INLINE struct radeon_bo *radeon_bo(struct pb_buffer *bo)
656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    assert(bo->vtbl == &radeon_bo_vtbl);
676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return (struct radeon_bo *)bo;
686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstruct radeon_bomgr {
716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Base class. */
726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_manager base;
736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Winsys. */
756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *rws;
766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* List of buffer handles and its mutex. */
786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct util_hash_table *bo_handles;
796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex bo_handles_mutex;
806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák};
816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic INLINE struct radeon_bomgr *radeon_bomgr(struct pb_manager *mgr)
836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return (struct radeon_bomgr *)mgr;
856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic struct radeon_bo *get_radeon_bo(struct pb_buffer *_buf)
886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo = NULL;
906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (_buf->vtbl == &radeon_bo_vtbl) {
926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        bo = radeon_bo(_buf);
936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    } else {
946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	struct pb_buffer *base_buf;
956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	pb_size offset;
966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	pb_get_base_buffer(_buf, &base_buf, &offset);
976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        if (base_buf->vtbl == &radeon_bo_vtbl)
996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            bo = radeon_bo(base_buf);
1006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
1016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return bo;
1036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1051e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšákstatic void radeon_bo_wait(struct pb_buffer *_buf, enum radeon_bo_usage usage)
1066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1072664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
1086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
109b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    while (p_atomic_read(&bo->num_active_ioctls)) {
110b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák        sched_yield();
111b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    }
112b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák
1131e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    if (bo->rws->info.drm_minor >= 12) {
1141e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_wait args = {};
1151e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1161e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.flags = usage;
1171e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
1181e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) == -EBUSY);
1191e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    } else {
1201e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_wait_idle args = {};
1211e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1221e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
1231e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) == -EBUSY);
1241e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    }
1256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1271e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšákstatic boolean radeon_bo_is_busy(struct pb_buffer *_buf,
1281e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                 enum radeon_bo_usage usage)
1296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1302664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
1316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
132b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    if (p_atomic_read(&bo->num_active_ioctls)) {
133b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák        return TRUE;
134b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    }
135b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák
1361e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    if (bo->rws->info.drm_minor >= 12) {
1371e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_wait args = {};
1381e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1391e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.flags = usage | RADEON_GEM_NO_WAIT;
1401e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
1411e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) != 0;
1421e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    } else {
1431e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_busy args = {};
1441e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1451e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
1461e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) != 0;
1471e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    }
1486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_destroy(struct pb_buffer *_buf)
1516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo = radeon_bo(_buf);
153c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    struct drm_gem_close args = {};
154c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák
155c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    if (bo->name) {
156c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        pipe_mutex_lock(bo->mgr->bo_handles_mutex);
157c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        util_hash_table_remove(bo->mgr->bo_handles,
158c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák			       (void*)(uintptr_t)bo->name);
159c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
160c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    }
1616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
162c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    if (bo->ptr)
163c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        munmap(bo->ptr, bo->size);
164c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák
165c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    /* Close object. */
166c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    args.handle = bo->handle;
167c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
168c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    pipe_mutex_destroy(bo->map_mutex);
169c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    FREE(bo);
1706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage)
1736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    unsigned res = 0;
1756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1766caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák    if (usage & PIPE_TRANSFER_WRITE)
1776caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák        res |= PB_USAGE_CPU_WRITE;
1786caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák
1796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (usage & PIPE_TRANSFER_DONTBLOCK)
1806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= PB_USAGE_DONTBLOCK;
1816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
1836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= PB_USAGE_UNSYNCHRONIZED;
1846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return res;
1866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void *radeon_bo_map_internal(struct pb_buffer *_buf,
1896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                    unsigned flags, void *flush_ctx)
1906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo = radeon_bo(_buf);
1926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_cs *cs = flush_ctx;
1936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_radeon_gem_mmap args = {};
1948decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    void *ptr;
1956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */
19745e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák    if (!(flags & PB_USAGE_UNSYNCHRONIZED)) {
19845e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */
19945e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        if (flags & PB_USAGE_DONTBLOCK) {
20045e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            if (radeon_bo_is_referenced_by_cs(cs, bo)) {
201d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
20245e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák                return NULL;
20345e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            }
20445e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák
2051e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák            if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
20645e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák                return NULL;
20745e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            }
20845e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        } else {
2096caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák            if (!(flags & PB_USAGE_CPU_WRITE)) {
2106caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                /* Mapping for read.
2116caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 *
2126caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * Since we are mapping for read, we don't need to wait
2136caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * if the GPU is using the buffer for read too
2146caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * (neither one is changing it).
2156caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 *
2166caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * Only check whether the buffer is being used for write. */
2176caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                if (radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
2186caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    cs->flush_cs(cs->flush_data, 0);
2191e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                    radeon_bo_wait((struct pb_buffer*)bo,
2201e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   RADEON_USAGE_READWRITE);
2211554e69e00566bc7255b82f5ea93b1f02f1a5bb3Marek Olšák                } else {
2221554e69e00566bc7255b82f5ea93b1f02f1a5bb3Marek Olšák                    /* XXX We could check whether the buffer is busy for write here. */
2231e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                    radeon_bo_wait((struct pb_buffer*)bo,
2241e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   RADEON_USAGE_READWRITE);
2251554e69e00566bc7255b82f5ea93b1f02f1a5bb3Marek Olšák                }
2265650a719f0c69c00954e47bd7a7b3e9433cb551dMarek Olšák            } else {
2276caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                /* Mapping for write. */
2286caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                if (radeon_bo_is_referenced_by_cs(cs, bo)) {
2296caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    cs->flush_cs(cs->flush_data, 0);
2306caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                } else {
2316caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    /* Try to avoid busy-waiting in radeon_bo_wait. */
2326caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    if (p_atomic_read(&bo->num_active_ioctls))
2336caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                        radeon_drm_cs_sync_flush(cs);
2346caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                }
2356caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák
2361e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                radeon_bo_wait((struct pb_buffer*)bo, RADEON_USAGE_READWRITE);
23745e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            }
2386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        }
2396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
2406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2418decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    /* Return the pointer if it's already mapped. */
2428decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (bo->ptr)
2438decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return bo->ptr;
2448decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák
2458decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    /* Map the buffer. */
2468decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_lock(bo->map_mutex);
247652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    /* Return the pointer if it's already mapped (in case of a race). */
248652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    if (bo->ptr) {
249652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
250652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák        return bo->ptr;
251652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    }
2528decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    args.handle = bo->handle;
2538decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    args.offset = 0;
2548decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    args.size = (uint64_t)bo->size;
2558decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (drmCommandWriteRead(bo->rws->fd,
2568decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            DRM_RADEON_GEM_MMAP,
2578decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            &args,
2588decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            sizeof(args))) {
2598decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
2608decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        fprintf(stderr, "radeon: gem_mmap failed: %p 0x%08X\n",
2618decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                bo, bo->handle);
2628decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return NULL;
2638decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    }
2648decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák
2658decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
2668decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák               bo->rws->fd, args.addr_ptr);
2678decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (ptr == MAP_FAILED) {
2688decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
2698decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno);
2708decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return NULL;
2716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
2728decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    bo->ptr = ptr;
2738decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_unlock(bo->map_mutex);
2746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return bo->ptr;
2766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
2776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_unmap_internal(struct pb_buffer *_buf)
2796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
2806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* NOP */
2816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
2826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_get_base_buffer(struct pb_buffer *buf,
2846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák				      struct pb_buffer **base_buf,
2856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák				      unsigned *offset)
2866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
2876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    *base_buf = buf;
2886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    *offset = 0;
2896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
2906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic enum pipe_error radeon_bo_validate(struct pb_buffer *_buf,
2926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák					  struct pb_validate *vl,
2936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák					  unsigned flags)
2946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
2956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Always pinned */
2966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return PIPE_OK;
2976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
2986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_fence(struct pb_buffer *buf,
3006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                            struct pipe_fence_handle *fence)
3016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákconst struct pb_vtbl radeon_bo_vtbl = {
3056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_destroy,
3066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_map_internal,
3076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_unmap_internal,
3086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_validate,
3096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_fence,
3106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_get_base_buffer,
3116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák};
3126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
3146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák						pb_size size,
3156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák						const struct pb_desc *desc)
3166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
3186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *rws = mgr->rws;
3196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo;
3206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_radeon_gem_create args = {};
3216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3226ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.size = size;
3236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.alignment = desc->alignment;
3246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.initial_domain =
3256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT  ?
3266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák         RADEON_GEM_DOMAIN_GTT  : 0) |
3276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ?
3286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák         RADEON_GEM_DOMAIN_VRAM : 0);
3296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_CREATE,
3316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                            &args, sizeof(args))) {
3329d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon: Failed to allocate a buffer:\n");
3339d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    size      : %d bytes\n", size);
3349d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    alignment : %d bytes\n", desc->alignment);
3359d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    domains   : %d\n", args.initial_domain);
3366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        return NULL;
3376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
3386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = CALLOC_STRUCT(radeon_bo);
3406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!bo)
3416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
3426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_reference_init(&bo->base.base.reference, 1);
3446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.alignment = desc->alignment;
3456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.usage = desc->usage;
3466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.size = size;
3476ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.vtbl = &radeon_bo_vtbl;
3486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->mgr = mgr;
349df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    bo->rws = mgr->rws;
3506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->handle = args.handle;
3516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->size = size;
3528decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_init(bo->map_mutex);
3536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return &bo->base;
3556ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bomgr_flush(struct pb_manager *mgr)
3586ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3596ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* NOP */
3606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
362a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák/* This is for the cache bufmgr. */
363a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšákstatic boolean radeon_bomgr_is_buffer_busy(struct pb_manager *_mgr,
364a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák                                           struct pb_buffer *_buf)
365a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák{
366a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   struct radeon_bo *bo = radeon_bo(_buf);
367a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
368a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   if (radeon_bo_is_referenced_by_any_cs(bo)) {
369333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák       return TRUE;
370a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   }
371a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
3721e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák   if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
373333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák       return TRUE;
374a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   }
375a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
376333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák   return FALSE;
377a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák}
378a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
3796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bomgr_destroy(struct pb_manager *_mgr)
3806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
3826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    util_hash_table_destroy(mgr->bo_handles);
3836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_destroy(mgr->bo_handles_mutex);
3846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    FREE(mgr);
3856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3878ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
388685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák
3896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic unsigned handle_hash(void *key)
3906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
391685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák    return PTR_TO_UINT(key);
3926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic int handle_compare(void *key1, void *key2)
3956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3968ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák    return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
3976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstruct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws)
4006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr;
4026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr = CALLOC_STRUCT(radeon_bomgr);
4046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!mgr)
4056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
4066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.destroy = radeon_bomgr_destroy;
4086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.create_buffer = radeon_bomgr_create_bo;
4096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.flush = radeon_bomgr_flush;
410a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák    mgr->base.is_buffer_busy = radeon_bomgr_is_buffer_busy;
4116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->rws = rws;
4136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->bo_handles = util_hash_table_create(handle_hash, handle_compare);
4146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_init(mgr->bo_handles_mutex);
4156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return &mgr->base;
4166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
418d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void *radeon_bo_map(struct pb_buffer *buf,
419d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                           struct radeon_winsys_cs *cs,
4206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                           enum pipe_transfer_usage usage)
4216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4222664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    return pb_map(buf, get_pb_usage_from_transfer_flags(usage), cs);
4236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
425d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void radeon_bo_get_tiling(struct pb_buffer *_buf,
426d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout *microtiled,
427d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout *macrotiled)
4286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4292664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
4306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_radeon_gem_set_tiling args = {};
4316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.handle = bo->handle;
4336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
434df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    drmCommandWriteRead(bo->rws->fd,
4356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        DRM_RADEON_GEM_GET_TILING,
4366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        &args,
4376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        sizeof(args));
4386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
439d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    *microtiled = RADEON_LAYOUT_LINEAR;
440d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    *macrotiled = RADEON_LAYOUT_LINEAR;
4416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (args.tiling_flags & RADEON_BO_FLAGS_MICRO_TILE)
442d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák	*microtiled = RADEON_LAYOUT_TILED;
4436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE)
445d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák	*macrotiled = RADEON_LAYOUT_TILED;
4466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4476ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
448d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void radeon_bo_set_tiling(struct pb_buffer *_buf,
449d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 struct radeon_winsys_cs *rcs,
450d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout microtiled,
451d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout macrotiled,
4526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                 uint32_t pitch)
4536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4542664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
455fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
4566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_radeon_gem_set_tiling args = {};
4576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
458fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    /* Tiling determines how DRM treats the buffer data.
459fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák     * We must flush CS when changing it if the buffer is referenced. */
460fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
4615650a719f0c69c00954e47bd7a7b3e9433cb551dMarek Olšák        cs->flush_cs(cs->flush_data, 0);
462fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    }
463fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák
464fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    while (p_atomic_read(&bo->num_active_ioctls)) {
465fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák        sched_yield();
466fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    }
467fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák
468d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (microtiled == RADEON_LAYOUT_TILED)
4696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE;
470d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    else if (microtiled == RADEON_LAYOUT_SQUARETILED)
4716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
4726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
473d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (macrotiled == RADEON_LAYOUT_TILED)
4746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MACRO_TILE;
4756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.handle = bo->handle;
4776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.pitch = pitch;
4786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
479df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    drmCommandWriteRead(bo->rws->fd,
4806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        DRM_RADEON_GEM_SET_TILING,
4816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        &args,
4826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        sizeof(args));
4836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
485d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct radeon_winsys_cs_handle *radeon_drm_get_cs_handle(
486d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák        struct pb_buffer *_buf)
4876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* return radeon_bo. */
4892664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    return (struct radeon_winsys_cs_handle*)get_radeon_bo(_buf);
4906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4927db148d3a5a350f80df8dc588e0079fda7aa378aMarek Olšákstatic unsigned get_pb_usage_from_create_flags(enum radeon_bo_domain domain)
4936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    unsigned res = 0;
4956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
496d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (domain & RADEON_DOMAIN_GTT)
4976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= RADEON_PB_USAGE_DOMAIN_GTT;
4986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
499d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (domain & RADEON_DOMAIN_VRAM)
5006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= RADEON_PB_USAGE_DOMAIN_VRAM;
5016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return res;
5036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
5046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
505d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct pb_buffer *
506d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákradeon_winsys_bo_create(struct radeon_winsys *rws,
5076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        unsigned size,
5086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        unsigned alignment,
5096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        unsigned bind,
510d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                        enum radeon_bo_domain domain)
5116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
5126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
5136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_desc desc;
5146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_manager *provider;
5156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_buffer *buffer;
5166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    memset(&desc, 0, sizeof(desc));
5186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    desc.alignment = alignment;
5197db148d3a5a350f80df8dc588e0079fda7aa378aMarek Olšák    desc.usage = get_pb_usage_from_create_flags(domain);
5206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Assign a buffer manager. */
522533e2289235c61eff9a14bb24da7c8a1ff0b0afaMarek Olšák    if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
523533e2289235c61eff9a14bb24da7c8a1ff0b0afaMarek Olšák                PIPE_BIND_CONSTANT_BUFFER))
5246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	provider = ws->cman;
5256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    else
5266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        provider = ws->kman;
5276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    buffer = provider->create_buffer(provider, size, &desc);
5296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!buffer)
5306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
5316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
532d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    return (struct pb_buffer*)buffer;
5336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
5346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
535d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
5366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                                           struct winsys_handle *whandle,
5376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                                           unsigned *stride,
5386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                                           unsigned *size)
5396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
5406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
5416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo;
5426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
5436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_gem_open open_arg = {};
5446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* We must maintain a list of pairs <handle, bo>, so that we always return
5466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * the same BO for one particular handle. If we didn't do that and created
5476ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * more than one BO for the same handle and then relocated them in a CS,
5486ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * we would hit a deadlock in the kernel.
5496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     *
5506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * The list of pairs is guarded by a mutex, of course. */
5516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_lock(mgr->bo_handles_mutex);
5526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* First check if there already is an existing bo for the handle. */
5546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = util_hash_table_get(mgr->bo_handles, (void*)(uintptr_t)whandle->handle);
5556ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (bo) {
5566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        /* Increase the refcount. */
5576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        struct pb_buffer *b = NULL;
5586ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        pb_reference(&b, &bo->base);
5596ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto done;
5606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
5616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* There isn't, create a new one. */
5636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = CALLOC_STRUCT(radeon_bo);
5646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!bo) {
5656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto fail;
5666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
5676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Open the BO. */
5696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    open_arg.name = whandle->handle;
5706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
571032b162ce88ef6ec8ad981fff709eb177d794589Marek Olšák        FREE(bo);
5726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto fail;
5736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
5746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->handle = open_arg.handle;
5756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->size = open_arg.size;
5766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->name = whandle->handle;
5776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Initialize it. */
5796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_reference_init(&bo->base.base.reference, 1);
5806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.alignment = 0;
5816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
5826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.base.size = bo->size;
5836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.vtbl = &radeon_bo_vtbl;
5846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->mgr = mgr;
585df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    bo->rws = mgr->rws;
5868decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_init(bo->map_mutex);
5876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)whandle->handle, bo);
5896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákdone:
5916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_unlock(mgr->bo_handles_mutex);
5926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (stride)
5946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        *stride = whandle->stride;
5956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (size)
5966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        *size = bo->base.base.size;
5976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
598d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    return (struct pb_buffer*)bo;
5996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákfail:
6016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_unlock(mgr->bo_handles_mutex);
6026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return NULL;
6036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
6046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
605d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
6066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                           unsigned stride,
6076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                           struct winsys_handle *whandle)
6086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
6096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_gem_flink flink = {};
6102664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(buffer);
6116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
6136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        if (!bo->flinked) {
6146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            flink.handle = bo->handle;
6156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
616df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák            if (ioctl(bo->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
6176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                return FALSE;
6186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            }
6196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            bo->flinked = TRUE;
6216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            bo->flink = flink.name;
6226ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        }
6236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        whandle->handle = bo->flink;
6246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
6256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        whandle->handle = bo->handle;
6266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
627df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák
628df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    whandle->stride = stride;
6296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return TRUE;
6306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
6316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid radeon_bomgr_init_functions(struct radeon_drm_winsys *ws)
6336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
6346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle;
6356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_set_tiling = radeon_bo_set_tiling;
6366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_tiling = radeon_bo_get_tiling;
6376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_map = radeon_bo_map;
6386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_unmap = pb_unmap;
6396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_wait = radeon_bo_wait;
6406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_is_busy = radeon_bo_is_busy;
6416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_create = radeon_winsys_bo_create;
6426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
6436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
6446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
645