/** Area for this BO within sim_state->mem */
struct mem_block *block;
uint32_t size;
- void *vaddr;
-
- void *winsys_map;
- uint32_t winsys_stride;
+ void *sim_vaddr;
+ void *gem_vaddr;
int handle;
};
set_gmp_flags(file, sim_bo->block->ofs, size, 0x3);
sim_bo->size = size;
- sim_bo->vaddr = sim_state.mem + sim_bo->block->ofs - sim_state.mem_base;
- memset(sim_bo->vaddr, 0xd0, size);
- *(uint32_t *)(sim_bo->vaddr + sim_bo->size) = BO_SENTINEL;
+ /* Allocate space for the buffer in simulator memory. */
+ sim_bo->sim_vaddr = sim_state.mem + sim_bo->block->ofs - sim_state.mem_base;
+ memset(sim_bo->sim_vaddr, 0xd0, size);
+
+ *(uint32_t *)(sim_bo->sim_vaddr + sim_bo->size) = BO_SENTINEL;
+
+ /* Map the GEM buffer for copy in/out to the simulator. */
+ struct drm_mode_map_dumb map = {
+ .handle = handle,
+ };
+ int ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
+ if (ret) {
+ fprintf(stderr, "Failed to get MMAP offset: %d\n", ret);
+ abort();
+ }
+ sim_bo->gem_vaddr = mmap(NULL, sim_bo->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, map.offset);
+ if (sim_bo->gem_vaddr == MAP_FAILED) {
+ fprintf(stderr, "mmap of bo %d (offset 0x%016llx, size %d) failed\n",
+ handle, (long long)map.offset, sim_bo->size);
+ abort();
+ }
/* A handle of 0 is used for v3d_gem.c internal allocations that
* don't need to go in the lookup table.
{
struct v3d_simulator_file *sim_file = sim_bo->file;
- if (sim_bo->winsys_map)
- munmap(sim_bo->winsys_map, sim_bo->size);
-
set_gmp_flags(sim_file, sim_bo->block->ofs, sim_bo->size, 0x0);
+ if (sim_bo->gem_vaddr)
+ munmap(sim_bo->gem_vaddr, sim_bo->size);
+
mtx_lock(&sim_state.mutex);
u_mmFreeMem(sim_bo->block);
if (sim_bo->handle) {
- struct hash_entry *entry =
- _mesa_hash_table_search(sim_file->bo_map,
- int_to_key(sim_bo->handle));
- _mesa_hash_table_remove(sim_file->bo_map, entry);
+ _mesa_hash_table_remove_key(sim_file->bo_map,
+ int_to_key(sim_bo->handle));
}
mtx_unlock(&sim_state.mutex);
ralloc_free(sim_bo);
return entry ? entry->data : NULL;
}
-static int
-v3d_simulator_pin_bos(int fd, struct v3d_job *job)
+static void
+v3d_simulator_copy_in_handle(struct v3d_simulator_file *file, int handle)
{
- struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
+ struct v3d_simulator_bo *sim_bo = v3d_get_simulator_bo(file, handle);
- set_foreach(job->bos, entry) {
- struct v3d_bo *bo = (struct v3d_bo *)entry->key;
- struct v3d_simulator_bo *sim_bo =
- v3d_get_simulator_bo(file, bo->handle);
+ if (!sim_bo)
+ return;
- v3d_bo_map(bo);
- memcpy(sim_bo->vaddr, bo->map, bo->size);
- }
+ memcpy(sim_bo->sim_vaddr, sim_bo->gem_vaddr, sim_bo->size);
+}
- return 0;
+static void
+v3d_simulator_copy_out_handle(struct v3d_simulator_file *file, int handle)
+{
+ struct v3d_simulator_bo *sim_bo = v3d_get_simulator_bo(file, handle);
+
+ if (!sim_bo)
+ return;
+
+ memcpy(sim_bo->gem_vaddr, sim_bo->sim_vaddr, sim_bo->size);
+
+ if (*(uint32_t *)(sim_bo->sim_vaddr +
+ sim_bo->size) != BO_SENTINEL) {
+ fprintf(stderr, "Buffer overflow in handle %d\n",
+ handle);
+ }
}
static int
-v3d_simulator_unpin_bos(int fd, struct v3d_job *job)
+v3d_simulator_pin_bos(struct v3d_simulator_file *file,
+ struct drm_v3d_submit_cl *submit)
{
- struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
+ uint32_t *bo_handles = (uint32_t *)(uintptr_t)submit->bo_handles;
- set_foreach(job->bos, entry) {
- struct v3d_bo *bo = (struct v3d_bo *)entry->key;
- struct v3d_simulator_bo *sim_bo =
- v3d_get_simulator_bo(file, bo->handle);
+ for (int i = 0; i < submit->bo_handle_count; i++)
+ v3d_simulator_copy_in_handle(file, bo_handles[i]);
- if (*(uint32_t *)(sim_bo->vaddr +
- sim_bo->size) != BO_SENTINEL) {
- fprintf(stderr, "Buffer overflow in %s\n", bo->name);
- }
+ return 0;
+}
- v3d_bo_map(bo);
- memcpy(bo->map, sim_bo->vaddr, bo->size);
- }
+static int
+v3d_simulator_unpin_bos(struct v3d_simulator_file *file,
+ struct drm_v3d_submit_cl *submit)
+{
+ uint32_t *bo_handles = (uint32_t *)(uintptr_t)submit->bo_handles;
+
+ for (int i = 0; i < submit->bo_handle_count; i++)
+ v3d_simulator_copy_out_handle(file, bo_handles[i]);
return 0;
}
-int
-v3d_simulator_flush(struct v3d_context *v3d,
- struct drm_v3d_submit_cl *submit, struct v3d_job *job)
+static int
+v3d_simulator_submit_cl_ioctl(int fd, struct drm_v3d_submit_cl *submit)
{
- struct v3d_screen *screen = v3d->screen;
- int fd = screen->fd;
struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
- struct v3d_surface *csurf = v3d_surface(v3d->framebuffer.cbufs[0]);
- struct v3d_resource *ctex = csurf ? v3d_resource(csurf->base.texture) : NULL;
- struct v3d_simulator_bo *csim_bo = ctex ? v3d_get_simulator_bo(file, ctex->bo->handle) : NULL;
- uint32_t winsys_stride = ctex ? csim_bo->winsys_stride : 0;
- uint32_t sim_stride = ctex ? ctex->slices[0].stride : 0;
- uint32_t row_len = MIN2(sim_stride, winsys_stride);
int ret;
- if (ctex && csim_bo->winsys_map) {
-#if 0
- fprintf(stderr, "%dx%d %d %d %d\n",
- ctex->base.b.width0, ctex->base.b.height0,
- winsys_stride,
- sim_stride,
- ctex->bo->size);
-#endif
-
- for (int y = 0; y < ctex->base.height0; y++) {
- memcpy(ctex->bo->map + y * sim_stride,
- csim_bo->winsys_map + y * winsys_stride,
- row_len);
- }
- }
-
- ret = v3d_simulator_pin_bos(fd, job);
+ ret = v3d_simulator_pin_bos(file, submit);
if (ret)
return ret;
if (sim_state.ver >= 41)
- v3d41_simulator_flush(sim_state.v3d, submit, file->gmp->ofs);
+ v3d41_simulator_submit_cl_ioctl(sim_state.v3d, submit, file->gmp->ofs);
else
- v3d33_simulator_flush(sim_state.v3d, submit, file->gmp->ofs);
+ v3d33_simulator_submit_cl_ioctl(sim_state.v3d, submit, file->gmp->ofs);
- ret = v3d_simulator_unpin_bos(fd, job);
+ ret = v3d_simulator_unpin_bos(file, submit);
if (ret)
return ret;
- if (ctex && csim_bo->winsys_map) {
- for (int y = 0; y < ctex->base.height0; y++) {
- memcpy(csim_bo->winsys_map + y * winsys_stride,
- ctex->bo->map + y * sim_stride,
- row_len);
- }
- }
-
return 0;
}
-/**
- * Map the underlying GEM object from the real hardware GEM handle.
- */
-static void *
-v3d_simulator_map_winsys_bo(int fd, struct v3d_simulator_bo *sim_bo)
-{
- int ret;
- void *map;
-
- struct drm_mode_map_dumb map_dumb = {
- .handle = sim_bo->handle,
- };
- ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
- if (ret != 0) {
- fprintf(stderr, "map ioctl failure\n");
- abort();
- }
-
- map = mmap(NULL, sim_bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
- fd, map_dumb.offset);
- if (map == MAP_FAILED) {
- fprintf(stderr,
- "mmap of bo %d (offset 0x%016llx, size %d) failed\n",
- sim_bo->handle, (long long)map_dumb.offset,
- (int)sim_bo->size);
- abort();
- }
-
- return map;
-}
-
/**
* Do fixups after a BO has been opened from a handle.
*
* time, but we're still using drmPrimeFDToHandle() so we have this helper to
* be called afterward instead.
*/
-void v3d_simulator_open_from_handle(int fd, uint32_t winsys_stride,
- int handle, uint32_t size)
+void v3d_simulator_open_from_handle(int fd, int handle, uint32_t size)
{
- struct v3d_simulator_bo *sim_bo =
- v3d_create_simulator_bo(fd, handle, size);
-
- sim_bo->winsys_stride = winsys_stride;
- sim_bo->winsys_map = v3d_simulator_map_winsys_bo(fd, sim_bo);
+ v3d_create_simulator_bo(fd, handle, size);
}
/**
return v3d33_simulator_get_param_ioctl(sim_state.v3d, args);
}
+static int
+v3d_simulator_submit_tfu_ioctl(int fd, struct drm_v3d_submit_tfu *args)
+{
+ struct v3d_simulator_file *file = v3d_get_simulator_file_for_fd(fd);
+ int ret;
+
+ v3d_simulator_copy_in_handle(file, args->bo_handles[0]);
+ v3d_simulator_copy_in_handle(file, args->bo_handles[1]);
+ v3d_simulator_copy_in_handle(file, args->bo_handles[2]);
+ v3d_simulator_copy_in_handle(file, args->bo_handles[3]);
+
+ if (sim_state.ver >= 41)
+ ret = v3d41_simulator_submit_tfu_ioctl(sim_state.v3d, args);
+ else
+ ret = v3d33_simulator_submit_tfu_ioctl(sim_state.v3d, args);
+
+ v3d_simulator_copy_out_handle(file, args->bo_handles[0]);
+
+ return ret;
+}
+
int
v3d_simulator_ioctl(int fd, unsigned long request, void *args)
{
switch (request) {
+ case DRM_IOCTL_V3D_SUBMIT_CL:
+ return v3d_simulator_submit_cl_ioctl(fd, args);
case DRM_IOCTL_V3D_CREATE_BO:
return v3d_simulator_create_bo_ioctl(fd, args);
case DRM_IOCTL_V3D_MMAP_BO:
case DRM_IOCTL_GEM_CLOSE:
return v3d_simulator_gem_close_ioctl(fd, args);
+ case DRM_IOCTL_V3D_SUBMIT_TFU:
+ return v3d_simulator_submit_tfu_ioctl(fd, args);
+
case DRM_IOCTL_GEM_OPEN:
case DRM_IOCTL_GEM_FLINK:
return drmIoctl(fd, request, args);