「 Intelチップセット 」一覧

GL_INTEL_map_texture 拡張


久々にIntelがOpenGL拡張を出していました。
それは、GL_INTEL_map_texture というもので、内容を読むと
GPUが読んでいるメモリ領域を直接CPUからアクセス可能にする拡張のようです。

確かに最近のIntel CPUはGPU統合してしまっており、グラフィックスメモリはすなわちメインメモリなわけで、CPUから直接扱うことが出来るようになっても自然です。
VRAMのように振る舞って一度メインメモリにコピーとか無駄なことをしなくてすむわけです。

増える関数はこんな感じです。

おおよそ通常のglMapBuffer/UnmapBufferと同じようですが、CPU/GPUでメモリ同期を取るためのSync関数も用意があるみたいです。

仕様: http://www.opengl.org/registry/specs/INTEL/map_texture.txt


IntelグラボとOpenGLの苦悩 その3


前回、Intelでは問題がなかった、という表現をしていましたが、
実はテクスチャ座標も正しくシェーダー側へ渡せてないことが分かりました。
うまく値が渡るのは頂点カラーのみ。これらの結果から、
GL_ARB_vertex_program の各頂点属性のインデックス値が、
仕様通りに動くのは NVIDIAのみということになります。

vertex_programを使用時においてどの環境でも動くためには、
EnableVertexAttribArray系ではなく、glEnableClientStatus系で有効にして、
頂点データ属性のセットには、glXXXXPointer系を使う必要があるということになります。

このvertex_programやfragment_programのシェーダーについて、
GLARBシェーダーとここでは表記することにします。

FBO未使用でのテクスチャレンダリング

GL_ARB_framebuffer_objectを使えない時のテクスチャレンダリングの話です。
使用しそうな場面としては、以下のような状況があるかと思います。

  • GLSL使えないとき(GLver2.0未満)の場合
  • ドライバが対応していないものを使用している場合

意外と古いドライバでは FBOが使えなかったりします。
それと古い環境で、DirectX9.0とGLの対応を行う場合に、
OpenGLでテクスチャレンダリングする場合にこの方法が必要になるかと思います。

これから説明する方法はパフォーマンスがあまりよくはありません。
しかしながら、制限された環境で、両者互換を取る場合には仕方ないかなと思っています。

wglCreatePbufferARBでPBufferを使う

OpenGLのP-Bufferというものを使います。
これはオフスクリーン描画のためのバッファです。
ただし、この拡張はプラットフォーム依存が酷く、マルチ展開は厳しいです。
また、FBOに比べて使い勝手が悪いです。

P-Bufferを用いて描画の方法はサンプルもそこそこあるので、
ここでは手順だけ説明します。

  1. P-Bufferを作成
    1. メインのGLコンテキストとリソース共有出来るようにwglShareListsを呼び出しておきます。
  2. テクスチャに書き込みたいシーンをP-Bufferを現在のコンテキストに設定して描画
  3. glCopyTexSubImage2Dを呼び出して、描画したシーンをテクスチャに転送
  4. P-Bufferでのコンテキストの各値をメインにコピー
    • 必要がないなら不要。wglCopyContextでコピーできる
    • コピーしておくとテクスチャレンダリングパスでのクリア値とかを引き継げる
    • コピー有無にかかわらず、頂点属性のセット値は引き継がれない。
  5. メインのコンテキストに戻す。
    1. ビューポートやシザーの再セット

これらの手順により、描画結果をテクスチャに落とし込めます。
glReadPixels命令でも一応可能ですが、それよりはこちらの方が若干マシです。

まとめ

OpenGL 2.0対応していて、FBOが使える状況ではまず必要にならない方法でした。
最近だと2.0あたりに対応はしているはずなので、あまり役に立たないかも。

P-Bufferなんて昔の話と思っていたので、まさか実際に触ってみる日が来るとはびっくりです。
Intel GMA950あたりで動かそうと思ったが運の尽きってことで。

勉強にはなったと思いますが…。


IntelグラボとOpenGLの苦悩 その2


シェーダーを使う状況かつVertexBufferObject(VBO)を使ってということを前提条件とします。
このとき、glEnableVertexAttribArray, glVertexAttribPointer等を使って、
頂点ストリームを設定していくのが自然です。しかしながら今回、これでトラブルに見舞われました。

GL_ARB_vertex_program の仕様をOpenGL Registryで調べると、
各頂点属性のindex値は、頂点データのセマンティクスにより決まるように書いてあります。
今までは、この値を参考にしながら glEnableVertexAttribArray( index ); を設定していました。

そのようにして実装した結果、NVIDIA, Intel のグラフィックチップによる描画では
問題が起こらなかったのですが、AMD(ATI)のチップでは、位置情報以外設定されない!という動作結果が出てしまいました。

もともとはIntelの場合を想定して、この作業を行っていたのに、
意外にもAMDでまともに動作しないという状況ではちょっと不味い…。

GLSLを使える状況、すなわち、GL_ARB_vertex_shaderの拡張でシェーダーを使う分には、
従来方式で問題はおこりません。今回~programのほうなので問題があるわけです。
この~programは、いわゆるシェーダーアセンブラへOpenGLが対応したときの拡張です。

おおまかな出現順から考えると、

  1. GL_ARB_vertex_program, fragment_program
  2. GL_ARB_vertex_buffer_object
  3. GL_ARB_vertex_shader

という順序なので、VBOとの同時使用で問題が引き起こされている感もありそうです。

  • VBOを使用せずに、頂点データを直接VertexAttribPointerで設定した
    • NG. 動作せず。
  • VBO使用して、glVertexPointer等でオフセットを指定した
    • OK. AMDで動作した。

こんな結果になりました。
もう古いAPIである glVertexPonterやglColorPointer等で、VBO内のオフセットを設定してあげることにより、
シェーダーアセンブラ使用時でも、頂点属性をシェーダー側へ流し込むことが出来ました。

※ なるべくならこんな古いAPIを使いたくはなかったんですが…。


IntelグラボとOpenGLの苦悩


久しぶりにOpenGLのコードを書いて実験していました。
今回気になってと色々と試していたのは、テクスチャへのレンダリングについてです。

背景

比較的新しい環境で、NVIDIA/AMDなどのグラフィックチップを使っている物については、FBO(FramebufferObject)の使用で簡単に対応可能です。
しかしたまにFBOを使えない環境という状況についてどうしようということがあります。

FBOはOpenGLの3系で初めてコアに取り込まれていたので、
OpenGL 2.1対応のビデオボードというだけでは、使えない可能性もあります。
(拡張でつかえることも当然ある。ドライバの完成度次第です)

今までは、「そんな環境は知らない。」としていたのですが、

  • 意外にも旧Intel Coreシリーズの内蔵グラフィックチップがOpenGL 2.1止まりである
  • Intelのグラフィックチップではかなりの世代がOpenGL対応バージョンが低いままである

という点から、このまま放置はダメだと思い、ちょっと調べてみることにしました。

調査

出典は英語のほうのWikiPediaより。

チップ OpenGL対応具合 備考
GMA 900 1.4
GMA 950 1.4
GMA 3100 1.5
GMA 3150 1.5
GMA X3500 2.0 G35のもの
GMA X4500 2.1 G4xあたり
HD Graphics 2.1 旧Intel Core iシリーズ.
HD Graphics 2000 3.0 新Core iシリーズ
HD Graphics 3000 3.0 新Core iシリーズ

ざっと、このような状況でした。
まだまだGMA3000番代を使っている環境も多いと思うので、
ここの対応を切ってしまうのはやはり不味そうです。

手元にGMA950のノートPCがあるので、これを実験対象として用いてみたいと思います。

実験中

今の世代を考慮して、シェーダーの使用は前提とします。
その場合に必要となる関数として以下のものを読み込んだのですが、エラーに。

  • glVertexAttribPointer
  • glEnableVertexAttribArray
  • glDisableVertexAttribArray

色々と調べてみると、末尾に”ARB”が付いているものを使用しなくてはならないようです。
この末尾になにもないタイプは、OpenGL 2.0でのコア関数に位置づけされるものっぽいです。

これらのことを考えると、2.0未満の場合では末尾にARBが付いている物を使い、
それ以外の場合には、何も付いていないものを使用するべきのように思います。

さて、そのようにして作業を進めていくと驚くべき事実が発覚。
GMA950のOpenGL 1.4の環境では、GLSLが使用不可能でした…
あれ?と思って調べてみると、GLSLではなくARBのシェーダーが使えるようです。
DirectXでもHLSLの前はシェーダーアセンブラでしたし、これと同じ状況です。

結果、この環境でシェーダーが動くためには、GLSLではなくアセンブラ形式のシェーダーを使う必要があるということでした。

シェーダー使用の前提を保ちつつ、レンダーテクスチャ(のようなもの)をサポートするには、
かなり厳しい道のりがありそうです。

とりあえず、HLSLで書いたコードをNVIDIAが提供しているCg Toolkitを用いて、
OpenGL ARB用のシェーダーアセンブラを出力することが可能です。
ここではこの助けを借りて、もうちょっとがんばってみようと思います。