예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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);
}