static __DRIimage * intel_create_image_from_fds(__DRIscreen *screen, int width, int height, int fourcc, int *fds, int num_fds, int *strides, int *offsets, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; struct intel_image_format *f; __DRIimage *image; int i, index; if (fds == NULL || num_fds != 1) return NULL; f = intel_image_format_lookup(fourcc); if (f == NULL) return NULL; if (f->nplanes == 1) image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate); else image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate); if (image == NULL) return NULL; image->bo = drm_intel_bo_gem_create_from_prime(intelScreen->bufmgr, fds[0], height * strides[0]); if (image->bo == NULL) { free(image); return NULL; } image->width = width; image->height = height; image->pitch = strides[0]; image->planar_format = f; for (i = 0; i < f->nplanes; i++) { index = f->planes[i].buffer_index; image->offsets[index] = offsets[index]; image->strides[index] = strides[index]; } if (f->nplanes == 1) { image->offset = image->offsets[0]; intel_image_warn_if_unaligned(image, __func__); } return image; }
static __DRIimage * intel_create_image(__DRIscreen *screen, int width, int height, int format, unsigned int use, void *loaderPrivate) { __DRIimage *image; struct intel_screen *intelScreen = screen->driverPrivate; uint32_t tiling; int cpp; tiling = I915_TILING_X; if (use & __DRI_IMAGE_USE_CURSOR) { if (width != 64 || height != 64) return NULL; tiling = I915_TILING_NONE; } image = intel_allocate_image(format, loaderPrivate); cpp = _mesa_get_format_bytes(image->format); image->region = intel_region_alloc(intelScreen, tiling, cpp, width, height, true); if (image->region == NULL) { free(image); return NULL; } return image; }
static __DRIimage * intel_create_image_from_name(__DRIscreen *screen, int width, int height, int format, int name, int pitch, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; __DRIimage *image; int cpp; image = intel_allocate_image(format, loaderPrivate); if (image == NULL) return NULL; if (image->format == MESA_FORMAT_NONE) cpp = 1; else cpp = _mesa_get_format_bytes(image->format); image->region = intel_region_alloc_for_handle(intelScreen, cpp, width, height, pitch * cpp, name, "image"); if (image->region == NULL) { free(image); return NULL; } intel_setup_image_from_dimensions(image); return image; }
static __DRIimage * intel_create_image(__DRIscreen *screen, int width, int height, int format, unsigned int use, void *loaderPrivate) { __DRIimage *image; struct intel_screen *intelScreen = screen->driverPrivate; uint32_t tiling; int cpp; tiling = I915_TILING_X; if (use & __DRI_IMAGE_USE_CURSOR) { if (width != 64 || height != 64) return NULL; tiling = I915_TILING_NONE; } /* We only support write for cursor drm images */ if ((use & __DRI_IMAGE_USE_WRITE) && use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR)) return NULL; image = intel_allocate_image(format, loaderPrivate); image->usage = use; cpp = _mesa_get_format_bytes(image->format); image->region = intel_region_alloc(intelScreen, tiling, cpp, width, height, true); if (image->region == NULL) { FREE(image); return NULL; } return image; }
static __DRIimage * intel_create_image_from_name(__DRIscreen *screen, int width, int height, int format, int name, int pitch, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; __DRIimage *image; int cpp; image = intel_allocate_image(format, loaderPrivate); if (image == NULL) return NULL; if (image->format == MESA_FORMAT_NONE) cpp = 1; else cpp = _mesa_get_format_bytes(image->format); image->width = width; image->height = height; image->pitch = pitch * cpp; image->bo = drm_intel_bo_gem_create_from_name(intelScreen->bufmgr, "image", name); if (!image->bo) { free(image); return NULL; } return image; }
static __DRIimage * intel_create_image_from_fds(__DRIscreen *screen, int width, int height, int fourcc, int *fds, int num_fds, int *strides, int *offsets, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; struct intel_image_format *f; __DRIimage *image; int i, index; if (fds == NULL || num_fds != 1) return NULL; f = intel_image_format_lookup(fourcc); if (f == NULL) return NULL; if (f->nplanes == 1) image = intel_allocate_image(f->planes[0].dri_format, loaderPrivate); else image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate); if (image == NULL) return NULL; image->region = intel_region_alloc_for_fd(intelScreen, 1, width, height, strides[0], fds[0], "image"); if (image->region == NULL) { free(image); return NULL; } image->planar_format = f; for (i = 0; i < f->nplanes; i++) { index = f->planes[i].buffer_index; image->offsets[index] = offsets[index]; image->strides[index] = strides[index]; } intel_setup_image_from_dimensions(image); return image; }
static __DRIimage * intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate) { int width, height, offset, stride, dri_format, index; struct intel_image_format *f; uint32_t mask_x, mask_y; __DRIimage *image; if (parent == NULL || parent->planar_format == NULL) return NULL; f = parent->planar_format; if (plane >= f->nplanes) return NULL; width = parent->region->width >> f->planes[plane].width_shift; height = parent->region->height >> f->planes[plane].height_shift; dri_format = f->planes[plane].dri_format; index = f->planes[plane].buffer_index; offset = parent->offsets[index]; stride = parent->strides[index]; image = intel_allocate_image(dri_format, loaderPrivate); if (image == NULL) return NULL; if (offset + height * stride > parent->region->bo->size) { _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); free(image); return NULL; } image->region = calloc(sizeof(*image->region), 1); if (image->region == NULL) { free(image); return NULL; } image->region->cpp = _mesa_get_format_bytes(image->format); image->region->width = width; image->region->height = height; image->region->pitch = stride; image->region->refcount = 1; image->region->bo = parent->region->bo; drm_intel_bo_reference(image->region->bo); image->region->tiling = parent->region->tiling; image->offset = offset; intel_setup_image_from_dimensions(image); intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false); if (offset & mask_x) _mesa_warning(NULL, "intel_create_sub_image: offset not on tile boundary"); return image; }
static __DRIimage * intel_create_image_from_fds(__DRIscreen *screen, int width, int height, int fourcc, int *fds, int num_fds, int *strides, int *offsets, void *loaderPrivate) { struct intel_screen *intelScreen = screen->driverPrivate; struct intel_image_format *f = NULL; __DRIimage *image; int i, index; if (fds == NULL || num_fds != 1) return NULL; for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) { if (intel_image_formats[i].fourcc == fourcc) { f = &intel_image_formats[i]; } } if (f == NULL) return NULL; image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate); if (image == NULL) return NULL; image->region = intel_region_alloc_for_fd(intelScreen, f->planes[0].cpp, width, height, strides[0], height * strides[0], fds[0], "image"); if (image->region == NULL) { free(image); return NULL; } image->planar_format = f; for (i = 0; i < f->nplanes; i++) { index = f->planes[i].buffer_index; image->offsets[index] = offsets[index]; image->strides[index] = strides[index]; } return image; }
static __DRIimage * intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate) { int width, height, offset, stride, dri_format, index; struct intel_image_format *f; __DRIimage *image; if (parent == NULL || parent->planar_format == NULL) return NULL; f = parent->planar_format; if (plane >= f->nplanes) return NULL; width = parent->width >> f->planes[plane].width_shift; height = parent->height >> f->planes[plane].height_shift; dri_format = f->planes[plane].dri_format; index = f->planes[plane].buffer_index; offset = parent->offsets[index]; stride = parent->strides[index]; image = intel_allocate_image(dri_format, loaderPrivate); if (image == NULL) return NULL; if (offset + height * stride > parent->bo->size) { _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); free(image); return NULL; } image->bo = parent->bo; drm_intel_bo_reference(parent->bo); image->width = width; image->height = height; image->pitch = stride; image->offset = offset; intel_image_warn_if_unaligned(image, __func__); return image; }
static __DRIimage * intel_create_sub_image(__DRIimage *parent, int width, int height, int dri_format, int offset, int pitch, void *loaderPrivate) { __DRIimage *image; int cpp; uint32_t mask_x, mask_y; image = intel_allocate_image(dri_format, loaderPrivate); cpp = _mesa_get_format_bytes(image->format); if (offset + height * cpp * pitch > parent->region->bo->size) { _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); FREE(image); return NULL; } image->region = calloc(sizeof(*image->region), 1); if (image->region == NULL) { FREE(image); return NULL; } image->region->cpp = _mesa_get_format_bytes(image->format); image->region->width = width; image->region->height = height; image->region->pitch = pitch; image->region->refcount = 1; image->region->bo = parent->region->bo; drm_intel_bo_reference(image->region->bo); image->region->tiling = parent->region->tiling; image->region->screen = parent->region->screen; image->offset = offset; intel_region_get_tile_masks(image->region, &mask_x, &mask_y); if (offset & mask_x) _mesa_warning(NULL, "intel_create_sub_image: offset not on tile boundary"); return image; }
static __DRIimage * intel_create_image(__DRIscreen *screen, int width, int height, int format, unsigned int use, void *loaderPrivate) { __DRIimage *image; struct intel_screen *intelScreen = screen->driverPrivate; uint32_t tiling; int cpp; unsigned long pitch; tiling = I915_TILING_X; if (use & __DRI_IMAGE_USE_CURSOR) { if (width != 64 || height != 64) return NULL; tiling = I915_TILING_NONE; } if (use & __DRI_IMAGE_USE_LINEAR) tiling = I915_TILING_NONE; image = intel_allocate_image(format, loaderPrivate); if (image == NULL) return NULL; cpp = _mesa_get_format_bytes(image->format); image->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "image", width, height, cpp, &tiling, &pitch, 0); if (image->bo == NULL) { free(image); return NULL; } image->width = width; image->height = height; image->pitch = pitch; return image; }