Beispiel #1
0
void intel_batch_emit_flush(ScrnInfoPtr scrn)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);
	int flags;

	assert (!intel->in_batch_atomic);

	/* Big hammer, look to the pipelined flushes in future. */
	if ((INTEL_INFO(intel)->gen >= 060)) {
		if (intel->current_batch == BLT_BATCH) {
			BEGIN_BATCH_BLT(4);
			OUT_BATCH(MI_FLUSH_DW | 2);
			OUT_BATCH(0);
			OUT_BATCH(0);
			OUT_BATCH(0);
			ADVANCE_BATCH();
		} else  {
			if ((INTEL_INFO(intel)->gen == 060)) {
				/* HW-Workaround for Sandybdrige */
				intel_emit_post_sync_nonzero_flush(scrn);
			} else {
				BEGIN_BATCH(4);
				OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
				OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH |
					  BRW_PIPE_CONTROL_TC_FLUSH |
					  BRW_PIPE_CONTROL_NOWRITE);
				OUT_BATCH(0); /* write address */
				OUT_BATCH(0); /* write data */
				ADVANCE_BATCH();
			}
		}
	} else {
		flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
		if (INTEL_INFO(intel)->gen >= 040)
			flags = 0;

		BEGIN_BATCH(1);
		OUT_BATCH(MI_FLUSH | flags);
		ADVANCE_BATCH();
	}
	intel_batch_do_flush(scrn);
}
Beispiel #2
0
static void i915_emit_composite_setup(ScrnInfoPtr scrn)
{
	intel_screen_private *intel = intel_get_screen_private(scrn);
	int op = intel->i915_render_state.op;
	PicturePtr mask_picture = intel->render_mask_picture;
	PicturePtr dest_picture = intel->render_dest_picture;
	PixmapPtr mask = intel->render_mask;
	PixmapPtr dest = intel->render_dest;
	Bool is_solid_src, is_solid_mask;
	int tex_count, t;

	intel->needs_render_state_emit = FALSE;

	IntelEmitInvarientState(scrn);
	intel->last_3d = LAST_3D_RENDER;

	is_solid_src = intel->render_source_is_solid;
	is_solid_mask = intel->render_mask_is_solid;

	tex_count = 0;
	tex_count += ! is_solid_src;
	tex_count += mask && ! is_solid_mask;

	assert(intel->in_batch_atomic);

	if (tex_count != 0) {
	    OUT_BATCH(_3DSTATE_MAP_STATE | (3 * tex_count));
	    OUT_BATCH((1 << tex_count) - 1);
	    for (t = 0; t < tex_count; t++) {
		OUT_RELOC_PIXMAP(intel->texture[t], I915_GEM_DOMAIN_SAMPLER, 0, 0);
		OUT_BATCH(intel->mapstate[3*t + 1]);
		OUT_BATCH(intel->mapstate[3*t + 2]);
	    }

	    OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * tex_count));
	    OUT_BATCH((1 << tex_count) - 1);
	    for (t = 0; t < tex_count; t++) {
		OUT_BATCH(intel->samplerstate[3*t + 0]);
		OUT_BATCH(intel->samplerstate[3*t + 1]);
		OUT_BATCH(intel->samplerstate[3*t + 2]);
	    }
	}

	if (is_solid_src) {
	    OUT_BATCH (_3DSTATE_DFLT_DIFFUSE_CMD);
	    OUT_BATCH (intel->render_source_solid);
	}
	if (mask && is_solid_mask) {
	    OUT_BATCH (_3DSTATE_DFLT_SPEC_CMD);
	    OUT_BATCH (intel->render_mask_solid);
	}

	/* BUF_INFO is an implicit flush, so avoid if the target has not changed.
	 * XXX However for reasons unfathomed, correct rendering in KDE requires
	 * at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here.
	 */
	if (1 || dest != intel->render_current_dest) {
		uint32_t tiling_bits;

		intel_batch_do_flush(scrn);

		if (intel_pixmap_tiled(dest)) {
			tiling_bits = BUF_3D_TILED_SURFACE;
			if (intel_get_pixmap_private(dest)->tiling
			    == I915_TILING_Y)
				tiling_bits |= BUF_3D_TILE_WALK_Y;
		} else
			tiling_bits = 0;

		OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
		OUT_BATCH(BUF_3D_ID_COLOR_BACK | tiling_bits |
			  BUF_3D_PITCH(intel_pixmap_pitch(dest)));
		OUT_RELOC_PIXMAP(dest, I915_GEM_DOMAIN_RENDER,
				 I915_GEM_DOMAIN_RENDER, 0);

		OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
		OUT_BATCH(intel->i915_render_state.dst_format);

		/* draw rect is unconditional */
		OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
		OUT_BATCH(0x00000000);
		OUT_BATCH(0x00000000);	/* ymin, xmin */
		OUT_BATCH(DRAW_YMAX(dest->drawable.height - 1) |
			  DRAW_XMAX(dest->drawable.width - 1));
		/* yorig, xorig (relate to color buffer?) */
		OUT_BATCH(0x00000000);

		intel->render_current_dest = dest;
	}

	{
		uint32_t ss2;

		ss2 = ~0;
		t = 0;
		if (! is_solid_src) {
		    ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
		    ss2 |= S2_TEXCOORD_FMT(t,
					   intel_transform_is_affine(intel->transform[t]) ?
					   TEXCOORDFMT_2D : TEXCOORDFMT_4D);
		    t++;
		}
		if (mask && ! is_solid_mask) {
		    ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
		    ss2 |= S2_TEXCOORD_FMT(t,
					   intel_transform_is_affine(intel->transform[t]) ?
					   TEXCOORDFMT_2D : TEXCOORDFMT_4D);
		    t++;
		}

		if (intel->needs_render_ca_pass) {
			OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | 0);
			OUT_BATCH(ss2);
		} else {
			OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(2) | I1_LOAD_S(6) | 1);
			OUT_BATCH(ss2);
			OUT_BATCH(i915_get_blend_cntl(op, mask_picture, dest_picture->format));
		}
	}

	if (! intel->needs_render_ca_pass)
		i915_composite_emit_shader(intel, op);
}
Beispiel #3
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;
}