Esempio n. 1
0
Bool
i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
	if (picture->repeatType > RepeatReflect) {
		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
		intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
			     picture->repeatType);
		return FALSE;
	}

	if (picture->filter != PictFilterNearest &&
	    picture->filter != PictFilterBilinear) {
		ScrnInfoPtr scrn = xf86Screens[screen->myNum];
		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
				     picture->filter);
		return FALSE;
	}

	if (picture->pSourcePict) {
		SourcePict *source = picture->pSourcePict;
		if (source->type == SourcePictTypeSolidFill)
			return TRUE;
	}

	if (picture->pDrawable) {
		int w, h, i;

		w = picture->pDrawable->width;
		h = picture->pDrawable->height;
		if ((w > 2048) || (h > 2048)) {
			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
			intel_debug_fallback(scrn,
					     "Picture w/h too large (%dx%d)\n",
					     w, h);
			return FALSE;
		}

		for (i = 0;
		     i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
		     i++) {
			if (i915_tex_formats[i].fmt == picture->format)
				break;
		}
		if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
		{
			ScrnInfoPtr scrn = xf86Screens[screen->myNum];
			intel_debug_fallback(scrn, "Unsupported picture format "
					     "0x%x\n",
					     (int)picture->format);
			return FALSE;
		}

		return TRUE;
	}

	return FALSE;
}
Esempio n. 2
0
static Bool i830_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
{
	ScrnInfoPtr scrn;

	switch (dest_picture->format) {
	case PICT_a8r8g8b8:
	case PICT_x8r8g8b8:
		*dst_format = COLR_BUF_ARGB8888;
		break;
	case PICT_r5g6b5:
		*dst_format = COLR_BUF_RGB565;
		break;
	case PICT_a1r5g5b5:
	case PICT_x1r5g5b5:
		*dst_format = COLR_BUF_ARGB1555;
		break;
	case PICT_a8:
		*dst_format = COLR_BUF_8BIT;
		break;
	case PICT_a4r4g4b4:
	case PICT_x4r4g4b4:
		*dst_format = COLR_BUF_ARGB4444;
		break;
	default:
		scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
		intel_debug_fallback(scrn, "Unsupported dest format 0x%x\n",
				     (int)dest_picture->format);
		return FALSE;
	}
	*dst_format |= DSTORG_HORT_BIAS(0x8) | DSTORG_VERT_BIAS(0x8);
	return TRUE;
}
Esempio n. 3
0
Bool
i915_check_composite(int op,
		     PicturePtr source_picture,
		     PicturePtr mask_picture,
		     PicturePtr dest_picture,
		     int width, int height)
{
	ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
	uint32_t tmp1;

	/* Check for unsupported compositing operations. */
	if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
		intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
				     op);
		return FALSE;
	}
	if (mask_picture != NULL && mask_picture->componentAlpha &&
	    PICT_FORMAT_RGB(mask_picture->format)) {
		/* Check if it's component alpha that relies on a source alpha
		 * and on the source value.  We can only get one of those
		 * into the single source value that we get to blend with.
		 */
		if (i915_blend_op[op].src_alpha &&
		    (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
			if (op != PictOpOver) {
				intel_debug_fallback(scrn,
						     "Component alpha not supported "
						     "with source alpha and source "
						     "value blending.\n");
				return FALSE;
			}
		}
	}

	if (!i915_get_dest_format(dest_picture, &tmp1)) {
		intel_debug_fallback(scrn, "Get Color buffer format\n");
		return FALSE;
	}

	if (width > 2048 || height > 2048)
		return FALSE;

	return TRUE;
}
Esempio n. 4
0
Bool
i830_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
	intel_screen_private *intel = intel_get_screen_private(scrn);

	if (picture->repeatType > RepeatReflect) {
		intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
			     picture->repeatType);
		return FALSE;
	}

	if (picture->filter != PictFilterNearest &&
	    picture->filter != PictFilterBilinear) {
		intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
				     picture->filter);
		return FALSE;
	}

	if (picture->pDrawable) {
		int w, h;

		w = picture->pDrawable->width;
		h = picture->pDrawable->height;
		if ((w > 2048) || (h > 2048)) {
			intel_debug_fallback(scrn,
					     "Picture w/h too large (%dx%d)\n",
					     w, h);
			return FALSE;
		}

		/* XXX we can use the xrgb32 types if there the picture covers the clip */
		if (!i8xx_get_card_format(intel, picture)) {
			intel_debug_fallback(scrn, "Unsupported picture format "
					     "0x%x\n",
					     (int)picture->format);
			return FALSE;
		}

		return TRUE;
	}

	return FALSE;
}
Esempio n. 5
0
Bool
i830_check_composite(int op,
		     PicturePtr source_picture,
		     PicturePtr mask_picture,
		     PicturePtr dest_picture,
		     int width, int height)
{
	ScrnInfoPtr scrn = xf86ScreenToScrn(dest_picture->pDrawable->pScreen);
	uint32_t tmp1;

	/* Check for unsupported compositing operations. */
	if (op >= sizeof(i830_blend_op) / sizeof(i830_blend_op[0])) {
		intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
				     op);
		return FALSE;
	}

	if (mask_picture != NULL && mask_picture->componentAlpha &&
	    PICT_FORMAT_RGB(mask_picture->format)) {
		/* Check if it's component alpha that relies on a source alpha and on
		 * the source value.  We can only get one of those into the single
		 * source value that we get to blend with.
		 */
		if (i830_blend_op[op].src_alpha &&
		    (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) {
			intel_debug_fallback(scrn, "Component alpha not "
					     "supported with source alpha and "
					     "source value blending.\n");
			return FALSE;
		}
	}

	if (!i830_get_dest_format(dest_picture, &tmp1)) {
		intel_debug_fallback(scrn, "Get Color buffer format\n");
		return FALSE;
	}

	if (width > 2048 || height > 2048) {
		intel_debug_fallback(scrn, "Operation is too large (%d, %d)\n", width, height);
		return FALSE;
	}

	return TRUE;
}
Esempio n. 6
0
Bool
intel_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
			 int num_bos)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);

	if (intel->batch_bo == NULL) {
		intel_debug_fallback(scrn, "VT inactive\n");
		return FALSE;
	}

	bo_table[0] = intel->batch_bo;
	if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) != 0) {
		intel_batch_submit(scrn);
		bo_table[0] = intel->batch_bo;
		if (drm_intel_bufmgr_check_aperture_space(bo_table, num_bos) !=
		    0) {
			intel_debug_fallback(scrn, "Couldn't get aperture "
					    "space for BOs\n");
			return FALSE;
		}
	}
	return TRUE;
}
Esempio n. 7
0
static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask,
				uint32_t dst_format, uint32_t * blendctl)
{
	uint32_t sblend, dblend;

	sblend = i830_blend_op[op].src_blend;
	dblend = i830_blend_op[op].dst_blend;

	/* If there's no dst alpha channel, adjust the blend op so that we'll treat
	 * it as always 1.
	 */
	if (PICT_FORMAT_A(dst_format) == 0 && i830_blend_op[op].dst_alpha) {
		if (sblend == BLENDFACTOR_DST_ALPHA)
			sblend = BLENDFACTOR_ONE;
		else if (sblend == BLENDFACTOR_INV_DST_ALPHA)
			sblend = BLENDFACTOR_ZERO;
	}

	/* For blending purposes, COLR_BUF_8BIT values show up in the green
	 * channel.  So we can't use the alpha channel.
	 */
	if (dst_format == PICT_a8 && ((sblend == BLENDFACTOR_DST_ALPHA ||
				       sblend == BLENDFACTOR_INV_DST_ALPHA))) {
		intel_debug_fallback(scrn, "Can't do dst alpha blending with "
				     "PICT_a8 dest.\n");
		return FALSE;
	}

	/* If the source alpha is being used, then we should only be in a case
	 * where the source blend factor is 0, and the source blend value is the
	 * mask channels multiplied by the source picture's alpha.
	 */
	if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format)
	    && i830_blend_op[op].src_alpha) {
		if (dblend == BLENDFACTOR_SRC_ALPHA) {
			dblend = BLENDFACTOR_SRC_COLR;
		} else if (dblend == BLENDFACTOR_INV_SRC_ALPHA) {
			dblend = BLENDFACTOR_INV_SRC_COLR;
		}
	}

	*blendctl = (sblend << S8_SRC_BLEND_FACTOR_SHIFT) |
	    (dblend << S8_DST_BLEND_FACTOR_SHIFT);

	return TRUE;
}
Esempio n. 8
0
static Bool
intel_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
{
	ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum];

	if (!UXA_PM_IS_SOLID(drawable, planemask)) {
		intel_debug_fallback(scrn, "planemask is not solid\n");
		return FALSE;
	}

	switch (drawable->bitsPerPixel) {
	case 8:
	case 16:
	case 32:
		break;
	default:
		return FALSE;
	}

	return TRUE;
}
Esempio n. 9
0
Bool
i915_prepare_composite(int op, PicturePtr source_picture,
		       PicturePtr mask_picture, PicturePtr dest_picture,
		       PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
{
	ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
	intel_screen_private *intel = intel_get_screen_private(scrn);
	drm_intel_bo *bo_table[] = {
		NULL,		/* batch_bo */
		intel_get_pixmap_bo(dest),
		source ? intel_get_pixmap_bo(source) : NULL,
		mask ? intel_get_pixmap_bo(mask) : NULL,
	};
	int tex_unit = 0;
	int floats_per_vertex;

	intel->render_source_picture = source_picture;
	intel->render_source = source;
	intel->render_mask_picture = mask_picture;
	intel->render_mask = mask;
	intel->render_dest_picture = dest_picture;
	intel->render_dest = dest;

	intel->render_source_is_solid = FALSE;
	if (source_picture->pSourcePict) {
		SourcePict *source = source_picture->pSourcePict;
		if (source->type == SourcePictTypeSolidFill) {
			intel->render_source_is_solid = TRUE;
			intel->render_source_solid = source->solidFill.color;
		}
	}
	if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
		return FALSE;

	intel->render_mask_is_solid = FALSE;
	if (mask) {
		if (mask_picture->pSourcePict) {
			SourcePict *source = mask_picture->pSourcePict;
			if (source->type == SourcePictTypeSolidFill) {
				intel->render_mask_is_solid = TRUE;
				intel->render_mask_solid = source->solidFill.color;
			}
		}
		if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
			return FALSE;
	}

	if (!intel_check_pitch_3d(dest))
		return FALSE;

	if (!i915_get_dest_format(dest_picture,
				  &intel->i915_render_state.dst_format))
		return FALSE;

	if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
		return FALSE;

	intel->needs_render_ca_pass = FALSE;
	if (mask_picture != NULL && mask_picture->componentAlpha &&
	    PICT_FORMAT_RGB(mask_picture->format)) {
		/* Check if it's component alpha that relies on a source alpha
		 * and on the source value.  We can only get one of those
		 * into the single source value that we get to blend with.
		 */
		if (i915_blend_op[op].src_alpha &&
		    (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
			if (op != PictOpOver)
				return FALSE;

			intel->needs_render_ca_pass = TRUE;
		}
	}

	intel->transform[0] = NULL;
	intel->scale_units[0][0] = -1;
	intel->scale_units[0][1] = -1;
	intel->transform[1] = NULL;
	intel->scale_units[1][0] = -1;
	intel->scale_units[1][1] = -1;

	floats_per_vertex = 2;		/* dest x/y */
	if (! intel->render_source_is_solid) {
		if (!i915_texture_setup(source_picture, source, tex_unit++)) {
			intel_debug_fallback(scrn, "fail to setup src texture\n");
			return FALSE;
		}

		if (intel_transform_is_affine(source_picture->transform))
			floats_per_vertex += 2;	/* src x/y */
		else
			floats_per_vertex += 4;	/* src x/y/z/w */
	}

	if (mask != NULL) {
		if (! intel->render_mask_is_solid) {
			if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
				intel_debug_fallback(scrn,
						"fail to setup mask texture\n");
				return FALSE;
			}

			if (intel_transform_is_affine(mask_picture->transform))
				floats_per_vertex += 2;	/* mask x/y */
			else
				floats_per_vertex += 4;	/* mask x/y/z/w */
		}
	}

	intel->i915_render_state.op = op;

	/* BUF_INFO is an implicit flush */
	if (dest != intel->render_current_dest)
		intel_batch_do_flush(scrn);
	else if((source && intel_pixmap_is_dirty(source)) ||
		(mask && intel_pixmap_is_dirty(mask)))
		intel_batch_emit_flush(scrn);

	intel->needs_render_state_emit = TRUE;

	intel->prim_emit = i915_emit_composite_primitive;
	if (!mask) {
		if (intel->render_source_is_solid)
			intel->prim_emit = i915_emit_composite_primitive_constant;
		else if (intel->transform[0] == NULL)
			intel->prim_emit = i915_emit_composite_primitive_identity_source;
		else if (intel_transform_is_affine(intel->transform[0]))
			intel->prim_emit = i915_emit_composite_primitive_affine_source;
	} else {
		if (intel->transform[0] == NULL) {
			if (intel->render_source_is_solid)
				intel->prim_emit = i915_emit_composite_primitive_constant_identity_mask;
			else if (intel->transform[1] == NULL)
				intel->prim_emit = i915_emit_composite_primitive_identity_source_mask;
		}
	}

	if (floats_per_vertex != intel->floats_per_vertex) {
		intel->floats_per_vertex = floats_per_vertex;
		intel->needs_render_vertex_emit = TRUE;
	}

	return TRUE;
}
Esempio n. 10
0
static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
{
	ScrnInfoPtr scrn = xf86Screens[picture->pDrawable->pScreen->myNum];
	intel_screen_private *intel = intel_get_screen_private(scrn);
	uint32_t format, pitch, filter;
	uint32_t wrap_mode, tiling_bits;
	int i;

	pitch = intel_pixmap_pitch(pixmap);
	intel->scale_units[unit][0] = 1. / pixmap->drawable.width;
	intel->scale_units[unit][1] = 1. / pixmap->drawable.height;

	for (i = 0; i < sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]);
	     i++) {
		if (i915_tex_formats[i].fmt == picture->format)
			break;
	}
	if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0])) {
		intel_debug_fallback(scrn, "unknown texture format\n");
		return FALSE;
	}
	format = i915_tex_formats[i].card_fmt;

	switch (picture->repeatType) {
	case RepeatNone:
		wrap_mode = TEXCOORDMODE_CLAMP_BORDER;
		break;
	case RepeatNormal:
		wrap_mode = TEXCOORDMODE_WRAP;
		break;
	case RepeatPad:
		wrap_mode = TEXCOORDMODE_CLAMP_EDGE;
		break;
	case RepeatReflect:
		wrap_mode = TEXCOORDMODE_MIRROR;
		break;
	default:
		FatalError("Unknown repeat type %d\n", picture->repeatType);
	}

	switch (picture->filter) {
	case PictFilterNearest:
		filter = (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT) |
		    (FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
		break;
	case PictFilterBilinear:
		filter = (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) |
		    (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT);
		break;
	default:
		filter = 0;
		intel_debug_fallback(scrn, "Bad filter 0x%x\n",
				     picture->filter);
		return FALSE;
	}

	/* offset filled in at emit time */
	if (intel_pixmap_tiled(pixmap)) {
		tiling_bits = MS3_TILED_SURFACE;
		if (intel_get_pixmap_private(pixmap)->tiling
				== I915_TILING_Y)
			tiling_bits |= MS3_TILE_WALK;
	} else
		tiling_bits = 0;

	intel->texture[unit] = pixmap;
	intel->mapstate[unit * 3 + 0] = 0;
	intel->mapstate[unit * 3 + 1] = format |
	    tiling_bits |
	    ((pixmap->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
	    ((pixmap->drawable.width - 1) << MS3_WIDTH_SHIFT);
	intel->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;

	intel->samplerstate[unit * 3 + 0] = (MIPFILTER_NONE <<
					     SS2_MIP_FILTER_SHIFT);
	intel->samplerstate[unit * 3 + 0] |= filter;
	intel->samplerstate[unit * 3 + 1] = SS3_NORMALIZED_COORDS;
	intel->samplerstate[unit * 3 + 1] |=
	    wrap_mode << SS3_TCX_ADDR_MODE_SHIFT;
	intel->samplerstate[unit * 3 + 1] |=
	    wrap_mode << SS3_TCY_ADDR_MODE_SHIFT;
	intel->samplerstate[unit * 3 + 1] |= unit << SS3_TEXTUREMAP_INDEX_SHIFT;
	intel->samplerstate[unit * 3 + 2] = 0x00000000;	/* border color */

	intel->transform[unit] = picture->transform;

	return TRUE;
}
Esempio n. 11
0
Bool
i830_prepare_composite(int op, PicturePtr source_picture,
		       PicturePtr mask_picture, PicturePtr dest_picture,
		       PixmapPtr source, PixmapPtr mask, PixmapPtr dest)
{
	ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
	intel_screen_private *intel = intel_get_screen_private(scrn);
	drm_intel_bo *bo_table[] = {
		NULL,		/* batch_bo */
		intel_get_pixmap_bo(source),
		mask ? intel_get_pixmap_bo(mask) : NULL,
		intel_get_pixmap_bo(dest),
	};

	intel->render_source_picture = source_picture;
	intel->render_source = source;
	intel->render_mask_picture = mask_picture;
	intel->render_mask = mask;
	intel->render_dest_picture = dest_picture;
	intel->render_dest = dest;

	if (!intel_check_pitch_3d(source))
		return FALSE;
	if (mask) {
		if (mask_picture->componentAlpha &&
		    PICT_FORMAT_RGB(mask_picture->format)) {
			/* Check if it's component alpha that relies on a source alpha and on
			 * the source value.  We can only get one of those into the single
			 * source value that we get to blend with.
			 */
			if (i830_blend_op[op].src_alpha &&
			    (i830_blend_op[op].src_blend != BLENDFACTOR_ZERO)) {
				intel_debug_fallback(scrn, "Component alpha not "
						     "supported with source alpha and "
						     "source value blending.\n");
				return FALSE;
			}
		}
		if (!intel_check_pitch_3d(mask))
			return FALSE;
	}
	if (!intel_check_pitch_3d(dest))
		return FALSE;

	if (!i830_get_dest_format(dest_picture, &intel->render_dest_format))
		return FALSE;

	if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
		return FALSE;

	if (mask) {
		intel->transform[1] = NULL;
		intel->scale_units[1][0] = -1;
		intel->scale_units[1][1] = -1;
	}

	{
		uint32_t cblend, ablend, blendctl;

		/* If component alpha is active in the mask and the blend operation
		 * uses the source alpha, then we know we don't need the source
		 * value (otherwise we would have hit a fallback earlier), so we
		 * provide the source alpha (src.A * mask.X) as output color.
		 * Conversely, if CA is set and we don't need the source alpha, then
		 * we produce the source value (src.X * mask.X) and the source alpha
		 * is unused..  Otherwise, we provide the non-CA source value
		 * (src.X * mask.A).
		 *
		 * The PICT_FORMAT_RGB(pict) == 0 fixups are not needed on 855+'s a8
		 * pictures, but we need to implement it for 830/845 and there's no
		 * harm done in leaving it in.
		 */
		cblend =
		    TB0C_LAST_STAGE | TB0C_RESULT_SCALE_1X | TB0C_OP_MODULE |
		    TB0C_OUTPUT_WRITE_CURRENT;
		ablend =
		    TB0A_RESULT_SCALE_1X | TB0A_OP_MODULE |
		    TB0A_OUTPUT_WRITE_CURRENT;

		/* Get the source picture's channels into TBx_ARG1 */
		if ((mask_picture != NULL &&
		     mask_picture->componentAlpha &&
		     PICT_FORMAT_RGB(mask_picture->format) &&
		     i830_blend_op[op].src_alpha)
		    || dest_picture->format == PICT_a8) {
			/* Producing source alpha value, so the first set of channels
			 * is src.A instead of src.X.  We also do this if the destination
			 * is a8, in which case src.G is what's written, and the other
			 * channels are ignored.
			 */
			ablend |= TB0A_ARG1_SEL_TEXEL0;
			cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA;
		} else {
			if (PICT_FORMAT_RGB(source_picture->format) != 0)
				cblend |= TB0C_ARG1_SEL_TEXEL0;
			else
				cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT;	/* 0.0 */
			ablend |= TB0A_ARG1_SEL_TEXEL0;
		}

		if (mask) {
			cblend |= TB0C_ARG2_SEL_TEXEL1;
			if (dest_picture->format == PICT_a8 ||
			    ! mask_picture->componentAlpha ||
			    ! PICT_FORMAT_RGB(mask_picture->format))
				cblend |= TB0C_ARG2_REPLICATE_ALPHA;
			ablend |= TB0A_ARG2_SEL_TEXEL1;
		} else {
			cblend |= TB0C_ARG2_SEL_ONE;
			ablend |= TB0A_ARG2_SEL_ONE;
		}

		if (!i830_get_blend_cntl
		    (scrn, op, mask_picture, dest_picture->format, &blendctl)) {
			return FALSE;
		}

		intel->cblend = cblend;
		intel->ablend = ablend;
		intel->s8_blendctl = blendctl;
	}

	if(intel_pixmap_is_dirty(source) ||
	   (mask && intel_pixmap_is_dirty(mask)))
		intel_batch_emit_flush(scrn);

	intel->needs_render_state_emit = TRUE;

	return TRUE;
}