#include <xf86drm.h>
#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
/*
* this are copy from radeon_drm, once an updated libdrm is released
#define RADEON_INFO_TIMESTAMP 0x11
#endif
+#ifndef RADEON_INFO_RING_WORKING
+#define RADEON_INFO_RING_WORKING 0x15
+#endif
+
+#ifndef RADEON_CS_RING_UVD
+#define RADEON_CS_RING_UVD 3
+#endif
+
static struct util_hash_table *fd_tab = NULL;
/* Enable/disable feature access for one command stream.
case CHIP_PITCAIRN:
case CHIP_VERDE:
case CHIP_OLAND:
- ws->info.chip_class = TAHITI;
+ case CHIP_HAINAN:
+ ws->info.chip_class = SI;
+ break;
+ case CHIP_BONAIRE:
+ case CHIP_KAVERI:
+ case CHIP_KABINI:
+ ws->info.chip_class = CIK;
break;
}
ws->info.r600_has_dma = TRUE;
}
+ /* Check for UVD */
+ ws->info.has_uvd = FALSE;
+ if (ws->info.drm_minor >= 32) {
+ uint32_t value = RADEON_CS_RING_UVD;
+ if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
+ "UVD Ring working", &value))
+ ws->info.has_uvd = value;
+ }
+
/* Get GEM info. */
retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
&gem_info, sizeof(gem_info));
&ws->info.r600_ib_vm_max_size))
ws->info.r600_virtual_address = FALSE;
}
+ if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", FALSE))
+ ws->info.r600_virtual_address = FALSE;
}
/* Get max pipes, this is only needed for compute shaders. All evergreen+
pipe_thread_wait(ws->thread);
}
pipe_semaphore_destroy(&ws->cs_queued);
- pipe_condvar_destroy(ws->cs_queue_empty);
-
- if (!pipe_reference(&ws->base.reference, NULL)) {
- return;
- }
pipe_mutex_destroy(ws->hyperz_owner_mutex);
pipe_mutex_destroy(ws->cmask_owner_mutex);
return radeon_surface_best(ws->surf_man, surf);
}
-static uint64_t radeon_query_timestamp(struct radeon_winsys *rws)
-{
- struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
- uint64_t ts = 0;
-
- if (ws->info.drm_minor < 20 ||
- ws->gen < DRV_R600) {
- assert(0);
- return 0;
- }
-
- radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
- (uint32_t*)&ts);
- return ts;
-}
-
static uint64_t radeon_query_value(struct radeon_winsys *rws,
enum radeon_value_id value)
{
struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+ uint64_t ts = 0;
switch (value) {
case RADEON_REQUESTED_VRAM_MEMORY:
return ws->allocated_vram;
case RADEON_REQUESTED_GTT_MEMORY:
return ws->allocated_gtt;
+ case RADEON_BUFFER_WAIT_TIME_NS:
+ return ws->buffer_wait_time;
+ case RADEON_TIMESTAMP:
+ if (ws->info.drm_minor < 20 || ws->gen < DRV_R600) {
+ assert(0);
+ return 0;
+ }
+
+ radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
+ (uint32_t*)&ts);
+ return ts;
}
return 0;
}
static unsigned hash_fd(void *key)
{
- return pointer_to_intptr(key);
+ int fd = pointer_to_intptr(key);
+ struct stat stat;
+ fstat(fd, &stat);
+
+ return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
}
static int compare_fd(void *key1, void *key2)
{
- return pointer_to_intptr(key1) != pointer_to_intptr(key2);
+ int fd1 = pointer_to_intptr(key1);
+ int fd2 = pointer_to_intptr(key2);
+ struct stat stat1, stat2;
+ fstat(fd1, &stat1);
+ fstat(fd2, &stat2);
+
+ return stat1.st_dev != stat2.st_dev ||
+ stat1.st_ino != stat2.st_ino ||
+ stat1.st_rdev != stat2.st_rdev;
}
void radeon_drm_ws_queue_cs(struct radeon_drm_winsys *ws, struct radeon_drm_cs *cs)
{
retry:
pipe_mutex_lock(ws->cs_stack_lock);
- if (p_atomic_read(&ws->ncs) >= RING_LAST) {
+ if (ws->ncs >= RING_LAST) {
/* no room left for a flush */
pipe_mutex_unlock(ws->cs_stack_lock);
goto retry;
}
- ws->cs_stack[p_atomic_read(&ws->ncs)] = cs;
- p_atomic_inc(&ws->ncs);
+ ws->cs_stack[ws->ncs++] = cs;
pipe_mutex_unlock(ws->cs_stack_lock);
pipe_semaphore_signal(&ws->cs_queued);
}
{
struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)param;
struct radeon_drm_cs *cs;
- unsigned i, empty_stack;
+ unsigned i;
while (1) {
pipe_semaphore_wait(&ws->cs_queued);
if (ws->kill_thread)
break;
-next:
+
pipe_mutex_lock(ws->cs_stack_lock);
cs = ws->cs_stack[0];
+ for (i = 1; i < ws->ncs; i++)
+ ws->cs_stack[i - 1] = ws->cs_stack[i];
+ ws->cs_stack[--ws->ncs] = NULL;
pipe_mutex_unlock(ws->cs_stack_lock);
if (cs) {
- radeon_drm_cs_emit_ioctl_oneshot(cs->cst);
-
- pipe_mutex_lock(ws->cs_stack_lock);
- for (i = 1; i < p_atomic_read(&ws->ncs); i++) {
- ws->cs_stack[i - 1] = ws->cs_stack[i];
- }
- ws->cs_stack[p_atomic_read(&ws->ncs) - 1] = NULL;
- empty_stack = p_atomic_dec_zero(&ws->ncs);
- if (empty_stack) {
- pipe_condvar_signal(ws->cs_queue_empty);
- }
- pipe_mutex_unlock(ws->cs_stack_lock);
-
+ radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
pipe_semaphore_signal(&cs->flush_completed);
-
- if (!empty_stack) {
- goto next;
- }
}
}
pipe_mutex_lock(ws->cs_stack_lock);
- for (i = 0; i < p_atomic_read(&ws->ncs); i++) {
+ for (i = 0; i < ws->ncs; i++) {
pipe_semaphore_signal(&ws->cs_stack[i]->flush_completed);
ws->cs_stack[i] = NULL;
}
- p_atomic_set(&ws->ncs, 0);
- pipe_condvar_signal(ws->cs_queue_empty);
+ ws->ncs = 0;
pipe_mutex_unlock(ws->cs_stack_lock);
return NULL;
}
ws->base.cs_request_feature = radeon_cs_request_feature;
ws->base.surface_init = radeon_drm_winsys_surface_init;
ws->base.surface_best = radeon_drm_winsys_surface_best;
- ws->base.query_timestamp = radeon_query_timestamp;
ws->base.query_value = radeon_query_value;
radeon_bomgr_init_functions(ws);
pipe_mutex_init(ws->cmask_owner_mutex);
pipe_mutex_init(ws->cs_stack_lock);
- p_atomic_set(&ws->ncs, 0);
+ ws->ncs = 0;
pipe_semaphore_init(&ws->cs_queued, 0);
- pipe_condvar_init(ws->cs_queue_empty);
if (ws->num_cpus > 1 && debug_get_option_thread())
ws->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, ws);