Exemple #1
0
void intel_debug_flush(ScrnInfoPtr scrn)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);

	if (intel->debug_flush & DEBUG_FLUSH_CACHES)
		intel_batch_emit_flush(scrn);

	if (intel->debug_flush & DEBUG_FLUSH_BATCHES)
		intel_batch_submit(scrn);
}
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;
}
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;
}