summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.c98
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h11
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c3
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c15
-rw-r--r--src/gallium/drivers/vc4/vc4_simulator.c139
5 files changed, 182 insertions, 84 deletions
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c
index cf6a5114b87..350761ee86c 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.c
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.c
@@ -148,28 +148,17 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name)
bo->name = name;
bo->private = true;
+ retry:
+ ;
+
bool cleared_and_retried = false;
-retry:
- if (!using_vc4_simulator) {
- struct drm_vc4_create_bo create;
- memset(&create, 0, sizeof(create));
-
- create.size = size;
-
- ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_CREATE_BO, &create);
- bo->handle = create.handle;
- } else {
- struct drm_mode_create_dumb create;
- memset(&create, 0, sizeof(create));
-
- create.width = 128;
- create.bpp = 8;
- create.height = (size + 127) / 128;
-
- ret = drmIoctl(screen->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
- bo->handle = create.handle;
- assert(create.size >= size);
- }
+ struct drm_vc4_create_bo create = {
+ .size = size
+ };
+
+ ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_CREATE_BO, &create);
+ bo->handle = create.handle;
+
if (ret != 0) {
if (!list_empty(&screen->bo_cache.time_list) &&
!cleared_and_retried) {
@@ -223,7 +212,7 @@ vc4_bo_free(struct vc4_bo *bo)
struct drm_gem_close c;
memset(&c, 0, sizeof(c));
c.handle = bo->handle;
- int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &c);
+ int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &c);
if (ret != 0)
fprintf(stderr, "close object %d: %s\n", bo->handle, strerror(errno));
@@ -380,7 +369,7 @@ vc4_bo_open_name(struct vc4_screen *screen, uint32_t name,
struct drm_gem_open o = {
.name = name
};
- int ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o);
+ int ret = vc4_ioctl(screen->fd, DRM_IOCTL_GEM_OPEN, &o);
if (ret) {
fprintf(stderr, "Failed to open bo %d: %s\n",
name, strerror(errno));
@@ -447,30 +436,15 @@ vc4_bo_alloc_shader(struct vc4_screen *screen, const void *data, uint32_t size)
bo->name = "code";
bo->private = false; /* Make sure it doesn't go back to the cache. */
- if (!using_vc4_simulator) {
- struct drm_vc4_create_shader_bo create = {
- .size = size,
- .data = (uintptr_t)data,
- };
-
- ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_CREATE_SHADER_BO,
- &create);
- bo->handle = create.handle;
- } else {
- struct drm_mode_create_dumb create;
- memset(&create, 0, sizeof(create));
-
- create.width = 128;
- create.bpp = 8;
- create.height = (size + 127) / 128;
-
- ret = drmIoctl(screen->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
- bo->handle = create.handle;
- assert(create.size >= size);
-
- vc4_bo_map(bo);
- memcpy(bo->map, data, size);
- }
+ struct drm_vc4_create_shader_bo create = {
+ .size = size,
+ .data = (uintptr_t)data,
+ };
+
+ ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_CREATE_SHADER_BO,
+ &create);
+ bo->handle = create.handle;
+
if (ret != 0) {
fprintf(stderr, "create shader ioctl failure\n");
abort();
@@ -492,7 +466,7 @@ vc4_bo_flink(struct vc4_bo *bo, uint32_t *name)
struct drm_gem_flink flink = {
.handle = bo->handle,
};
- int ret = drmIoctl(bo->screen->fd, DRM_IOCTL_GEM_FLINK, &flink);
+ int ret = vc4_ioctl(bo->screen->fd, DRM_IOCTL_GEM_FLINK, &flink);
if (ret) {
fprintf(stderr, "Failed to flink bo %d: %s\n",
bo->handle, strerror(errno));
@@ -508,14 +482,11 @@ vc4_bo_flink(struct vc4_bo *bo, uint32_t *name)
static int vc4_wait_seqno_ioctl(int fd, uint64_t seqno, uint64_t timeout_ns)
{
- if (using_vc4_simulator)
- return 0;
-
struct drm_vc4_wait_seqno wait = {
.seqno = seqno,
.timeout_ns = timeout_ns,
};
- int ret = drmIoctl(fd, DRM_IOCTL_VC4_WAIT_SEQNO, &wait);
+ int ret = vc4_ioctl(fd, DRM_IOCTL_VC4_WAIT_SEQNO, &wait);
if (ret == -1)
return -errno;
else
@@ -553,14 +524,11 @@ vc4_wait_seqno(struct vc4_screen *screen, uint64_t seqno, uint64_t timeout_ns,
static int vc4_wait_bo_ioctl(int fd, uint32_t handle, uint64_t timeout_ns)
{
- if (using_vc4_simulator)
- return 0;
-
struct drm_vc4_wait_bo wait = {
.handle = handle,
.timeout_ns = timeout_ns,
};
- int ret = drmIoctl(fd, DRM_IOCTL_VC4_WAIT_BO, &wait);
+ int ret = vc4_ioctl(fd, DRM_IOCTL_VC4_WAIT_BO, &wait);
if (ret == -1)
return -errno;
else
@@ -602,19 +570,11 @@ vc4_bo_map_unsynchronized(struct vc4_bo *bo)
if (bo->map)
return bo->map;
- if (!using_vc4_simulator) {
- struct drm_vc4_mmap_bo map;
- memset(&map, 0, sizeof(map));
- map.handle = bo->handle;
- ret = drmIoctl(bo->screen->fd, DRM_IOCTL_VC4_MMAP_BO, &map);
- offset = map.offset;
- } else {
- struct drm_mode_map_dumb map;
- memset(&map, 0, sizeof(map));
- map.handle = bo->handle;
- ret = drmIoctl(bo->screen->fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
- offset = map.offset;
- }
+ struct drm_vc4_mmap_bo map;
+ memset(&map, 0, sizeof(map));
+ map.handle = bo->handle;
+ ret = vc4_ioctl(bo->screen->fd, DRM_IOCTL_VC4_MMAP_BO, &map);
+ offset = map.offset;
if (ret != 0) {
fprintf(stderr, "map ioctl failure\n");
abort();
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 313630a7e2f..249caebc1bc 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -30,6 +30,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/slab.h"
+#include "xf86drm.h"
#define __user
#include "vc4_drm.h"
@@ -427,6 +428,16 @@ void vc4_simulator_destroy(struct vc4_screen *screen);
int vc4_simulator_flush(struct vc4_context *vc4,
struct drm_vc4_submit_cl *args,
struct vc4_job *job);
+int vc4_simulator_ioctl(int fd, unsigned long request, void *arg);
+
+static inline int
+vc4_ioctl(int fd, unsigned long request, void *arg)
+{
+ if (using_vc4_simulator)
+ return vc4_simulator_ioctl(fd, request, arg);
+ else
+ return drmIoctl(fd, request, arg);
+}
void vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader);
void vc4_write_uniforms(struct vc4_context *vc4,
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 81ac070d463..c0d956c276b 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -38,9 +38,6 @@
#include "vc4_qpu.h"
#include "vc4_qir.h"
#include "mesa/state_tracker/st_glsl_types.h"
-#ifdef USE_VC4_SIMULATOR
-#include "simpenrose/simpenrose.h"
-#endif
static struct qreg
ntq_get_src(struct vc4_compile *c, nir_src src, int i);
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index 72fd09aee4f..37bca30b1b9 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -528,14 +528,10 @@ static int handle_compare(void *key1, void *key2)
static bool
vc4_supports_branches(struct vc4_screen *screen)
{
-#if USE_VC4_SIMULATOR
- return true;
-#endif
-
struct drm_vc4_get_param p = {
.param = DRM_VC4_PARAM_SUPPORTS_BRANCHES,
};
- int ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
+ int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
if (ret != 0)
return false;
@@ -546,11 +542,6 @@ vc4_supports_branches(struct vc4_screen *screen)
static bool
vc4_get_chip_info(struct vc4_screen *screen)
{
-#if USE_VC4_SIMULATOR
- screen->v3d_ver = 21;
- return true;
-#endif
-
struct drm_vc4_get_param ident0 = {
.param = DRM_VC4_PARAM_V3D_IDENT0,
};
@@ -559,7 +550,7 @@ vc4_get_chip_info(struct vc4_screen *screen)
};
int ret;
- ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
+ ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
if (ret != 0) {
if (errno == EINVAL) {
/* Backwards compatibility with 2835 kernels which
@@ -573,7 +564,7 @@ vc4_get_chip_info(struct vc4_screen *screen)
return false;
}
}
- ret = drmIoctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
+ ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
if (ret != 0) {
fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",
strerror(errno));
diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c
index 0291a4e1458..76896c06e73 100644
--- a/src/gallium/drivers/vc4/vc4_simulator.c
+++ b/src/gallium/drivers/vc4/vc4_simulator.c
@@ -23,6 +23,8 @@
#ifdef USE_VC4_SIMULATOR
+#include <sys/mman.h>
+#include "xf86drm.h"
#include "util/u_memory.h"
#include "util/ralloc.h"
@@ -320,6 +322,143 @@ vc4_simulator_flush(struct vc4_context *vc4,
return 0;
}
+/**
+ * Simulated ioctl(fd, DRM_VC4_CREATE_BO) implementation.
+ *
+ * Making a VC4 BO is just a matter of making a corresponding BO on the host.
+ */
+static int
+vc4_simulator_create_bo_ioctl(int fd, struct drm_vc4_create_bo *args)
+{
+ int ret;
+ struct drm_mode_create_dumb create = {
+ .width = 128,
+ .bpp = 8,
+ .height = (args->size + 127) / 128,
+ };
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
+ assert(create.size >= args->size);
+
+ args->handle = create.handle;
+
+ return ret;
+}
+
+/**
+ * Simulated ioctl(fd, DRM_VC4_CREATE_SHADER_BO) implementation.
+ *
+ * In simulation we defer shader validation until exec time. Just make a host
+ * BO and memcpy the contents in.
+ */
+static int
+vc4_simulator_create_shader_bo_ioctl(int fd,
+ struct drm_vc4_create_shader_bo *args)
+{
+ int ret;
+ struct drm_mode_create_dumb create = {
+ .width = 128,
+ .bpp = 8,
+ .height = (args->size + 127) / 128,
+ };
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
+ if (ret)
+ return ret;
+ assert(create.size >= args->size);
+
+ args->handle = create.handle;
+
+ struct drm_mode_map_dumb map = {
+ .handle = create.handle
+ };
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
+ if (ret)
+ return ret;
+
+ void *shader = mmap(NULL, args->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, map.offset);
+ memcpy(shader, (void *)(uintptr_t)args->data, args->size);
+ munmap(shader, args->size);
+
+ return 0;
+}
+
+/**
+ * Simulated ioctl(fd, DRM_VC4_MMAP_BO) implementation.
+ *
+ * We just pass this straight through to dumb mmap.
+ */
+static int
+vc4_simulator_mmap_bo_ioctl(int fd, struct drm_vc4_mmap_bo *args)
+{
+ int ret;
+ struct drm_mode_map_dumb map = {
+ .handle = args->handle,
+ };
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
+ args->offset = map.offset;
+
+ return ret;
+}
+
+static int
+vc4_simulator_get_param_ioctl(int fd, struct drm_vc4_get_param *args)
+{
+ switch (args->param) {
+ case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
+ args->value = true;
+ return 0;
+
+ case DRM_VC4_PARAM_V3D_IDENT0:
+ args->value = 0x02000000;
+ return 0;
+
+ case DRM_VC4_PARAM_V3D_IDENT1:
+ args->value = 0x00000001;
+ return 0;
+
+ default:
+ fprintf(stderr, "Unknown DRM_IOCTL_VC4_GET_PARAM(%lld)\n",
+ (long long)args->value);
+ abort();
+ };
+}
+
+int
+vc4_simulator_ioctl(int fd, unsigned long request, void *args)
+{
+ switch (request) {
+ case DRM_IOCTL_VC4_CREATE_BO:
+ return vc4_simulator_create_bo_ioctl(fd, args);
+ case DRM_IOCTL_VC4_CREATE_SHADER_BO:
+ return vc4_simulator_create_shader_bo_ioctl(fd, args);
+ case DRM_IOCTL_VC4_MMAP_BO:
+ return vc4_simulator_mmap_bo_ioctl(fd, args);
+
+ case DRM_IOCTL_VC4_WAIT_BO:
+ case DRM_IOCTL_VC4_WAIT_SEQNO:
+ /* We do all of the vc4 rendering synchronously, so we just
+ * return immediately on the wait ioctls. This ignores any
+ * native rendering to the host BO, so it does mean we race on
+ * front buffer rendering.
+ */
+ return 0;
+
+ case DRM_IOCTL_VC4_GET_PARAM:
+ return vc4_simulator_get_param_ioctl(fd, args);
+
+ case DRM_IOCTL_GEM_OPEN:
+ case DRM_IOCTL_GEM_CLOSE:
+ case DRM_IOCTL_GEM_FLINK:
+ return drmIoctl(fd, request, args);
+ default:
+ fprintf(stderr, "Unknown ioctl 0x%08x\n", (int)request);
+ abort();
+ }
+}
+
static void *sim_mem_base = NULL;
static int sim_mem_refcount = 0;
static ssize_t sim_mem_size = 256 * 1024 * 1024;