/*
 * Function: XvMCCreateSurface
 */
_X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
				   XvMCSurface * surface)
{
	Status ret;
	int priv_count;
	CARD32 *priv_data;
	intel_xvmc_surface_ptr intel_surf = NULL;
	struct intel_xvmc_context *intel_ctx;

	if (!display || !context)
		return XvMCBadContext;

	if (!surface)
		return XvMCBadSurface;

	intel_ctx = context->privData;

	if ((ret = _xvmc_create_surface(display, context, surface,
					&priv_count, &priv_data))) {
		XVMC_ERR("Unable to create XvMCSurface.");
		return ret;
	}

	XFree(priv_data);

	surface->privData = calloc(1, sizeof(struct intel_xvmc_surface));

	if (!(intel_surf = surface->privData)) {
		PPTHREAD_MUTEX_UNLOCK();
		return BadAlloc;
	}

	intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
					      "surface",
					      intel_ctx->surface_bo_size,
					      GTT_PAGE_SIZE);
	if (!intel_surf->bo) {
		free(intel_surf);
		return BadAlloc;
	}

	drm_intel_bo_disable_reuse(intel_surf->bo);

	intel_surf = surface->privData;
	intel_surf->context = context;

	intel_surf->image = XvCreateImage(display, context->port,
					  FOURCC_XVMC,
					  (char *) &intel_surf->gem_handle,
					  surface->width, surface->height);
	if (!intel_surf->image) {
		XVMC_ERR("Can't create XvImage for surface\n");
		free(intel_surf);
		_xvmc_destroy_surface(display, surface);
		return BadAlloc;
	}

	return Success;
}
int main(int argc, char **argv)
{
	int fd, i;

	fd = drm_open_any();

	bufmgr = drm_intel_bufmgr_gem_init(fd, 4096);
	if (!bufmgr) {
		fprintf(stderr, "failed to init libdrm\n");
		exit(-1);
	}
	/* don't enable buffer reuse!! */
	//drm_intel_bufmgr_gem_enable_reuse(bufmgr);

	batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd));
	assert(batch);

	/* put some load onto the gpu to keep the light buffers active for long
	 * enough */
	for (i = 0; i < 1000; i++) {
		load_bo = drm_intel_bo_alloc(bufmgr, "target bo", 1024*4096, 4096);
		if (!load_bo) {
			fprintf(stderr, "failed to alloc target buffer\n");
			exit(-1);
		}

		BEGIN_BATCH(8);
		OUT_BATCH(XY_SRC_COPY_BLT_CMD |
			  XY_SRC_COPY_BLT_WRITE_ALPHA |
			  XY_SRC_COPY_BLT_WRITE_RGB);
		OUT_BATCH((3 << 24) | /* 32 bits */
			  (0xcc << 16) | /* copy ROP */
			  4096);
		OUT_BATCH(0); /* dst x1,y1 */
		OUT_BATCH((1024 << 16) | 512);
		OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
		OUT_BATCH((0 << 16) | 512); /* src x1, y1 */
		OUT_BATCH(4096);
		OUT_RELOC(load_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
		ADVANCE_BATCH();

		intel_batchbuffer_flush(batch);

		drm_intel_bo_disable_reuse(load_bo);
		drm_intel_bo_unreference(load_bo);
	}

	drm_intel_bufmgr_destroy(bufmgr);

	close(fd);

	return 0;
}
Esempio n. 3
0
drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn,
					 int width, int height, int cpp,
					 int *out_stride,
					 uint32_t *out_tiling)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);
	uint32_t tiling;
	int stride, size;
	drm_intel_bo *bo;

	intel_set_gem_max_sizes(scrn);

	if (intel->tiling & INTEL_TILING_FB)
		tiling = I915_TILING_X;
	else
		tiling = I915_TILING_NONE;

retry:
	size = intel_compute_size(intel,
                                  width, height,
                                  intel->cpp*8, 0,
                                  &tiling, &stride);
	if (!intel_check_display_stride(scrn, stride, tiling)) {
		if (tiling != I915_TILING_NONE) {
			tiling = I915_TILING_NONE;
			goto retry;
		}

		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
			   "Front buffer stride %d kB "
			   "exceeds display limit\n", stride / 1024);
		return NULL;
	}

	bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0);
	if (bo == NULL)
		return FALSE;

	if (tiling != I915_TILING_NONE)
		drm_intel_bo_set_tiling(bo, &tiling, stride);

	xf86DrvMsg(scrn->scrnIndex, X_INFO,
		   "Allocated new frame buffer %dx%d stride %d, %s\n",
		   width, height, stride,
		   tiling == I915_TILING_NONE ? "untiled" : "tiled");

	drm_intel_bo_disable_reuse(bo);

	*out_stride = stride;
	*out_tiling = tiling;
	return bo;
}