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) {
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));
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));
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();
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));
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
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
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();
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/slab.h"
+#include "xf86drm.h"
#define __user
#include "vc4_drm.h"
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,
#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);
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;
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,
};
};
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
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));
#ifdef USE_VC4_SIMULATOR
+#include <sys/mman.h>
+#include "xf86drm.h"
#include "util/u_memory.h"
#include "util/ralloc.h"
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;