mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
Merge branch 'radeon_winsys_randernode' into 'main'
winsys/radeon: Prefer a render node FD for internal work Closes #11724 See merge request mesa/mesa!40873
This commit is contained in:
commit
335c90e365
5 changed files with 211 additions and 68 deletions
|
|
@ -33,6 +33,50 @@ static inline struct radeon_bo *radeon_bo(struct pb_buffer_lean *bo)
|
|||
return (struct radeon_bo *)bo;
|
||||
}
|
||||
|
||||
static bool
|
||||
radeon_bo_ref_existing(struct radeon_bo *bo)
|
||||
{
|
||||
if (unlikely(p_atomic_inc_return(&bo->base.reference.count) == 1)) {
|
||||
p_atomic_dec(&bo->base.reference.count);
|
||||
assert(p_atomic_read(&bo->base.reference.count) == 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* GEM handles are only valid for the DRM file that created/imported them.
|
||||
* When internal work uses a render-node FD, KMS/shared exports still need a
|
||||
* handle for the original app FD, so translate it once and cache the result.
|
||||
*/
|
||||
static bool
|
||||
radeon_bo_get_display_handle(struct radeon_bo *bo, uint32_t *handle)
|
||||
{
|
||||
struct radeon_drm_winsys *ws = bo->rws;
|
||||
int dma_fd;
|
||||
|
||||
if (ws->fd == ws->ioctl_fd) {
|
||||
*handle = bo->handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!bo->display_handle) {
|
||||
if (drmPrimeHandleToFD(ws->ioctl_fd, bo->handle,
|
||||
DRM_CLOEXEC | DRM_RDWR, &dma_fd))
|
||||
return false;
|
||||
|
||||
if (drmPrimeFDToHandle(ws->fd, dma_fd, &bo->display_handle)) {
|
||||
close(dma_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
close(dma_fd);
|
||||
}
|
||||
|
||||
*handle = bo->display_handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct radeon_bo_va_hole {
|
||||
struct list_head list;
|
||||
uint64_t offset;
|
||||
|
|
@ -44,7 +88,7 @@ static bool radeon_real_bo_is_busy(struct radeon_bo *bo)
|
|||
struct drm_radeon_gem_busy args = {0};
|
||||
|
||||
args.handle = bo->handle;
|
||||
return drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_BUSY,
|
||||
return drmCommandWriteRead(bo->rws->ioctl_fd, DRM_RADEON_GEM_BUSY,
|
||||
&args, sizeof(args)) != 0;
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +121,7 @@ static void radeon_real_bo_wait_idle(struct radeon_bo *bo)
|
|||
struct drm_radeon_gem_wait_idle args = {0};
|
||||
|
||||
args.handle = bo->handle;
|
||||
while (drmCommandWrite(bo->rws->fd, DRM_RADEON_GEM_WAIT_IDLE,
|
||||
while (drmCommandWrite(bo->rws->ioctl_fd, DRM_RADEON_GEM_WAIT_IDLE,
|
||||
&args, sizeof(args)) == -EBUSY);
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +207,7 @@ static enum radeon_bo_domain radeon_bo_get_initial_domain(
|
|||
args.handle = bo->handle;
|
||||
args.op = RADEON_GEM_OP_GET_INITIAL_DOMAIN;
|
||||
|
||||
if (drmCommandWriteRead(bo->rws->fd, DRM_RADEON_GEM_OP,
|
||||
if (drmCommandWriteRead(bo->rws->ioctl_fd, DRM_RADEON_GEM_OP,
|
||||
&args, sizeof(args))) {
|
||||
fprintf(stderr, "radeon: failed to get initial domain: %p 0x%08X\n",
|
||||
bo, bo->handle);
|
||||
|
|
@ -360,7 +404,7 @@ void radeon_bo_destroy(void *winsys, struct pb_buffer_lean *_buf)
|
|||
RADEON_VM_PAGE_SNOOPED;
|
||||
va.offset = bo->va;
|
||||
|
||||
if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, &va,
|
||||
if (drmCommandWriteRead(rws->ioctl_fd, DRM_RADEON_GEM_VA, &va,
|
||||
sizeof(va)) != 0 &&
|
||||
va.operation == RADEON_VA_RESULT_ERROR) {
|
||||
fprintf(stderr, "radeon: Failed to deallocate virtual address for buffer:\n");
|
||||
|
|
@ -376,7 +420,12 @@ void radeon_bo_destroy(void *winsys, struct pb_buffer_lean *_buf)
|
|||
|
||||
/* Close object. */
|
||||
args.handle = bo->handle;
|
||||
drmIoctl(rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
|
||||
drmIoctl(rws->ioctl_fd, DRM_IOCTL_GEM_CLOSE, &args);
|
||||
|
||||
if (bo->display_handle) {
|
||||
args.handle = bo->display_handle;
|
||||
drmIoctl(rws->fd, DRM_IOCTL_GEM_CLOSE, &args);
|
||||
}
|
||||
|
||||
mtx_destroy(&bo->u.real.map_mutex);
|
||||
|
||||
|
|
@ -437,7 +486,7 @@ void *radeon_bo_do_map(struct radeon_bo *bo)
|
|||
args.handle = bo->handle;
|
||||
args.offset = 0;
|
||||
args.size = (uint64_t)bo->base.size;
|
||||
if (drmCommandWriteRead(bo->rws->fd,
|
||||
if (drmCommandWriteRead(bo->rws->ioctl_fd,
|
||||
DRM_RADEON_GEM_MMAP,
|
||||
&args,
|
||||
sizeof(args))) {
|
||||
|
|
@ -448,13 +497,13 @@ void *radeon_bo_do_map(struct radeon_bo *bo)
|
|||
}
|
||||
|
||||
ptr = os_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
bo->rws->fd, args.addr_ptr);
|
||||
bo->rws->ioctl_fd, args.addr_ptr);
|
||||
if (ptr == MAP_FAILED) {
|
||||
/* Clear the cache and try again. */
|
||||
pb_cache_release_all_buffers(&bo->rws->bo_cache);
|
||||
|
||||
ptr = os_mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED,
|
||||
bo->rws->fd, args.addr_ptr);
|
||||
bo->rws->ioctl_fd, args.addr_ptr);
|
||||
if (ptr == MAP_FAILED) {
|
||||
mtx_unlock(&bo->u.real.map_mutex);
|
||||
fprintf(stderr, "radeon: mmap failed, errno: %i\n", errno);
|
||||
|
|
@ -624,7 +673,7 @@ static struct radeon_bo *radeon_create_bo(struct radeon_drm_winsys *rws,
|
|||
if (flags & RADEON_FLAG_NO_CPU_ACCESS)
|
||||
args.flags |= RADEON_GEM_NO_CPU_ACCESS;
|
||||
|
||||
if (drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_CREATE,
|
||||
if (drmCommandWriteRead(rws->ioctl_fd, DRM_RADEON_GEM_CREATE,
|
||||
&args, sizeof(args))) {
|
||||
fprintf(stderr, "radeon: Failed to allocate a buffer:\n");
|
||||
fprintf(stderr, "radeon: size : %u bytes\n", size);
|
||||
|
|
@ -677,7 +726,7 @@ static struct radeon_bo *radeon_create_bo(struct radeon_drm_winsys *rws,
|
|||
RADEON_VM_PAGE_WRITEABLE |
|
||||
RADEON_VM_PAGE_SNOOPED;
|
||||
va.offset = bo->va;
|
||||
r = drmCommandWriteRead(rws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
r = drmCommandWriteRead(rws->ioctl_fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
if (r && va.operation == RADEON_VA_RESULT_ERROR) {
|
||||
fprintf(stderr, "radeon: Failed to allocate virtual address for buffer:\n");
|
||||
fprintf(stderr, "radeon: size : %d bytes\n", size);
|
||||
|
|
@ -854,7 +903,7 @@ static void radeon_bo_get_metadata(struct radeon_winsys *rws,
|
|||
|
||||
args.handle = bo->handle;
|
||||
|
||||
drmCommandWriteRead(bo->rws->fd,
|
||||
drmCommandWriteRead(bo->rws->ioctl_fd,
|
||||
DRM_RADEON_GEM_GET_TILING,
|
||||
&args,
|
||||
sizeof(args));
|
||||
|
|
@ -963,7 +1012,7 @@ static void radeon_bo_set_metadata(struct radeon_winsys *rws,
|
|||
|
||||
args.handle = bo->handle;
|
||||
|
||||
drmCommandWriteRead(bo->rws->fd,
|
||||
drmCommandWriteRead(bo->rws->ioctl_fd,
|
||||
DRM_RADEON_GEM_SET_TILING,
|
||||
&args,
|
||||
sizeof(args));
|
||||
|
|
@ -1085,7 +1134,7 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_ptr(struct radeon_winsys *rw
|
|||
RADEON_GEM_USERPTR_REGISTER |
|
||||
RADEON_GEM_USERPTR_VALIDATE;
|
||||
|
||||
if (drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR,
|
||||
if (drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_GEM_USERPTR,
|
||||
&args, sizeof(args))) {
|
||||
FREE(bo);
|
||||
return NULL;
|
||||
|
|
@ -1124,7 +1173,7 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_ptr(struct radeon_winsys *rw
|
|||
RADEON_VM_PAGE_WRITEABLE |
|
||||
RADEON_VM_PAGE_SNOOPED;
|
||||
va.offset = bo->va;
|
||||
r = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
r = drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
if (r && va.operation == RADEON_VA_RESULT_ERROR) {
|
||||
fprintf(stderr, "radeon: Failed to assign virtual address space\n");
|
||||
radeon_bo_destroy(NULL, &bo->base);
|
||||
|
|
@ -1173,8 +1222,10 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
|
|||
/* First check if there already is an existing bo for the handle. */
|
||||
bo = util_hash_table_get(ws->bo_names, (void*)(uintptr_t)whandle->handle);
|
||||
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
|
||||
/* We must first get the GEM handle, as fds are unreliable keys */
|
||||
r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
|
||||
/* dma-buf FDs are process-local and unsuitable as cache keys.
|
||||
* Look up the imported BO via its GEM handle on ws->ioctl_fd.
|
||||
*/
|
||||
r = drmPrimeFDToHandle(ws->ioctl_fd, whandle->handle, &handle);
|
||||
if (r)
|
||||
goto fail;
|
||||
bo = util_hash_table_get(ws->bo_handles, (void*)(uintptr_t)handle);
|
||||
|
|
@ -1184,13 +1235,8 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
|
|||
}
|
||||
|
||||
if (bo) {
|
||||
/* Increase the refcount. */
|
||||
if (unlikely(p_atomic_inc_return(&bo->base.reference.count) == 1)) {
|
||||
p_atomic_dec(&bo->base.reference.count);
|
||||
assert(p_atomic_read(&bo->base.reference.count) == 0);
|
||||
} else {
|
||||
if (radeon_bo_ref_existing(bo))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* There isn't, create a new one. */
|
||||
|
|
@ -1201,8 +1247,9 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
|
|||
|
||||
if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
|
||||
struct drm_gem_open open_arg = {};
|
||||
struct drm_gem_close close_arg = {};
|
||||
memset(&open_arg, 0, sizeof(open_arg));
|
||||
/* Open the BO. */
|
||||
/* GEM flink names are tied to the original app FD, so open on ws->fd. */
|
||||
open_arg.name = whandle->handle;
|
||||
if (drmIoctl(ws->fd, DRM_IOCTL_GEM_OPEN, &open_arg)) {
|
||||
FREE(bo);
|
||||
|
|
@ -1211,6 +1258,55 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
|
|||
handle = open_arg.handle;
|
||||
size = open_arg.size;
|
||||
bo->flink_name = whandle->handle;
|
||||
|
||||
if (ws->fd != ws->ioctl_fd) {
|
||||
int dma_fd;
|
||||
|
||||
/* Internal BO tracking and command submission use ws->ioctl_fd.
|
||||
* When that differs from ws->fd, convert the temporary GEM handle
|
||||
* from ws->fd into a dma-buf and re-import it on ws->ioctl_fd, so
|
||||
* bo->handle always names the object on the internal ioctl fd.
|
||||
*/
|
||||
if (drmPrimeHandleToFD(ws->fd, open_arg.handle, DRM_CLOEXEC | DRM_RDWR,
|
||||
&dma_fd)) {
|
||||
close_arg.handle = open_arg.handle;
|
||||
drmIoctl(ws->fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
|
||||
FREE(bo);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = drmPrimeFDToHandle(ws->ioctl_fd, dma_fd, &handle);
|
||||
close(dma_fd);
|
||||
|
||||
close_arg.handle = open_arg.handle;
|
||||
drmIoctl(ws->fd, DRM_IOCTL_GEM_CLOSE, &close_arg);
|
||||
|
||||
if (r) {
|
||||
FREE(bo);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Mixed legacy-name and dma-buf imports of the same object should
|
||||
* still resolve to a single winsys BO keyed by the ioctl_fd handle.
|
||||
*/
|
||||
struct radeon_bo *existing = util_hash_table_get(ws->bo_handles,
|
||||
(void*)(uintptr_t)handle);
|
||||
if (existing) {
|
||||
if (radeon_bo_ref_existing(existing)) {
|
||||
FREE(bo);
|
||||
assert(!existing->flink_name ||
|
||||
existing->flink_name == whandle->handle);
|
||||
if (!existing->flink_name) {
|
||||
existing->flink_name = whandle->handle;
|
||||
_mesa_hash_table_insert(ws->bo_names,
|
||||
(void*)(uintptr_t)existing->flink_name,
|
||||
existing);
|
||||
}
|
||||
bo = existing;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
|
||||
size = lseek(whandle->handle, 0, SEEK_END);
|
||||
/*
|
||||
|
|
@ -1226,6 +1322,7 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
|
|||
|
||||
assert(handle != 0);
|
||||
|
||||
/* bo->handle is always the GEM handle valid on ws->ioctl_fd. */
|
||||
bo->handle = handle;
|
||||
|
||||
/* Initialize it. */
|
||||
|
|
@ -1258,7 +1355,7 @@ done:
|
|||
RADEON_VM_PAGE_WRITEABLE |
|
||||
RADEON_VM_PAGE_SNOOPED;
|
||||
va.offset = bo->va;
|
||||
r = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
r = drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
|
||||
if (r && va.operation == RADEON_VA_RESULT_ERROR) {
|
||||
fprintf(stderr, "radeon: Failed to assign virtual address space\n");
|
||||
radeon_bo_destroy(NULL, &bo->base);
|
||||
|
|
@ -1310,8 +1407,13 @@ static bool radeon_winsys_bo_get_handle(struct radeon_winsys *rws,
|
|||
bo->u.real.use_reusable_pool = false;
|
||||
|
||||
if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
|
||||
uint32_t handle;
|
||||
|
||||
if (!bo->flink_name) {
|
||||
flink.handle = bo->handle;
|
||||
if (!radeon_bo_get_display_handle(bo, &handle))
|
||||
return false;
|
||||
|
||||
flink.handle = handle;
|
||||
|
||||
if (ioctl(ws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
|
||||
return false;
|
||||
|
|
@ -1325,9 +1427,15 @@ static bool radeon_winsys_bo_get_handle(struct radeon_winsys *rws,
|
|||
}
|
||||
whandle->handle = bo->flink_name;
|
||||
} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
|
||||
whandle->handle = bo->handle;
|
||||
uint32_t handle;
|
||||
|
||||
if (!radeon_bo_get_display_handle(bo, &handle))
|
||||
return false;
|
||||
|
||||
whandle->handle = handle;
|
||||
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
|
||||
if (drmPrimeHandleToFD(ws->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, (int*)&whandle->handle))
|
||||
if (drmPrimeHandleToFD(ws->ioctl_fd, bo->handle,
|
||||
DRM_CLOEXEC | DRM_RDWR, (int*)&whandle->handle))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct radeon_bo {
|
|||
void *user_ptr; /* from buffer_from_ptr */
|
||||
|
||||
uint32_t handle; /* 0 for slab entries */
|
||||
uint32_t display_handle; /* GEM handle valid for rws->fd when it differs. */
|
||||
uint32_t flink_name;
|
||||
uint64_t va;
|
||||
uint32_t hash;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ static bool radeon_init_cs_context(struct radeon_cs_context *csc,
|
|||
{
|
||||
int i;
|
||||
|
||||
csc->fd = ws->fd;
|
||||
csc->fd = ws->ioctl_fd;
|
||||
|
||||
csc->chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
|
||||
csc->chunks[0].length_dw = 0;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <xf86drm.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -31,6 +32,24 @@
|
|||
static struct hash_table *fd_tab = NULL;
|
||||
static simple_mtx_t fd_tab_mutex = SIMPLE_MTX_INITIALIZER;
|
||||
|
||||
static int
|
||||
radeon_open_render_node(int fd)
|
||||
{
|
||||
char *render_device;
|
||||
int render_fd = -1;
|
||||
|
||||
if (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER)
|
||||
return -1;
|
||||
|
||||
render_device = drmGetRenderDeviceNameFromFd(fd);
|
||||
if (!render_device)
|
||||
return -1;
|
||||
|
||||
render_fd = open(render_device, O_RDWR | O_CLOEXEC);
|
||||
free(render_device);
|
||||
return render_fd;
|
||||
}
|
||||
|
||||
/* Enable/disable feature access for one command stream.
|
||||
* If enable == true, return true on success.
|
||||
* Otherwise, return false.
|
||||
|
|
@ -66,7 +85,7 @@ static bool radeon_set_fd_access(struct radeon_drm_cs *applier,
|
|||
/* Pass through the request to the kernel. */
|
||||
info.value = (unsigned long)&value;
|
||||
info.request = request;
|
||||
if (drmCommandWriteRead(applier->ws->fd, DRM_RADEON_INFO,
|
||||
if (drmCommandWriteRead(applier->ws->ioctl_fd, DRM_RADEON_INFO,
|
||||
&info, sizeof(info)) != 0) {
|
||||
mtx_unlock(&*mutex);
|
||||
return false;
|
||||
|
|
@ -87,7 +106,7 @@ static bool radeon_set_fd_access(struct radeon_drm_cs *applier,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool radeon_get_drm_value(int fd, unsigned request,
|
||||
static bool radeon_get_drm_value(struct radeon_drm_winsys *ws, unsigned request,
|
||||
const char *errname, uint32_t *out)
|
||||
{
|
||||
struct drm_radeon_info info;
|
||||
|
|
@ -98,7 +117,7 @@ static bool radeon_get_drm_value(int fd, unsigned request,
|
|||
info.value = (unsigned long)out;
|
||||
info.request = request;
|
||||
|
||||
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
|
||||
retval = drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_INFO, &info, sizeof(info));
|
||||
if (retval) {
|
||||
if (errname) {
|
||||
fprintf(stderr, "radeon: Failed to get %s, error number %d\n",
|
||||
|
|
@ -204,7 +223,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
*/
|
||||
|
||||
/* Get DRM version. */
|
||||
version = drmGetVersion(ws->fd);
|
||||
version = drmGetVersion(ws->ioctl_fd);
|
||||
if (!version)
|
||||
return false;
|
||||
|
||||
|
|
@ -227,7 +246,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
drmFreeVersion(version);
|
||||
|
||||
/* Get PCI ID. */
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID",
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_DEVICE_ID, "PCI ID",
|
||||
&ws->info.pci_id))
|
||||
return false;
|
||||
|
||||
|
|
@ -371,16 +390,16 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
ws->info.vce_fw_version = 0x00000000;
|
||||
|
||||
uint32_t value = RADEON_CS_RING_UVD;
|
||||
if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
|
||||
if (radeon_get_drm_value(ws, RADEON_INFO_RING_WORKING,
|
||||
"UVD Ring working", &value)) {
|
||||
ws->info.ip[AMD_IP_UVD].num_queues = 1;
|
||||
}
|
||||
|
||||
value = RADEON_CS_RING_VCE;
|
||||
if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
|
||||
if (radeon_get_drm_value(ws, RADEON_INFO_RING_WORKING,
|
||||
NULL, &value) && value) {
|
||||
|
||||
if (radeon_get_drm_value(ws->fd, RADEON_INFO_VCE_FW_VERSION,
|
||||
if (radeon_get_drm_value(ws, RADEON_INFO_VCE_FW_VERSION,
|
||||
"VCE FW version", &value)) {
|
||||
ws->info.vce_fw_version = value;
|
||||
ws->info.ip[AMD_IP_VCE].num_queues = 1;
|
||||
|
|
@ -398,12 +417,12 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
* aren't set.
|
||||
*/
|
||||
ws->info.has_userptr =
|
||||
drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR,
|
||||
drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_GEM_USERPTR,
|
||||
&args, sizeof(args)) == -EACCES;
|
||||
}
|
||||
|
||||
/* Get GEM info. */
|
||||
retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
|
||||
retval = drmCommandWriteRead(ws->ioctl_fd, DRM_RADEON_GEM_INFO,
|
||||
&gem_info, sizeof(gem_info));
|
||||
if (retval) {
|
||||
fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
|
||||
|
|
@ -427,7 +446,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
ws->info.max_heap_size_kb = MIN2(ws->info.max_heap_size_kb, 4 * 1024 * 1024); /* 4 GB */
|
||||
|
||||
/* Get max clock frequency info and convert it to MHz */
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SCLK, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_MAX_SCLK, NULL,
|
||||
&ws->info.max_gpu_freq_mhz);
|
||||
ws->info.max_gpu_freq_mhz /= 1000;
|
||||
|
||||
|
|
@ -435,12 +454,12 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
|
||||
/* Generation-specific queries. */
|
||||
if (ws->gen == DRV_R300) {
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_NUM_GB_PIPES,
|
||||
"GB pipe count",
|
||||
&ws->info.r300_num_gb_pipes))
|
||||
return false;
|
||||
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_NUM_Z_PIPES,
|
||||
"Z pipe count",
|
||||
&ws->info.r300_num_z_pipes))
|
||||
return false;
|
||||
|
|
@ -448,16 +467,16 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
else if (ws->gen >= DRV_R600) {
|
||||
uint32_t tiling_config = 0;
|
||||
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_NUM_BACKENDS,
|
||||
"num backends",
|
||||
&ws->info.max_render_backends))
|
||||
return false;
|
||||
|
||||
/* get the GPU counter frequency, failure is not fatal */
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL,
|
||||
&ws->info.clock_crystal_freq);
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_TILING_CONFIG, NULL,
|
||||
&tiling_config);
|
||||
|
||||
ws->info.r600_num_banks =
|
||||
|
|
@ -474,7 +493,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
ws->info.r600_pipe_interleave_bytes =
|
||||
ws->info.gfx_level >= EVERGREEN ? 512 : 256;
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_NUM_TILE_PIPES, NULL,
|
||||
&ws->info.num_tile_pipes);
|
||||
|
||||
/* "num_tiles_pipes" must be equal to the number of pipes (Px) in the
|
||||
|
|
@ -485,7 +504,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
if (ws->gen == DRV_SI && ws->info.num_tile_pipes == 12)
|
||||
ws->info.num_tile_pipes = 8;
|
||||
|
||||
if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL,
|
||||
if (radeon_get_drm_value(ws, RADEON_INFO_BACKEND_MAP, NULL,
|
||||
&ws->info.r600_gb_backend_map))
|
||||
ws->info.r600_gb_backend_map_valid = true;
|
||||
|
||||
|
|
@ -498,7 +517,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
if (ws->gen >= DRV_SI) {
|
||||
uint32_t mask;
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_SI_BACKEND_ENABLED_MASK, NULL, &mask);
|
||||
radeon_get_drm_value(ws, RADEON_INFO_SI_BACKEND_ENABLED_MASK, NULL, &mask);
|
||||
ws->info.enabled_rb_mask = mask;
|
||||
}
|
||||
|
||||
|
|
@ -507,13 +526,13 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
uint32_t ib_vm_max_size;
|
||||
|
||||
ws->info.r600_has_virtual_memory = true;
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_VA_START, NULL,
|
||||
&ws->va_start))
|
||||
ws->info.r600_has_virtual_memory = false;
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
|
||||
&ib_vm_max_size))
|
||||
ws->info.r600_has_virtual_memory = false;
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_VA_UNMAP_WORKING, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_VA_UNMAP_WORKING, NULL,
|
||||
&ws->va_unmap_working);
|
||||
|
||||
if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", false))
|
||||
|
|
@ -523,15 +542,15 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
/* Get max pipes, this is only needed for compute shaders. All evergreen+
|
||||
* chips have at least 2 pipes, so we use 2 as a default. */
|
||||
ws->info.r600_max_quad_pipes = 2;
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_MAX_PIPES, NULL,
|
||||
&ws->info.r600_max_quad_pipes);
|
||||
|
||||
/* All GPUs have at least one compute unit */
|
||||
ws->info.num_cu = 1;
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_ACTIVE_CU_COUNT, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_ACTIVE_CU_COUNT, NULL,
|
||||
&ws->info.num_cu);
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SE, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_MAX_SE, NULL,
|
||||
&ws->info.max_se);
|
||||
|
||||
switch (ws->info.family) {
|
||||
|
|
@ -581,7 +600,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
|
||||
ws->info.num_se = ws->info.max_se;
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SH_PER_SE, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_MAX_SH_PER_SE, NULL,
|
||||
&ws->info.max_sa_per_se);
|
||||
if (ws->gen == DRV_SI) {
|
||||
ws->info.max_good_cu_per_sa =
|
||||
|
|
@ -589,7 +608,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
(ws->info.max_se * ws->info.max_sa_per_se);
|
||||
}
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_ACCEL_WORKING2, NULL,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_ACCEL_WORKING2, NULL,
|
||||
&ws->accel_working2);
|
||||
if (ws->info.family == CHIP_HAWAII && ws->accel_working2 < 2) {
|
||||
fprintf(stderr, "radeon: GPU acceleration for Hawaii disabled, "
|
||||
|
|
@ -600,7 +619,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
}
|
||||
|
||||
if (ws->info.gfx_level == GFX7) {
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, NULL,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, NULL,
|
||||
ws->info.cik_macrotile_mode_array)) {
|
||||
fprintf(stderr, "radeon: Kernel 3.13 is required for Sea Islands support.\n");
|
||||
return false;
|
||||
|
|
@ -608,7 +627,7 @@ static bool do_winsys_init(struct radeon_drm_winsys *ws)
|
|||
}
|
||||
|
||||
if (ws->info.gfx_level >= GFX6) {
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL,
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL,
|
||||
ws->info.si_tile_mode_array)) {
|
||||
fprintf(stderr, "radeon: Kernel 3.10 is required for Southern Islands support.\n");
|
||||
return false;
|
||||
|
|
@ -736,6 +755,8 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
|
|||
mtx_destroy(&ws->vm64.mutex);
|
||||
mtx_destroy(&ws->bo_fence_lock);
|
||||
|
||||
if (ws->ioctl_fd >= 0 && ws->ioctl_fd != ws->fd)
|
||||
close(ws->ioctl_fd);
|
||||
if (ws->fd >= 0)
|
||||
close(ws->fd);
|
||||
|
||||
|
|
@ -773,7 +794,7 @@ uint32_t radeon_drm_get_gpu_reset_counter(struct radeon_drm_winsys *ws)
|
|||
{
|
||||
uint64_t retval = 0;
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_GPU_RESET_COUNTER,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_GPU_RESET_COUNTER,
|
||||
"gpu-reset-counter", (uint32_t*)&retval);
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -803,7 +824,7 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws,
|
|||
return 0;
|
||||
}
|
||||
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
|
||||
radeon_get_drm_value(ws, RADEON_INFO_TIMESTAMP, "timestamp",
|
||||
(uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_NUM_GFX_IBS:
|
||||
|
|
@ -811,7 +832,7 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws,
|
|||
case RADEON_NUM_SDMA_IBS:
|
||||
return ws->num_sdma_IBs;
|
||||
case RADEON_NUM_BYTES_MOVED:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BYTES_MOVED,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_NUM_BYTES_MOVED,
|
||||
"num-bytes-moved", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_NUM_EVICTIONS:
|
||||
|
|
@ -823,23 +844,23 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws,
|
|||
case RADEON_SLAB_WASTED_GTT:
|
||||
return 0; /* unimplemented */
|
||||
case RADEON_VRAM_USAGE:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_VRAM_USAGE,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_VRAM_USAGE,
|
||||
"vram-usage", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_GTT_USAGE:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_GTT_USAGE,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_GTT_USAGE,
|
||||
"gtt-usage", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_GPU_TEMPERATURE:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_TEMP,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_CURRENT_GPU_TEMP,
|
||||
"gpu-temp", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_CURRENT_SCLK:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_SCLK,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_CURRENT_GPU_SCLK,
|
||||
"current-gpu-sclk", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_CURRENT_MCLK:
|
||||
radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_MCLK,
|
||||
radeon_get_drm_value(ws, RADEON_INFO_CURRENT_GPU_MCLK,
|
||||
"current-gpu-mclk", (uint32_t*)&retval);
|
||||
return retval;
|
||||
case RADEON_CS_THREAD_TIME:
|
||||
|
|
@ -858,7 +879,7 @@ static bool radeon_read_registers(struct radeon_winsys *rws,
|
|||
for (i = 0; i < num_registers; i++) {
|
||||
uint32_t reg = reg_offset + i*4;
|
||||
|
||||
if (!radeon_get_drm_value(ws->fd, RADEON_INFO_READ_REG, NULL, ®))
|
||||
if (!radeon_get_drm_value(ws, RADEON_INFO_READ_REG, NULL, ®))
|
||||
return false;
|
||||
out[i] = reg;
|
||||
}
|
||||
|
|
@ -944,7 +965,17 @@ radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ws->fd = -1;
|
||||
ws->ioctl_fd = -1;
|
||||
ws->fd = os_dupfd_cloexec(fd);
|
||||
if (ws->fd < 0)
|
||||
goto fail1;
|
||||
|
||||
ws->ioctl_fd = ws->fd;
|
||||
|
||||
int render_fd = radeon_open_render_node(ws->fd);
|
||||
if (render_fd >= 0)
|
||||
ws->ioctl_fd = render_fd;
|
||||
|
||||
if (!do_winsys_init(ws))
|
||||
goto fail1;
|
||||
|
|
@ -977,7 +1008,7 @@ radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config,
|
|||
}
|
||||
|
||||
if (ws->gen >= DRV_R600) {
|
||||
ws->surf_man = radeon_surface_manager_new(ws->fd);
|
||||
ws->surf_man = radeon_surface_manager_new(ws->ioctl_fd);
|
||||
if (!ws->surf_man)
|
||||
goto fail_slab;
|
||||
}
|
||||
|
|
@ -1073,6 +1104,8 @@ fail1:
|
|||
simple_mtx_unlock(&fd_tab_mutex);
|
||||
if (ws->surf_man)
|
||||
radeon_surface_manager_free(ws->surf_man);
|
||||
if (ws->ioctl_fd >= 0 && ws->ioctl_fd != ws->fd)
|
||||
close(ws->ioctl_fd);
|
||||
if (ws->fd >= 0)
|
||||
close(ws->fd);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ struct radeon_drm_winsys {
|
|||
struct pb_cache bo_cache;
|
||||
struct pb_slabs bo_slabs;
|
||||
|
||||
int fd; /* DRM file descriptor */
|
||||
int fd; /* Application-facing DRM file descriptor. */
|
||||
int ioctl_fd; /* Render-capable DRM file descriptor for GEM and CS ioctls. */
|
||||
int num_cs; /* The number of command streams created. */
|
||||
uint64_t allocated_vram;
|
||||
uint64_t allocated_gtt;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue