E7221 (on SC420) で OpenGL を使いたい(FC6)

E7221 のグラフィックスコアは i915 と同等なんですが,Fedora core 6 の環境で compiz / beryl がうまく使えません。で,あれこれやってたら一応でけました。

今時の Linux で compiz / beryl を使うためには,

  • AIGLX が有効(もしくは NVIDIA の場合 GLX)である必要があり
  • Direct Rendering (DRI) が有効である必要があり
  • DRM が有効である必要があり

ます。より下のものほど上のための必要条件となってます(ほんとはもっと細かい条件があるんですが,忘れました)。

E7221 で AIGLX がうまく使えない理由はいくつかあって

  1. agpgart が E7221 をうまく認識しない
  2. kernel drm module (i915) が E7221 をうまく認識しない
  3. mesa が E7221 を中途半端にしか認識しない

というのが原因ぽかったんで,それぞれ無理矢理 E7221 を i915 のフリをさせることにしました。

以下,パッチが続きます。

まず,agpgart へのパッチ。

--- drivers/char/agp/intel-agp.c.orig	2007-06-18 16:19:00.847772353 +0900
+++ drivers/char/agp/intel-agp.c	2007-06-18 16:40:30.753965599 +0900
@@ -9,6 +9,8 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+#define PCI_DEVICE_ID_INTEL_7221_HB         0x2588
+#define PCI_DEVICE_ID_INTEL_7221_IG         0x258a
 #define PCI_DEVICE_ID_INTEL_82946GZ_HB      0x2970
 #define PCI_DEVICE_ID_INTEL_82946GZ_IG      0x2972
 #define PCI_DEVICE_ID_INTEL_82965G_1_HB     0x2980
@@ -477,6 +479,7 @@
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_7221_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965 )
 				gtt_entries = MB(48) - KB(size);
@@ -487,6 +490,7 @@
 			/* Check it's really I915G */
 			if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
+			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_7221_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
 			    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || IS_I965)
 				gtt_entries = MB(64) - KB(size);
@@ -1824,6 +1828,13 @@
 			bridge->driver = &intel_845_driver;
 		name = "915GM";
 		break;
+	case PCI_DEVICE_ID_INTEL_7221_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_7221_IG))
+			bridge->driver = &intel_915_driver;
+		else
+			bridge->driver = &intel_845_driver;
+		name = "E7221";
+		break;
 	case PCI_DEVICE_ID_INTEL_82945G_HB:
 		if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG))
 			bridge->driver = &intel_915_driver;
@@ -2019,6 +2030,7 @@
 	ID(PCI_DEVICE_ID_INTEL_7205_0),
 	ID(PCI_DEVICE_ID_INTEL_82915G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
+	ID(PCI_DEVICE_ID_INTEL_7221_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 	ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
 	ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),

次に,i915 drm module へのパッチ

--- drivers/char/drm/drm_pciids.h.orig	2007-02-05 03:44:54.000000000 +0900
+++ drivers/char/drm/drm_pciids.h	2007-06-19 11:53:20.594836904 +0900
@@ -294,5 +294,6 @@
 	{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x8086, 0x258a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0, 0, 0}
 

ここまでで DRI が有効になります(Xorg.*.log で「direct rendering: Enabled」となる)が,glxinfo で見ると,DRI はやはり無効のままです。これは mesa GL library が E7221 の場合に GL context を初期化してくれないためです。

なので,mesa へのパッチ

--- src/mesa/drivers/dri/i915/intel_context.h.orig	2006-08-19 02:04:03.000000000 +0900
+++ src/mesa/drivers/dri/i915/intel_context.h	2007-06-19 13:54:34.924249539 +0900
@@ -440,6 +440,7 @@
 #define PCI_CHIP_I915_GM		0x2592
 #define PCI_CHIP_I945_G			0x2772
 #define PCI_CHIP_I945_GM		0x27A2
+#define PCI_CHIP_E7221_G		0x258A
 
 
 /* ================================================================
--- src/mesa/drivers/dri/i915/intel_context.c.orig	2006-09-12 06:35:49.000000000 +0900
+++ src/mesa/drivers/dri/i915/intel_context.c	2007-06-19 13:51:45.320199680 +0900
@@ -122,6 +122,8 @@
 	 chipset = "Intel(R) 945G"; break;
       case PCI_CHIP_I945_GM:
 	 chipset = "Intel(R) 945GM"; break;
+      case PCI_CHIP_E7221_G:
+	 chipset = "Intel(R) E7221"; break;
       default:
 	 chipset = "Unknown Intel Chipset"; break;
       }
--- src/mesa/drivers/dri/i915/intel_screen.c.orig	2006-09-12 06:35:49.000000000 +0900
+++ src/mesa/drivers/dri/i915/intel_screen.c	2007-06-19 13:50:20.011624242 +0900
@@ -514,6 +514,7 @@
    case PCI_CHIP_I915_GM:
    case PCI_CHIP_I945_G:
    case PCI_CHIP_I945_GM:
+   case PCI_CHIP_E7221_G:
       return i915CreateContext( mesaVis, driContextPriv, 
 			       sharedContextPrivate );
  

これで作成される /usr/lib/dri/i915_dri.so を置き換えれば OK になります。Fedora の場合,mesa-libGL というパッケージになります。

これらのパッチを適用して,適切な xorg.conf を書けば,E7221 でも無事 compiz / beryl が立ち上がります……が,さすがに NVIDIA とかに比べるとちと重いですね。

あと,なぜか,画面下64ドット目くらいから16ピクセルくらいの幅で表示がおかしくなってしまう……たぶん agpgart まわりでもうちょっときちんとしないといけないんだと思うんですが,正しい対策方法をご存知の方がいらっしゃったら御教示ください。

自分用メモ

カーネルパッケージのビルドは「--with baseonly」をつけないと,PAE だの Xen だののためのカーネルもビルドするのでめちゃめちゃ時間がかかる。

% rpmbuild -ba --target=i686 --with baseonly SPECS/kernel-2.6.spec