radeon_drm_bo.c revision 3da5196263fb2ae60483044cbd34c94270e2accd
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"
3470b1837dfb1b282ad9efcaeec4f9c8da5f9a74d8Chia-I Wu#include "os/os_mman.h"
356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include "state_tracker/drm_driver.h"
376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák#include <sys/ioctl.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
113ef64da8f013691c66744064769db379e57ef95deMarek Olšák    /* XXX use this when it's ready */
114ef64da8f013691c66744064769db379e57ef95deMarek Olšák    /*if (bo->rws->info.drm_minor >= 12) {
1151e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_wait args = {};
1161e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1171e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.flags = usage;
1181e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
1191e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) == -EBUSY);
120ef64da8f013691c66744064769db379e57ef95deMarek Olšák    } else*/ {
1213da5196263fb2ae60483044cbd34c94270e2accdBrian Paul        struct drm_radeon_gem_wait_idle args;
1223da5196263fb2ae60483044cbd34c94270e2accdBrian Paul        memset(&args, 0, sizeof(args));
1231e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1241e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        while (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
1251e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) == -EBUSY);
1261e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    }
1276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1291e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšákstatic boolean radeon_bo_is_busy(struct pb_buffer *_buf,
1301e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                 enum radeon_bo_usage usage)
1316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1322664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
1336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
134b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    if (p_atomic_read(&bo->num_active_ioctls)) {
135b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák        return TRUE;
136b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák    }
137b9e2cde6006b557a3a23a82384899f4d5a5ac7b8Marek Olšák
138ef64da8f013691c66744064769db379e57ef95deMarek Olšák    /* XXX use this when it's ready */
139ef64da8f013691c66744064769db379e57ef95deMarek Olšák    /*if (bo->rws->info.drm_minor >= 12) {
1401e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        struct drm_radeon_gem_wait args = {};
1411e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1421e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.flags = usage | RADEON_GEM_NO_WAIT;
1431e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_WAIT,
1441e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) != 0;
145ef64da8f013691c66744064769db379e57ef95deMarek Olšák    } else*/ {
1463da5196263fb2ae60483044cbd34c94270e2accdBrian Paul        struct drm_radeon_gem_busy args;
1473da5196263fb2ae60483044cbd34c94270e2accdBrian Paul        memset(&args, 0, sizeof(args));
1481e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        args.handle = bo->handle;
1491e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák        return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
1501e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                                   &args, sizeof(args)) != 0;
1511e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák    }
1526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_destroy(struct pb_buffer *_buf)
1556ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo = radeon_bo(_buf);
1573da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_gem_close args;
1583da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
1593da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&args, 0, sizeof(args));
160c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák
161c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    if (bo->name) {
162c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        pipe_mutex_lock(bo->mgr->bo_handles_mutex);
163c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        util_hash_table_remove(bo->mgr->bo_handles,
164c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák			       (void*)(uintptr_t)bo->name);
165c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák        pipe_mutex_unlock(bo->mgr->bo_handles_mutex);
166c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    }
1676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
168c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    if (bo->ptr)
169a3cd2c6c9b3724dbc3aa565dab98968c46bde963Marek Olšák        os_munmap(bo->ptr, bo->base.size);
170c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák
171c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    /* Close object. */
172c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    args.handle = bo->handle;
173c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    drmIoctl(bo->rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
174c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    pipe_mutex_destroy(bo->map_mutex);
175c35572352e3e92683988ee8d151b47f4190d62f9Marek Olšák    FREE(bo);
1766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage)
1796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    unsigned res = 0;
1816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1826caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák    if (usage & PIPE_TRANSFER_WRITE)
1836caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák        res |= PB_USAGE_CPU_WRITE;
1846caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák
1856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (usage & PIPE_TRANSFER_DONTBLOCK)
1866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= PB_USAGE_DONTBLOCK;
1876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
1896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        res |= PB_USAGE_UNSYNCHRONIZED;
1906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return res;
1926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
1936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
1946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void *radeon_bo_map_internal(struct pb_buffer *_buf,
1956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                    unsigned flags, void *flush_ctx)
1966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
1976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo = radeon_bo(_buf);
1986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_cs *cs = flush_ctx;
1993da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_radeon_gem_mmap args;
2008decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    void *ptr;
2016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2023da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&args, 0, sizeof(args));
2033da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
2046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */
20545e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák    if (!(flags & PB_USAGE_UNSYNCHRONIZED)) {
20645e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */
20745e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        if (flags & PB_USAGE_DONTBLOCK) {
208ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák            if (!(flags & PB_USAGE_CPU_WRITE)) {
209ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                /* Mapping for read.
210ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 *
211ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 * Since we are mapping for read, we don't need to wait
212ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 * if the GPU is using the buffer for read too
213ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 * (neither one is changing it).
214ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 *
215ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                 * Only check whether the buffer is being used for write. */
216ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                if (radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
217ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
218ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    return NULL;
219ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                }
22045e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák
221ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                if (radeon_bo_is_busy((struct pb_buffer*)bo,
222ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                                      RADEON_USAGE_WRITE)) {
223ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    return NULL;
224ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                }
225ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák            } else {
226ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                if (radeon_bo_is_referenced_by_cs(cs, bo)) {
227ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
228ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    return NULL;
229ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                }
230ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák
231ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                if (radeon_bo_is_busy((struct pb_buffer*)bo,
232ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                                      RADEON_USAGE_READWRITE)) {
233ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                    return NULL;
234ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                }
23545e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            }
23645e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák        } else {
2376caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák            if (!(flags & PB_USAGE_CPU_WRITE)) {
2386caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                /* Mapping for read.
2396caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 *
2406caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * Since we are mapping for read, we don't need to wait
2416caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * if the GPU is using the buffer for read too
2426caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * (neither one is changing it).
2436caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 *
2446caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                 * Only check whether the buffer is being used for write. */
2456caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                if (radeon_bo_is_referenced_by_cs_for_write(cs, bo)) {
2466caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    cs->flush_cs(cs->flush_data, 0);
2471554e69e00566bc7255b82f5ea93b1f02f1a5bb3Marek Olšák                }
248ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                radeon_bo_wait((struct pb_buffer*)bo,
249ebfcc58b93cc08c534857c2314694e35b29690aeMarek Olšák                               RADEON_USAGE_WRITE);
2505650a719f0c69c00954e47bd7a7b3e9433cb551dMarek Olšák            } else {
2516caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                /* Mapping for write. */
2526caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                if (radeon_bo_is_referenced_by_cs(cs, bo)) {
2536caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    cs->flush_cs(cs->flush_data, 0);
2546caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                } else {
2556caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    /* Try to avoid busy-waiting in radeon_bo_wait. */
2566caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                    if (p_atomic_read(&bo->num_active_ioctls))
2576caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                        radeon_drm_cs_sync_flush(cs);
2586caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák                }
2596caac3ecb8bc32d92c35fdb1f0a67541ffa8af29Marek Olšák
2601e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák                radeon_bo_wait((struct pb_buffer*)bo, RADEON_USAGE_READWRITE);
26145e1cd522bd26a5aa3d424ea49975b90feef8450Marek Olšák            }
2626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        }
2636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
2646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2658decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    /* Return the pointer if it's already mapped. */
2668decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (bo->ptr)
2678decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return bo->ptr;
2688decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák
2698decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    /* Map the buffer. */
2708decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_lock(bo->map_mutex);
271652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    /* Return the pointer if it's already mapped (in case of a race). */
272652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    if (bo->ptr) {
273652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
274652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák        return bo->ptr;
275652bf121f2124ec92b74f6e3e40e6aefcc1c50dcMarek Olšák    }
2768decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    args.handle = bo->handle;
2778decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    args.offset = 0;
278a3cd2c6c9b3724dbc3aa565dab98968c46bde963Marek Olšák    args.size = (uint64_t)bo->base.size;
2798decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (drmCommandWriteRead(bo->rws->fd,
2808decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            DRM_RADEON_GEM_MMAP,
2818decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            &args,
2828decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                            sizeof(args))) {
2838decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
2848decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        fprintf(stderr, "radeon: gem_mmap failed: %p 0x%08X\n",
2858decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák                bo, bo->handle);
2868decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return NULL;
2878decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    }
2888decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák
28970b1837dfb1b282ad9efcaeec4f9c8da5f9a74d8Chia-I Wu    ptr = os_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
2908decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák               bo->rws->fd, args.addr_ptr);
2918decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    if (ptr == MAP_FAILED) {
2928decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        pipe_mutex_unlock(bo->map_mutex);
2938decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno);
2948decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák        return NULL;
2956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
2968decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    bo->ptr = ptr;
2978decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_unlock(bo->map_mutex);
2986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
2996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return bo->ptr;
3006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_unmap_internal(struct pb_buffer *_buf)
3036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* NOP */
3056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_get_base_buffer(struct pb_buffer *buf,
3086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák				      struct pb_buffer **base_buf,
3096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák				      unsigned *offset)
3106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    *base_buf = buf;
3126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    *offset = 0;
3136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic enum pipe_error radeon_bo_validate(struct pb_buffer *_buf,
3166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák					  struct pb_validate *vl,
3176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák					  unsigned flags)
3186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Always pinned */
3206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return PIPE_OK;
3216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3226ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bo_fence(struct pb_buffer *buf,
3246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                            struct pipe_fence_handle *fence)
3256ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákconst struct pb_vtbl radeon_bo_vtbl = {
3296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_destroy,
3306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_map_internal,
3316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_unmap_internal,
3326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_validate,
3336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_fence,
3346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    radeon_bo_get_base_buffer,
3356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák};
3366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
3386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák						pb_size size,
3396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák						const struct pb_desc *desc)
3406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
3426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *rws = mgr->rws;
3436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo;
3443da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_radeon_gem_create args;
345bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák    struct radeon_bo_desc *rdesc = (struct radeon_bo_desc*)desc;
3466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3473da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&args, 0, sizeof(args));
3483da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
349363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    assert(rdesc->initial_domains && rdesc->reloc_domains);
350363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    assert((rdesc->initial_domains &
351363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0);
352363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    assert((rdesc->reloc_domains &
353363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0);
354363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák
3556ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.size = size;
3566ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.alignment = desc->alignment;
357bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák    args.initial_domain = rdesc->initial_domains;
3586ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3596ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_CREATE,
3606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                            &args, sizeof(args))) {
3619d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon: Failed to allocate a buffer:\n");
3629d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    size      : %d bytes\n", size);
3639d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    alignment : %d bytes\n", desc->alignment);
3649d5de0fcb6ced7a4da85a09ad25dcbc2b21bfdf9Marek Olšák        fprintf(stderr, "radeon:    domains   : %d\n", args.initial_domain);
3656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        return NULL;
3666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
3676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = CALLOC_STRUCT(radeon_bo);
3696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!bo)
3706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
3716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3724682e706012fe26627a2f827db01b5068cc62814Marek Olšák    pipe_reference_init(&bo->base.reference, 1);
3734682e706012fe26627a2f827db01b5068cc62814Marek Olšák    bo->base.alignment = desc->alignment;
3744682e706012fe26627a2f827db01b5068cc62814Marek Olšák    bo->base.usage = desc->usage;
3754682e706012fe26627a2f827db01b5068cc62814Marek Olšák    bo->base.size = size;
3766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.vtbl = &radeon_bo_vtbl;
3776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->mgr = mgr;
378df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    bo->rws = mgr->rws;
3796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->handle = args.handle;
380363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    bo->reloc_domains = rdesc->reloc_domains;
3818decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_init(bo->map_mutex);
3826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return &bo->base;
3846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
3866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bomgr_flush(struct pb_manager *mgr)
3876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
3886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* NOP */
3896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
3906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
391a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák/* This is for the cache bufmgr. */
392a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšákstatic boolean radeon_bomgr_is_buffer_busy(struct pb_manager *_mgr,
393a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák                                           struct pb_buffer *_buf)
394a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák{
395a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   struct radeon_bo *bo = radeon_bo(_buf);
396a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
397a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   if (radeon_bo_is_referenced_by_any_cs(bo)) {
398333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák       return TRUE;
399a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   }
400a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
4011e3c81a068c4ae04cd1c6b18c687d5be69b7b8c4Marek Olšák   if (radeon_bo_is_busy((struct pb_buffer*)bo, RADEON_USAGE_READWRITE)) {
402333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák       return TRUE;
403a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák   }
404a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
405333d3daf472485b247101932d95ccb798cb55f7bMarek Olšák   return FALSE;
406a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák}
407a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák
4086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic void radeon_bomgr_destroy(struct pb_manager *_mgr)
4096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(_mgr);
4116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    util_hash_table_destroy(mgr->bo_handles);
4126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_destroy(mgr->bo_handles_mutex);
4136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    FREE(mgr);
4146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4168ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák#define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
417685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák
4186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic unsigned handle_hash(void *key)
4196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
420685c3262b945a7f0e9f1f3a9409a12fdda08c828Marek Olšák    return PTR_TO_UINT(key);
4216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4226ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstatic int handle_compare(void *key1, void *key2)
4246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4258ab1fcc66a58ca87fb19fea2b0e14e62562decccMarek Olšák    return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
4266ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákstruct pb_manager *radeon_bomgr_create(struct radeon_drm_winsys *rws)
4296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr;
4316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr = CALLOC_STRUCT(radeon_bomgr);
4336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!mgr)
4346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
4356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.destroy = radeon_bomgr_destroy;
4376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.create_buffer = radeon_bomgr_create_bo;
4386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->base.flush = radeon_bomgr_flush;
439a87730ff3f83253465fbe9a1e9e9b1ea92cb79b9Marek Olšák    mgr->base.is_buffer_busy = radeon_bomgr_is_buffer_busy;
4406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4416ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->rws = rws;
4426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    mgr->bo_handles = util_hash_table_create(handle_hash, handle_compare);
4436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_init(mgr->bo_handles_mutex);
4446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return &mgr->base;
4456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
447d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void *radeon_bo_map(struct pb_buffer *buf,
448d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                           struct radeon_winsys_cs *cs,
4496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                           enum pipe_transfer_usage usage)
4506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4512664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    return pb_map(buf, get_pb_usage_from_transfer_flags(usage), cs);
4526ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
454d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void radeon_bo_get_tiling(struct pb_buffer *_buf,
455d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout *microtiled,
456d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout *macrotiled)
4576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4582664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
4593da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_radeon_gem_set_tiling args;
4603da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
4613da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&args, 0, sizeof(args));
4626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.handle = bo->handle;
4646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
465df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    drmCommandWriteRead(bo->rws->fd,
4666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        DRM_RADEON_GEM_GET_TILING,
4676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        &args,
4686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        sizeof(args));
4696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
470d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    *microtiled = RADEON_LAYOUT_LINEAR;
471d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    *macrotiled = RADEON_LAYOUT_LINEAR;
4726ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (args.tiling_flags & RADEON_BO_FLAGS_MICRO_TILE)
473d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák	*microtiled = RADEON_LAYOUT_TILED;
4746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
4756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (args.tiling_flags & RADEON_BO_FLAGS_MACRO_TILE)
476d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák	*macrotiled = RADEON_LAYOUT_TILED;
4776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
4786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
479d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic void radeon_bo_set_tiling(struct pb_buffer *_buf,
480d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 struct radeon_winsys_cs *rcs,
481d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout microtiled,
482d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák                                 enum radeon_bo_layout macrotiled,
4836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                 uint32_t pitch)
4846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
4852664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(_buf);
486fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
4873da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_radeon_gem_set_tiling args;
4883da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
4893da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&args, 0, sizeof(args));
4906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
491fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    /* Tiling determines how DRM treats the buffer data.
492fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák     * We must flush CS when changing it if the buffer is referenced. */
493fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
4945650a719f0c69c00954e47bd7a7b3e9433cb551dMarek Olšák        cs->flush_cs(cs->flush_data, 0);
495fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    }
496fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák
497fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    while (p_atomic_read(&bo->num_active_ioctls)) {
498fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák        sched_yield();
499fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák    }
500fa3f1348e49feeac511dbe5b22bbddc47f56ba81Marek Olšák
501d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (microtiled == RADEON_LAYOUT_TILED)
5026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE;
503d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    else if (microtiled == RADEON_LAYOUT_SQUARETILED)
5046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
5056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
506d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (macrotiled == RADEON_LAYOUT_TILED)
5076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        args.tiling_flags |= RADEON_BO_FLAGS_MACRO_TILE;
5086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.handle = bo->handle;
5106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    args.pitch = pitch;
5116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
512df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    drmCommandWriteRead(bo->rws->fd,
5136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        DRM_RADEON_GEM_SET_TILING,
5146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        &args,
5156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        sizeof(args));
5166ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
5176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
518d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct radeon_winsys_cs_handle *radeon_drm_get_cs_handle(
519d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák        struct pb_buffer *_buf)
5206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
5216ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* return radeon_bo. */
5222664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    return (struct radeon_winsys_cs_handle*)get_radeon_bo(_buf);
5236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
5246ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
525d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct pb_buffer *
526d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákradeon_winsys_bo_create(struct radeon_winsys *rws,
5276ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        unsigned size,
5286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                        unsigned alignment,
529363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák                        unsigned bind, unsigned usage)
5306ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
5316ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
532bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák    struct radeon_bo_desc desc;
5336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_manager *provider;
5346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct pb_buffer *buffer;
5356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    memset(&desc, 0, sizeof(desc));
537bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák    desc.base.alignment = alignment;
538363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák
539363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    /* Determine the memory domains. */
540363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    switch (usage) {
541363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    case PIPE_USAGE_STAGING:
542363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    case PIPE_USAGE_STREAM:
543363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    case PIPE_USAGE_DYNAMIC:
544363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            desc.initial_domains = RADEON_GEM_DOMAIN_GTT;
545363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            desc.reloc_domains = RADEON_GEM_DOMAIN_GTT;
546363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            break;
5472717b8f034db16cf551e167aa5ce3a9be3bf730bMathias Fröhlich    case PIPE_USAGE_IMMUTABLE:
5482717b8f034db16cf551e167aa5ce3a9be3bf730bMathias Fröhlich    case PIPE_USAGE_STATIC:
5492717b8f034db16cf551e167aa5ce3a9be3bf730bMathias Fröhlich            desc.initial_domains = RADEON_GEM_DOMAIN_VRAM;
5502717b8f034db16cf551e167aa5ce3a9be3bf730bMathias Fröhlich            desc.reloc_domains = RADEON_GEM_DOMAIN_VRAM;
5512717b8f034db16cf551e167aa5ce3a9be3bf730bMathias Fröhlich            break;
552363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    default:
553363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
554363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák                        PIPE_BIND_CONSTANT_BUFFER)) {
555363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák                desc.initial_domains = RADEON_GEM_DOMAIN_GTT;
556363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            } else {
557363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák                desc.initial_domains = RADEON_GEM_DOMAIN_VRAM;
558363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            }
559363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák            desc.reloc_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
560363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    }
561363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák
562363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    /* Additional criteria for the cache manager. */
563363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    desc.base.usage = desc.initial_domains;
5646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Assign a buffer manager. */
566533e2289235c61eff9a14bb24da7c8a1ff0b0afaMarek Olšák    if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
56734f4bd81906d8385eb3e9af721d50e985cb9d7d4Marek Olšák                PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_CUSTOM))
5686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	provider = ws->cman;
5696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    else
5706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        provider = ws->kman;
5716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
572bfa51dfeac67a7e3383614374c86bdfb5751997aMarek Olšák    buffer = provider->create_buffer(provider, size, &desc.base);
5736ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!buffer)
5746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák	return NULL;
5756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
576d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    return (struct pb_buffer*)buffer;
5776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
5786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
579d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
580af8eb5c851a9d566059ae9e37745614cd96b9a13Marek Olšák                                                      struct winsys_handle *whandle,
581af8eb5c851a9d566059ae9e37745614cd96b9a13Marek Olšák                                                      unsigned *stride)
5826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
5836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
5846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bo *bo;
5856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct radeon_bomgr *mgr = radeon_bomgr(ws->kman);
5866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    struct drm_gem_open open_arg = {};
5876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5883da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&open_arg, 0, sizeof(open_arg));
5893da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
5906ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* We must maintain a list of pairs <handle, bo>, so that we always return
5916ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * the same BO for one particular handle. If we didn't do that and created
5926ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * more than one BO for the same handle and then relocated them in a CS,
5936ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * we would hit a deadlock in the kernel.
5946ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     *
5956ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák     * The list of pairs is guarded by a mutex, of course. */
5966ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_lock(mgr->bo_handles_mutex);
5976ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
5986ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* First check if there already is an existing bo for the handle. */
5996ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = util_hash_table_get(mgr->bo_handles, (void*)(uintptr_t)whandle->handle);
6006ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (bo) {
6016ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        /* Increase the refcount. */
6026ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        struct pb_buffer *b = NULL;
6036ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        pb_reference(&b, &bo->base);
6046ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto done;
6056ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
6066ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6076ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* There isn't, create a new one. */
6086ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo = CALLOC_STRUCT(radeon_bo);
6096ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (!bo) {
6106ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto fail;
6116ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
6126ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6136ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Open the BO. */
6146ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    open_arg.name = whandle->handle;
6156ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
616032b162ce88ef6ec8ad981fff709eb177d794589Marek Olšák        FREE(bo);
6176ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        goto fail;
6186ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
6196ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->handle = open_arg.handle;
6206ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->name = whandle->handle;
621363ff844753c46ac9c13866627e096b091ea81f8Marek Olšák    bo->reloc_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
6226ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6236ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    /* Initialize it. */
6244682e706012fe26627a2f827db01b5068cc62814Marek Olšák    pipe_reference_init(&bo->base.reference, 1);
6254682e706012fe26627a2f827db01b5068cc62814Marek Olšák    bo->base.alignment = 0;
6264682e706012fe26627a2f827db01b5068cc62814Marek Olšák    bo->base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
627a3cd2c6c9b3724dbc3aa565dab98968c46bde963Marek Olšák    bo->base.size = open_arg.size;
6286ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->base.vtbl = &radeon_bo_vtbl;
6296ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    bo->mgr = mgr;
630df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    bo->rws = mgr->rws;
6318decb0a96de0accfc8361890cbcf9db89f8fe8baMarek Olšák    pipe_mutex_init(bo->map_mutex);
6326ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6336ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    util_hash_table_set(mgr->bo_handles, (void*)(uintptr_t)whandle->handle, bo);
6346ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6356ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákdone:
6366ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_unlock(mgr->bo_handles_mutex);
6376ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6386ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (stride)
6396ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        *stride = whandle->stride;
6406ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
641d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    return (struct pb_buffer*)bo;
6426ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6436ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákfail:
6446ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    pipe_mutex_unlock(mgr->bo_handles_mutex);
6456ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return NULL;
6466ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
6476ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
648d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšákstatic boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
6496ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                           unsigned stride,
6506ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                           struct winsys_handle *whandle)
6516ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
6523da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    struct drm_gem_flink flink;
6532664980760c5cf2e7dde4065f9cc8e8b865627c3Marek Olšák    struct radeon_bo *bo = get_radeon_bo(buffer);
6546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6553da5196263fb2ae60483044cbd34c94270e2accdBrian Paul    memset(&flink, 0, sizeof(flink));
6563da5196263fb2ae60483044cbd34c94270e2accdBrian Paul
6576ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
6586ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        if (!bo->flinked) {
6596ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            flink.handle = bo->handle;
6606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
661df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák            if (ioctl(bo->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
6626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                return FALSE;
6636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            }
6646ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6656ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            bo->flinked = TRUE;
6666ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák            bo->flink = flink.name;
6676ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        }
6686ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        whandle->handle = bo->flink;
6696ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
6706ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák        whandle->handle = bo->handle;
6716ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    }
672df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák
673df54b53b7d12a3bca5867b6649cb308feb36f0daMarek Olšák    whandle->stride = stride;
6746ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    return TRUE;
6756ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
6766ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák
6776ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšákvoid radeon_bomgr_init_functions(struct radeon_drm_winsys *ws)
6786ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák{
6796ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_cs_handle = radeon_drm_get_cs_handle;
6806ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_set_tiling = radeon_bo_set_tiling;
6816ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_tiling = radeon_bo_get_tiling;
6826ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_map = radeon_bo_map;
6836ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_unmap = pb_unmap;
6846ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_wait = radeon_bo_wait;
6856ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_is_busy = radeon_bo_is_busy;
6866ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_create = radeon_winsys_bo_create;
6876ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
6886ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák    ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
6896ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák}
690