struct intel_region * intel_region_alloc(struct intel_screen *screen, uint32_t tiling, GLuint cpp, GLuint width, GLuint height, bool expect_accelerated_upload) { drm_intel_bo *buffer; unsigned long flags = 0; unsigned long aligned_pitch; struct intel_region *region; if (expect_accelerated_upload) flags |= BO_ALLOC_FOR_RENDER; buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "region", width, height, cpp, &tiling, &aligned_pitch, flags); if (buffer == NULL) return NULL; region = intel_region_alloc_internal(screen, cpp, width, height, aligned_pitch, tiling, buffer); if (region == NULL) { drm_intel_bo_unreference(buffer); return NULL; } return region; }
struct intel_bo * intel_winsys_alloc_texture(struct intel_winsys *winsys, const char *name, int width, int height, int cpp, enum intel_tiling_mode tiling, uint32_t initial_domain, unsigned long *pitch) { const unsigned long flags = (initial_domain & (INTEL_DOMAIN_RENDER | INTEL_DOMAIN_INSTRUCTION)) ? BO_ALLOC_FOR_RENDER : 0; uint32_t real_tiling = tiling; drm_intel_bo *bo; bo = drm_intel_bo_alloc_tiled(winsys->bufmgr, name, width, height, cpp, &real_tiling, pitch, flags); if (!bo) return NULL; if (real_tiling != tiling) { assert(!"tiling mismatch"); drm_intel_bo_unreference(bo); return NULL; } return (struct intel_bo *) bo; }
static struct i915_winsys_buffer * i915_drm_buffer_create_tiled(struct i915_winsys *iws, unsigned *stride, unsigned height, enum i915_winsys_buffer_tile *tiling, enum i915_winsys_buffer_type type) { struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); struct i915_drm_winsys *idws = i915_drm_winsys(iws); unsigned long pitch = 0; uint32_t tiling_mode = *tiling; if (!buf) return NULL; buf->magic = 0xDEAD1337; buf->flinked = FALSE; buf->flink = 0; buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager, i915_drm_type_to_name(type), *stride, height, 1, &tiling_mode, &pitch, 0); if (!buf->bo) goto err; *stride = pitch; *tiling = tiling_mode; return (struct i915_winsys_buffer *)buf; err: assert(0); FREE(buf); return NULL; }
static bool test_address_swizzling(struct intel_winsys *winsys) { drm_intel_bo *bo; uint32_t tiling = I915_TILING_X, swizzle; unsigned long pitch; bo = drm_intel_bo_alloc_tiled(winsys->bufmgr, "address swizzling test", 64, 64, 4, &tiling, &pitch, 0); if (bo) { drm_intel_bo_get_tiling(bo, &tiling, &swizzle); drm_intel_bo_unreference(bo); } else { swizzle = I915_BIT_6_SWIZZLE_NONE; } return (swizzle != I915_BIT_6_SWIZZLE_NONE); }
static void emit_dummy_load(void) { int i; uint32_t tile_flags = 0; uint32_t tiling_mode = I915_TILING_X; unsigned long pitch; drm_intel_bo *dummy_bo; dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", 2048, 2048, 4, &tiling_mode, &pitch, 0); if (IS_965(devid)) { pitch /= 4; tile_flags = XY_SRC_COPY_BLT_SRC_TILED | XY_SRC_COPY_BLT_DST_TILED; } for (i = 0; i < 5; i++) { BLIT_COPY_BATCH_START(tile_flags); OUT_BATCH((3 << 24) | /* 32 bits */ (0xcc << 16) | /* copy ROP */ pitch); OUT_BATCH(0 << 16 | 1024); OUT_BATCH((2048) << 16 | (2048)); OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(0 << 16 | 0); OUT_BATCH(pitch); OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); ADVANCE_BATCH(); if (batch->gen >= 6) { BEGIN_BATCH(3, 0); OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); OUT_BATCH(0); OUT_BATCH(0); ADVANCE_BATCH(); } } intel_batchbuffer_flush(batch); drm_intel_bo_unreference(dummy_bo); }
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; }
static __DRIbuffer * intelAllocateBuffer(__DRIscreen *screen, unsigned attachment, unsigned format, int width, int height) { struct intel_buffer *intelBuffer; struct intel_screen *intelScreen = screen->driverPrivate; assert(attachment == __DRI_BUFFER_FRONT_LEFT || attachment == __DRI_BUFFER_BACK_LEFT); intelBuffer = calloc(1, sizeof *intelBuffer); if (intelBuffer == NULL) return NULL; /* The front and back buffers are color buffers, which are X tiled. */ uint32_t tiling = I915_TILING_X; unsigned long pitch; int cpp = format / 8; intelBuffer->bo = drm_intel_bo_alloc_tiled(intelScreen->bufmgr, "intelAllocateBuffer", width, height, cpp, &tiling, &pitch, BO_ALLOC_FOR_RENDER); if (intelBuffer->bo == NULL) { free(intelBuffer); return NULL; } drm_intel_bo_flink(intelBuffer->bo, &intelBuffer->base.name); intelBuffer->base.attachment = attachment; intelBuffer->base.cpp = cpp; intelBuffer->base.pitch = pitch; return &intelBuffer->base; }
static bool intel_detect_swizzling(struct intel_screen *screen) { drm_intel_bo *buffer; unsigned long flags = 0; unsigned long aligned_pitch; uint32_t tiling = I915_TILING_X; uint32_t swizzle_mode = 0; buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test", 64, 64, 4, &tiling, &aligned_pitch, flags); if (buffer == NULL) return false; drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode); drm_intel_bo_unreference(buffer); if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE) return false; else return true; }
static int alloc_bo(struct buffer *my_buf) { /* XXX: try different tiling modes for testing FB modifiers. */ uint32_t tiling = I915_TILING_NONE; assert(my_buf->bufmgr); my_buf->bo = drm_intel_bo_alloc_tiled(my_buf->bufmgr, "test", my_buf->width, my_buf->height, (my_buf->bpp / 8), &tiling, &my_buf->stride, 0); printf("buffer allocated w %d, h %d, stride %lu, size %lu\n", my_buf->width, my_buf->height, my_buf->stride, my_buf->bo->size); if (!my_buf->bo) return 0; if (tiling != I915_TILING_NONE) return 0; return 1; }
VOID media_alloc_surface_bo (VADriverContextP ctx, struct object_surface * obj_surface, INT tiled, UINT fourcc, UINT subsampling) { INT region_width, region_height; MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) ctx->pDriverData; MEDIA_DRV_ASSERT (ctx); MEDIA_DRV_ASSERT (drv_ctx); if (obj_surface->bo) { MEDIA_DRV_ASSERT (obj_surface->fourcc); MEDIA_DRV_ASSERT (obj_surface->fourcc == fourcc); MEDIA_DRV_ASSERT (obj_surface->subsampling == subsampling); return; } obj_surface->x_cb_offset = 0; /* X offset is always 0 */ obj_surface->x_cr_offset = 0; if (tiled) { MEDIA_DRV_ASSERT (fourcc != VA_FOURCC ('I', '4', '2', '0') && fourcc != VA_FOURCC ('I', 'Y', 'U', 'V') && fourcc != VA_FOURCC ('Y', 'V', '1', '2')); obj_surface->width = ALIGN (obj_surface->orig_width, 128); obj_surface->height = ALIGN (obj_surface->orig_height, 32); region_height = obj_surface->height; switch (fourcc) { case VA_FOURCC ('N', 'V', '1', '2'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV420); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->height; region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32); break; case VA_FOURCC ('I', 'M', 'C', '1'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV420); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->y_cr_offset = obj_surface->height; obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('I', 'M', 'C', '3'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV420); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('4', '2', '2', 'H'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV422H); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('4', '2', '2', 'V'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV422V); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('4', '1', '1', 'P'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV411); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width / 4; obj_surface->cb_cr_height = obj_surface->orig_height; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('4', '4', '4', 'P'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV444); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = obj_surface->orig_width; obj_surface->cb_cr_height = obj_surface->orig_height; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('Y', '8', '0', '0'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV400); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->cb_cr_width = 0; obj_surface->cb_cr_height = 0; obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN (obj_surface->cb_cr_height, 32); region_width = obj_surface->width; region_height = obj_surface->height + ALIGN (obj_surface->cb_cr_height, 32) * 2; break; case VA_FOURCC ('Y', 'U', 'Y', '2'): case VA_FOURCC ('U', 'Y', 'V', 'Y'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV422H); obj_surface->width = ALIGN (obj_surface->orig_width * 2, 128); obj_surface->cb_cr_pitch = obj_surface->width; obj_surface->y_cb_offset = 0; obj_surface->y_cr_offset = 0; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; region_width = obj_surface->width; region_height = obj_surface->height; break; case VA_FOURCC ('R', 'G', 'B', 'A'): case VA_FOURCC ('R', 'G', 'B', 'X'): case VA_FOURCC ('B', 'G', 'R', 'A'): case VA_FOURCC ('B', 'G', 'R', 'X'): MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_RGBX); obj_surface->width = ALIGN (obj_surface->orig_width * 4, 128); region_width = obj_surface->width; region_height = obj_surface->height; break; default: /* Never get here */ MEDIA_DRV_ASSERT (0); break; } } else { MEDIA_DRV_ASSERT (subsampling == SUBSAMPLE_YUV420 || subsampling == SUBSAMPLE_YUV422H || subsampling == SUBSAMPLE_YUV422V || subsampling == SUBSAMPLE_RGBX || subsampling == SUBSAMPLE_P208); region_width = obj_surface->width; region_height = obj_surface->height; switch (fourcc) { case VA_FOURCC ('N', 'V', '1', '2'): obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->height; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->cb_cr_pitch = obj_surface->width; region_height = obj_surface->height + obj_surface->height / 2; break; case VA_FOURCC ('Y', 'V', '1', '2'): case VA_FOURCC ('I', '4', '2', '0'): if (fourcc == VA_FOURCC ('Y', 'V', '1', '2')) { obj_surface->y_cr_offset = obj_surface->height; obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4; } else { obj_surface->y_cb_offset = obj_surface->height; obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4; } obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height / 2; obj_surface->cb_cr_pitch = obj_surface->width / 2; region_height = obj_surface->height + obj_surface->height / 2; break; case VA_FOURCC ('Y', 'U', 'Y', '2'): case VA_FOURCC ('U', 'Y', 'V', 'Y'): obj_surface->width = ALIGN (obj_surface->orig_width * 2, 16); obj_surface->y_cb_offset = 0; obj_surface->y_cr_offset = 0; obj_surface->cb_cr_width = obj_surface->orig_width / 2; obj_surface->cb_cr_height = obj_surface->orig_height; obj_surface->cb_cr_pitch = obj_surface->width; region_width = obj_surface->width; region_height = obj_surface->height; break; case VA_FOURCC ('R', 'G', 'B', 'A'): case VA_FOURCC ('R', 'G', 'B', 'X'): case VA_FOURCC ('B', 'G', 'R', 'A'): case VA_FOURCC ('B', 'G', 'R', 'X'): obj_surface->width = ALIGN (obj_surface->orig_width * 4, 16); region_width = obj_surface->width; region_height = obj_surface->height; break; case VA_FOURCC ('P', '2', '0', '8'): obj_surface->width = ALIGN (obj_surface->orig_width, 32); region_width = obj_surface->width; region_height = obj_surface->height; break; default: /* Never get here */ MEDIA_DRV_ASSERT (0); break; } } obj_surface->size = ALIGN (region_width * region_height, 0x1000); if (tiled) { UINT tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */ ULONG pitch; obj_surface->bo = drm_intel_bo_alloc_tiled (drv_ctx->drv_data.bufmgr, "vaapi surface", region_width, region_height, 1, &tiling_mode, &pitch, 0); MEDIA_DRV_ASSERT (tiling_mode == I915_TILING_Y); MEDIA_DRV_ASSERT (pitch == obj_surface->width); } else { obj_surface->bo = dri_bo_alloc (drv_ctx->drv_data.bufmgr, "vaapi surface", obj_surface->size, 0x1000); } obj_surface->fourcc = fourcc; obj_surface->subsampling = subsampling; MEDIA_DRV_ASSERT (obj_surface->bo); }