static int vc4_simulator_pin_bos(struct drm_device *dev, struct vc4_exec_info *exec) { struct drm_vc4_submit_cl *args = exec->args; struct vc4_context *vc4 = dev->vc4; struct vc4_bo **bos = vc4->bo_pointers.base; exec->bo_count = args->bo_handle_count; exec->bo = calloc(exec->bo_count, sizeof(void *)); for (int i = 0; i < exec->bo_count; i++) { struct vc4_bo *bo = bos[i]; struct drm_gem_cma_object *obj = vc4_wrap_bo_with_cma(dev, bo); struct drm_vc4_bo *drm_bo = to_vc4_bo(&obj->base); #if 0 fprintf(stderr, "bo hindex %d: %s\n", i, bo->name); #endif vc4_bo_map(bo); memcpy(obj->vaddr, bo->map, bo->size); exec->bo[i] = obj; /* The kernel does this validation at shader create ioctl * time. */ if (strcmp(bo->name, "code") == 0) { drm_bo->validated_shader = vc4_validate_shader(obj); if (!drm_bo->validated_shader) abort(); } } return 0; }
static int vc4_simulator_pin_bos(struct drm_device *dev, struct exec_info *exec) { struct drm_vc4_submit_cl *args = exec->args; struct vc4_context *vc4 = dev->vc4; struct vc4_bo **bos = vc4->bo_pointers.base; exec->bo_count = args->bo_handle_count; exec->bo = calloc(exec->bo_count, sizeof(struct vc4_bo_exec_state)); for (int i = 0; i < exec->bo_count; i++) { struct vc4_bo *bo = bos[i]; struct drm_gem_cma_object *obj = vc4_wrap_bo_with_cma(dev, bo); #if 0 fprintf(stderr, "bo hindex %d: %s\n", i, bo->name); #endif vc4_bo_map(bo); memcpy(obj->vaddr, bo->map, bo->size); exec->bo[i].bo = obj; } return 0; }
static void * vc4_resource_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, unsigned level, unsigned usage, const struct pipe_box *box, struct pipe_transfer **pptrans) { struct vc4_context *vc4 = vc4_context(pctx); struct vc4_resource *rsc = vc4_resource(prsc); struct vc4_resource_slice *slice = &rsc->slices[level]; struct vc4_transfer *trans; struct pipe_transfer *ptrans; enum pipe_format format = prsc->format; char *buf; if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { vc4_resource_bo_alloc(rsc); } else if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { if (vc4_cl_references_bo(pctx, rsc->bo)) { if ((usage & PIPE_TRANSFER_DISCARD_RANGE) && prsc->last_level == 0 && prsc->width0 == box->width && prsc->height0 == box->height && prsc->depth0 == box->depth) { vc4_resource_bo_alloc(rsc); } else { vc4_flush(pctx); } } } if (usage & PIPE_TRANSFER_WRITE) rsc->writes++; trans = util_slab_alloc(&vc4->transfer_pool); if (!trans) return NULL; /* XXX: Handle DONTBLOCK, DISCARD_RANGE, PERSISTENT, COHERENT. */ /* util_slab_alloc() doesn't zero: */ memset(trans, 0, sizeof(*trans)); ptrans = &trans->base; pipe_resource_reference(&ptrans->resource, prsc); ptrans->level = level; ptrans->usage = usage; ptrans->box = *box; /* Note that the current kernel implementation is synchronous, so no * need to do syncing stuff here yet. */ buf = vc4_bo_map(rsc->bo); if (!buf) { fprintf(stderr, "Failed to map bo\n"); goto fail; } *pptrans = ptrans; if (rsc->tiled) { uint32_t utile_w = vc4_utile_width(rsc->cpp); uint32_t utile_h = vc4_utile_height(rsc->cpp); /* No direct mappings of tiled, since we need to manually * tile/untile. */ if (usage & PIPE_TRANSFER_MAP_DIRECTLY) return NULL; /* We need to align the box to utile boundaries, since that's * what load/store operate on. */ uint32_t box_start_x = ptrans->box.x & (utile_w - 1); uint32_t box_start_y = ptrans->box.y & (utile_h - 1); ptrans->box.width += box_start_x; ptrans->box.x -= box_start_x; ptrans->box.height += box_start_y; ptrans->box.y -= box_start_y; ptrans->box.width = align(ptrans->box.width, utile_w); ptrans->box.height = align(ptrans->box.height, utile_h); ptrans->stride = ptrans->box.width * rsc->cpp; ptrans->layer_stride = ptrans->stride; trans->map = malloc(ptrans->stride * ptrans->box.height); if (usage & PIPE_TRANSFER_READ) { vc4_load_tiled_image(trans->map, ptrans->stride, buf + slice->offset + box->z * rsc->cube_map_stride, slice->stride, slice->tiling, rsc->cpp, &ptrans->box); } return (trans->map + box_start_x * rsc->cpp + box_start_y * ptrans->stride); } else { ptrans->stride = slice->stride; ptrans->layer_stride = ptrans->stride; return buf + slice->offset + box->y / util_format_get_blockheight(format) * ptrans->stride + box->x / util_format_get_blockwidth(format) * rsc->cpp + box->z * rsc->cube_map_stride; } fail: vc4_resource_transfer_unmap(pctx, ptrans); return NULL; }