xf86-video-intel: 2 commits - man/intel.man src/intel_module.c src/sna/gen2_render.c src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h src/sna/sna_module.h

Chris Wilson ickle at kemper.freedesktop.org
Tue Jun 7 08:59:35 PDT 2011


 man/intel.man         |   10 +++
 src/intel_module.c    |    4 -
 src/sna/gen2_render.c |  141 ++++++++++++++++++++++++++++++++------------------
 src/sna/sna.h         |    1 
 src/sna/sna_display.c |   77 +++++++++++++++++++++------
 src/sna/sna_driver.c  |   67 ++++++++++++++++++++---
 src/sna/sna_module.h  |    2 
 7 files changed, 226 insertions(+), 76 deletions(-)

New commits:
commit 265d94e0aa46b30a3198893544dd3619cc9145de
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 7 14:23:51 2011 +0100

    sna: Add zaphod support
    
    Zaphod support is a rudimentary method for creating an Xserver with
    multiple screens from a single device. The Device is instantiated, with
    a duplication of its resources, as many as required up to a maximum of
    the number of its outputs, and each instance is attached to a Screen
    and added to the ServerLayout. A Device can be bound to a selection of
    outputs using a comma separated list of RandR names.
    
    Note: in general, this is not the preferred solution! And will be
    superseded by per-crtc-pixmaps in RandR-1.4.
    
    For example, the following xorg.conf fragment creates an XServer with
    two screens, one attached to the LVDS panel on the laptop, and the other
    to any external output:
    
    Section "Device"
    	Identifier "Intel0"
    	Driver     "intel"
    	BusID	   "PCI:0:2:0"
    	Option     "ZaphodHeads" "LVDS1"
    	Screen     0
    EndSection
    
    Section "Device"
    	Identifier "Intel1"
    	Driver     "intel"
    	BusID	   "PCI:0:2:0"
    	Option     "ZaphodHeads" "DVI1,VGA1"
    	Screen     1
    EndSection
    
    Section "Screen"
    	Identifier "Screen0"
    	Device     "Intel0"
    EndSection
    
    Section "Screen"
    	Identifier "Screen1"
    	Device     "Intel1"
    EndSection
    
    Section "ServerLayout"
    	Identifier "default"
    	Screen     "Screen0"
    	Screen     "Screen1"
    EndSection
    
    Based on a patch by Ben Skegs <bskeggs at redhat.com>
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/man/intel.man b/man/intel.man
index ab46db2..e5e0572 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -222,6 +222,16 @@ This option controls whether the driver automatically notifies
 applications when monitors are connected or disconnected.
 .IP
 Default: enabled.
+.BI "Option \*qZaphodHeads\*q \*q" string \*q
+.IP
+Specify the randr output(s) to use with zaphod mode for a particular driver
+instance.  If you this option you must use it with all instances of the
+driver
+.br
+For example:
+.B
+Option \*qZaphodHeads\*q \*qLVDS1,VGA1\*q
+will assign xrandr outputs LVDS1 and VGA0 to this instance of the driver.
 
 .SH OUTPUT CONFIGURATION
 On 830M and better chipsets, the driver supports runtime configuration of
diff --git a/src/intel_module.c b/src/intel_module.c
index 12097df..bec3d0f 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -363,12 +363,12 @@ static Bool intel_pci_probe(DriverPtr		driver,
 		case PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS:
 		case PCI_CHIP_SANDYBRIDGE_S_GT:
 #endif
-			sna_init_scrn(scrn);
+			sna_init_scrn(scrn, entity_num);
 			break;
 #endif
 		default:
 #if SNA_DEFAULT
-			sna_init_scrn(scrn);
+			sna_init_scrn(scrn, entity_num);
 #else
 			intel_init_scrn(scrn);
 #endif
diff --git a/src/sna/sna.h b/src/sna/sna.h
index cb4b61a..e36ef48 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -201,6 +201,7 @@ enum {
 	OPTION_THROTTLE,
 	OPTION_RELAXED_FENCING,
 	OPTION_VMAP,
+	OPTION_ZAPHOD,
 };
 
 enum {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index d27eafd..847d821 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1231,6 +1231,43 @@ static const char *output_names[] = {
 	"eDP",
 };
 
+static bool
+sna_zaphod_match(ScrnInfoPtr scrn, const char *s, const char *output)
+{
+	char t[20];
+	int i = 0;
+
+	do {
+		/* match any outputs in a comma list, stopping at whitespace */
+		switch (*s) {
+		case '\0':
+			t[i] = '\0';
+			return strcmp(t, output) == 0;
+
+		case ',':
+			t[i] ='\0';
+			if (strcmp(t, output) == 0)
+				return TRUE;
+			i = 0;
+			break;
+
+		case ' ':
+		case '\t':
+		case '\n':
+		case '\r':
+			break;
+
+		default:
+			t[i++] = *s;
+			break;
+		}
+
+		s++;
+	} while (i < sizeof(t));
+
+	return FALSE;
+}
+
 static void
 sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 {
@@ -1240,6 +1277,7 @@ sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 	drmModeEncoderPtr kencoder;
 	struct sna_output *sna_output;
 	const char *output_name;
+	const char *s;
 	char name[32];
 
 	koutput = drmModeGetConnector(sna->kgem.fd,
@@ -1248,10 +1286,8 @@ sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		return;
 
 	kencoder = drmModeGetEncoder(sna->kgem.fd, koutput->encoders[0]);
-	if (!kencoder) {
-		drmModeFreeConnector(koutput);
-		return;
-	}
+	if (!kencoder)
+		goto cleanup_connector;
 
 	if (koutput->connector_type < ARRAY_SIZE(output_names))
 		output_name = output_names[koutput->connector_type];
@@ -1259,20 +1295,22 @@ sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 		output_name = "UNKNOWN";
 	snprintf(name, 32, "%s%d", output_name, koutput->connector_type_id);
 
-	output = xf86OutputCreate (scrn, &sna_output_funcs, name);
-	if (!output) {
-		drmModeFreeEncoder(kencoder);
-		drmModeFreeConnector(koutput);
-		return;
+	if (xf86IsEntityShared(scrn->entityList[0])) {
+		s = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
+		if (s && !sna_zaphod_match(scrn, s, name)) {
+			ErrorF("output '%s' not matched for zaphod '%s'\n",
+			       name, s);
+			goto cleanup_encoder;
+		}
 	}
 
+	output = xf86OutputCreate(scrn, &sna_output_funcs, name);
+	if (!output)
+		goto cleanup_encoder;
+
 	sna_output = calloc(sizeof(struct sna_output), 1);
-	if (!sna_output) {
-		xf86OutputDestroy(output);
-		drmModeFreeConnector(koutput);
-		drmModeFreeEncoder(kencoder);
-		return;
-	}
+	if (!sna_output)
+		goto cleanup_output;
 
 	sna_output->output_id = mode->mode_res->connectors[num];
 	sna_output->mode_output = koutput;
@@ -1294,6 +1332,15 @@ sna_output_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 
 	sna_output->output = output;
 	list_add(&sna_output->link, &mode->outputs);
+
+	return;
+
+cleanup_output:
+	xf86OutputDestroy(output);
+cleanup_connector:
+	drmModeFreeConnector(koutput);
+cleanup_encoder:
+	drmModeFreeEncoder(kencoder);
 }
 
 struct sna_visit_set_pixmap_window {
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index b0df9aa..bbd1d49 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -81,6 +81,7 @@ static OptionInfoRec sna_options[] = {
    {OPTION_THROTTLE,	"Throttle",	OPTV_BOOLEAN,	{0},	TRUE},
    {OPTION_RELAXED_FENCING,	"UseRelaxedFencing",	OPTV_BOOLEAN,	{0},	TRUE},
    {OPTION_VMAP,	"UseVmap",	OPTV_BOOLEAN,	{0},	TRUE},
+   {OPTION_ZAPHOD,	"ZaphodHeads",	OPTV_STRING,	{0},	FALSE},
    {-1,			NULL,		OPTV_NONE,	{0},	FALSE}
 };
 
@@ -257,18 +258,41 @@ static Bool sna_get_early_options(ScrnInfoPtr scrn)
 	return TRUE;
 }
 
+struct sna_device {
+	int fd;
+	int open_count;
+};
+static int sna_device_key;
+
+static inline struct sna_device *sna_device(ScrnInfoPtr scrn)
+{
+	return xf86GetEntityPrivate(scrn->entityList[0], sna_device_key)->ptr;
+}
+
+static inline void sna_set_device(ScrnInfoPtr scrn, struct sna_device *dev)
+{
+	xf86GetEntityPrivate(scrn->entityList[0], sna_device_key)->ptr = dev;
+}
+
 static int sna_open_drm_master(ScrnInfoPtr scrn)
 {
+	struct sna_device *dev;
 	struct sna *sna = to_sna(scrn);
-	struct pci_device *dev = sna->PciInfo;
+	struct pci_device *pci = sna->PciInfo;
 	drmSetVersion sv;
 	struct drm_i915_getparam gp;
 	int err, val;
 	char busid[20];
 	int fd;
 
+	dev = sna_device(scrn);
+	if (dev) {
+		dev->open_count++;
+		return dev->fd;
+	}
+
 	snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%d",
-		 dev->domain, dev->bus, dev->dev, dev->func);
+		 pci->domain, pci->bus, pci->dev, pci->func);
 
 	fd = drmOpen("i915", busid);
 	if (fd == -1) {
@@ -305,15 +329,26 @@ static int sna_open_drm_master(ScrnInfoPtr scrn)
 		return -1;
 	}
 
+	dev = malloc(sizeof(*dev));
+	if (dev) {
+		dev->fd = fd;
+		dev->open_count = 1;
+		sna_set_device(scrn, dev);
+	}
+
 	return fd;
 }
 
-static void sna_close_drm_master(struct sna *sna)
+static void sna_close_drm_master(ScrnInfoPtr scrn)
 {
-	if (sna && sna->kgem.fd > 0) {
-		drmClose(sna->kgem.fd);
-		sna->kgem.fd = -1;
-	}
+	struct sna_device *dev = sna_device(scrn);
+
+	if (--dev->open_count)
+		return;
+
+	drmClose(dev->fd);
+	sna_set_device(scrn, NULL);
+	free(dev);
 }
 
 static void sna_selftest(void)
@@ -321,7 +356,6 @@ static void sna_selftest(void)
 	sna_damage_selftest();
 }
 
-
 /**
  * This is called before ScreenInit to do any require probing of screen
  * configuration.
@@ -811,12 +845,13 @@ static void sna_free_screen(int scrnIndex, int flags)
 
 	if (sna) {
 		sna_mode_fini(sna);
-		sna_close_drm_master(sna);
 
 		free(sna);
 		scrn->driverPrivate = NULL;
 	}
 
+	sna_close_drm_master(scrn);
+
 	if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
 		vgaHWFreeHWRec(xf86Screens[scrnIndex]);
 }
@@ -911,8 +946,12 @@ static Bool sna_pm_event(int scrnIndex, pmEvent event, Bool undo)
 	return TRUE;
 }
 
-void sna_init_scrn(ScrnInfoPtr scrn)
+void sna_init_scrn(ScrnInfoPtr scrn, int entity_num)
 {
+	EntityInfoPtr entity;
+
+	sna_device_key = xf86AllocateEntityPrivateIndex();
+
 	scrn->PreInit = sna_pre_init;
 	scrn->ScreenInit = sna_screen_init;
 	scrn->SwitchMode = sna_switch_mode;
@@ -922,4 +961,12 @@ void sna_init_scrn(ScrnInfoPtr scrn)
 	scrn->FreeScreen = sna_free_screen;
 	scrn->ValidMode = sna_valid_mode;
 	scrn->PMEvent = sna_pm_event;
+
+	xf86SetEntitySharable(scrn->entityList[0]);
+
+	entity = xf86GetEntityInfo(entity_num);
+	xf86SetEntityInstanceForScreen(scrn,
+				       entity->index,
+				       xf86GetNumEntityInstances(entity->index)-1);
+	free(entity);
 }
diff --git a/src/sna/sna_module.h b/src/sna/sna_module.h
index 9b14acc..97d5dd5 100644
--- a/src/sna/sna_module.h
+++ b/src/sna/sna_module.h
@@ -1,3 +1,3 @@
 const OptionInfoRec *sna_available_options(int chipid, int busid);
-void sna_init_scrn(ScrnInfoPtr scrn);
+void sna_init_scrn(ScrnInfoPtr scrn, int entity_num);
 
commit ad5ead8257b7dda84a886461873d87831d43e663
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 7 11:06:52 2011 +0100

    sna/gen2: Support covered xrgb sources on 830/845
    
    830/845 cannot directly sample from an x8r8g8b8 source, but if we know
    that we are only sampling from within the confines of the source then we
    force the alpha channel to one. (Outside of the source we require the
    sampler to return a==0.)
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 0eabf40..368e910 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -157,42 +157,29 @@ gen2_get_card_format(struct sna *sna, uint32_t format)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) {
+	for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++)
 		if (i8xx_tex_formats[i].fmt == format)
 			return i8xx_tex_formats[i].card_fmt;
-	}
 
-	if (!(IS_I830(sna) || IS_845G(sna))) {
-		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) {
+	if (IS_I830(sna) || IS_845G(sna)) {
+		/* Whilst these are not directly supported on 830/845,
+		 * we only enable them when we can implicitly convert
+		 * them to a supported variant through the texture
+		 * combiners.
+		 */
+		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++)
+			if (i85x_tex_formats[i].fmt == format)
+				return i8xx_tex_formats[1+i].card_fmt;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++)
 			if (i85x_tex_formats[i].fmt == format)
 				return i85x_tex_formats[i].card_fmt;
-		}
 	}
 
 	assert(0);
 	return 0;
 }
 
-static Bool
-gen2_check_card_format(struct sna *sna, uint32_t format)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) {
-		if (i8xx_tex_formats[i].fmt == format)
-			return TRUE;
-	}
-
-	if (!(IS_I830(sna) || IS_845G(sna))) {
-		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) {
-			if (i85x_tex_formats[i].fmt == format)
-				return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
 static uint32_t
 gen2_sampler_tiling_bits(uint32_t tiling)
 {
@@ -275,17 +262,17 @@ gen2_emit_texture(struct sna *sna,
 		assert(0);
 	case PictFilterNearest:
 		filter = (FILTER_NEAREST << TM0S3_MAG_FILTER_SHIFT |
-			  FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT);
+			  FILTER_NEAREST << TM0S3_MIN_FILTER_SHIFT |
+			  MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT);
 		break;
 	case PictFilterBilinear:
 		filter = (FILTER_LINEAR << TM0S3_MAG_FILTER_SHIFT |
-			  FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT);
+			  FILTER_LINEAR << TM0S3_MIN_FILTER_SHIFT |
+			  MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT);
 		break;
 	}
-	filter |= MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT;
 
-	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
-		  LOAD_TEXTURE_MAP(unit) | 4);
+	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 | LOAD_TEXTURE_MAP(unit) | 4);
 	OUT_BATCH(kgem_add_reloc(&sna->kgem, sna->kgem.nbatch,
 				 channel->bo,
 				 I915_GEM_DOMAIN_SAMPLER << 16,
@@ -365,7 +352,10 @@ gen2_get_blend_factors(const struct sna_composite_op *op,
 			cblend |= TB0C_ARG1_SEL_TEXEL0;
 		else
 			cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT;	/* 0.0 */
-		ablend |= TB0A_ARG1_SEL_TEXEL0;
+		if (op->src.is_opaque)
+			ablend |= TB0A_ARG1_SEL_ONE;
+		else
+			ablend |= TB0A_ARG1_SEL_TEXEL0;
 	}
 
 	if (op->mask.bo) {
@@ -506,7 +496,6 @@ static void gen2_emit_invariant(struct sna *sna)
 		  TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
 		  TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
 
-	/* copy from mesa */
 	OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD |
 		  DISABLE_INDPT_ALPHA_BLEND |
 		  ENABLE_ALPHA_BLENDFUNC | ABLENDFUNC_ADD);
@@ -552,7 +541,6 @@ static void gen2_emit_invariant(struct sna *sna)
 		  ENABLE_STENCIL_REF_VALUE | STENCIL_REF_VALUE(0));
 
 	OUT_BATCH(_3DSTATE_MODES_5_CMD |
-		  FLUSH_TEXTURE_CACHE |
 		  ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF |
 		  ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */
 		  ENABLE_FIXED_POINT_WIDTH | FIXED_POINT_WIDTH(1));
@@ -676,23 +664,12 @@ static void gen2_emit_composite_state(struct sna *sna,
 				      op->dst.format) |
 		  S8_ENABLE_COLOR_BUFFER_WRITE);
 
-	OUT_BATCH(_3DSTATE_INDPT_ALPHA_BLEND_CMD | DISABLE_INDPT_ALPHA_BLEND);
-
 	gen2_get_blend_factors(op, &cblend, &ablend);
 	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_2 |
 		  LOAD_TEXTURE_BLEND_STAGE(0) | 1);
 	OUT_BATCH(cblend);
 	OUT_BATCH(ablend);
 
-	OUT_BATCH(_3DSTATE_ENABLES_1_CMD | DISABLE_LOGIC_OP |
-		  DISABLE_STENCIL_TEST | DISABLE_DEPTH_BIAS |
-		  DISABLE_SPEC_ADD | DISABLE_FOG | DISABLE_ALPHA_TEST |
-		  ENABLE_COLOR_BLEND | DISABLE_DEPTH_TEST);
-	/* We have to explicitly say we don't want write disabled */
-	OUT_BATCH(_3DSTATE_ENABLES_2_CMD | ENABLE_COLOR_MASK |
-		  DISABLE_STENCIL_WRITE | ENABLE_TEX_CACHE |
-		  DISABLE_DITHER | ENABLE_COLOR_WRITE | DISABLE_DEPTH_WRITE);
-
 	texcoordfmt = 0;
 	if (op->src.is_affine)
 		texcoordfmt |= TEXCOORDFMT_2D << 0;
@@ -792,9 +769,7 @@ static void gen2_magic_ca_pass(struct sna *sna,
 
 	OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(8) | 0);
 	OUT_BATCH(S8_ENABLE_COLOR_BLEND | S8_BLENDFUNC_ADD |
-		  gen2_get_blend_cntl(PictOpAdd,
-				      op->has_component_alpha,
-				      op->dst.format) |
+		  gen2_get_blend_cntl(PictOpAdd, TRUE, op->dst.format) |
 		  S8_ENABLE_COLOR_BUFFER_WRITE);
 
 	gen2_get_blend_factors(op, &cblend, &ablend);
@@ -939,6 +914,76 @@ gen2_composite_solid_init(struct sna *sna,
 	return channel->bo != NULL;
 }
 
+static Bool source_is_covered(PicturePtr picture,
+			      int x, int y,
+			      int width, int height)
+{
+	int x1, y1, x2, y2;
+
+	if (picture->repeat && picture->repeatType != RepeatNone)
+		return TRUE;
+
+	if (picture->pDrawable == NULL)
+		return FALSE;
+
+	if (picture->transform) {
+		pixman_box16_t sample;
+
+		sample.x1 = x;
+		sample.y1 = y;
+		sample.x2 = x + width;
+		sample.y2 = y + height;
+
+		pixman_transform_bounds(picture->transform, &sample);
+
+		x1 = sample.x1;
+		x2 = sample.x2;
+		y1 = sample.y1;
+		y2 = sample.y2;
+	} else {
+		x1 = x;
+		y1 = y;
+		x2 = x + width;
+		y2 = y + height;
+	}
+
+	return
+		x1 >= 0 && y1 >= 0 &&
+		x2 <= picture->pDrawable->width &&
+		y2 <= picture->pDrawable->height;
+}
+
+static Bool
+gen2_check_card_format(struct sna *sna,
+		       PicturePtr picture,
+		       struct sna_composite_channel *channel,
+		       int x, int y, int w, int h)
+{
+	uint32_t format = picture->format;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(i8xx_tex_formats); i++) {
+		if (i8xx_tex_formats[i].fmt == format)
+			return TRUE;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) {
+		if (i85x_tex_formats[i].fmt == format) {
+			if (!(IS_I830(sna) || IS_845G(sna)))
+				return TRUE;
+
+			if ( source_is_covered(picture, x, y, w,h)) {
+				channel->is_opaque = true;
+				return TRUE;
+			}
+
+			return FALSE;
+		}
+	}
+
+	return FALSE;
+}
+
 static int
 gen2_composite_picture(struct sna *sna,
 		       PicturePtr picture,
@@ -992,7 +1037,7 @@ gen2_composite_picture(struct sna *sna,
 	} else
 		channel->transform = picture->transform;
 
-	if (!gen2_check_card_format(sna, picture->format))
+	if (!gen2_check_card_format(sna, picture, channel, x,  y, w ,h))
 		return sna_render_picture_convert(sna, picture, channel, pixmap,
 						  x, y, w, h, dst_x, dst_y);
 


More information about the xorg-commit mailing list