2011年5月23日月曜日

ETC1圧縮方法その2

アルゴリズムでどうにかする方法が思い浮かばないので、
小手先でなんとかしてみる。

とりあえず、テーブルのインデックス計算で
RGB各値で別に誤差計算するのではなく、
あらかじめ計算した輝度値だけで行う。
元々のフォーマットが輝度値の誤差をベースカラーに
載せる形式だから、それほど悪くない解だと思う。

浮動小数点数を固定小数点数に直す。
小手先の極みである、計算時間はどうやっても線形にしか減らない。
浮動小数点なら、汚いが見れる範囲だなと思うアルゴリズムでも、
かなり汚くなる。そこまで汚くなるほど精度が足りていないとは思えないので
どこか間違っている。

もう少し思考錯誤の必要がある。
満足いく速度と品質は得られそうにないので、
ユーザが設定するオプションという扱いになりそうだ。
それはプログラマの敗北宣言。

2011年5月20日金曜日

Ericsson Texture Compressionへの圧縮方法

ETC1のフォーマット概要と圧縮法について。

問題は、ETC1へ圧縮するにあたり計算時間が許容できないので、
速い計算方法はないものかというもの。

詳細は、Open GL ES の拡張OES_compressed_ETC1_RGB8_textureの仕様に説明されている。
RGB 24bitの4x4ピクセルを、64ビットに圧縮する。
4x4を、2x4又は4x2のサブブロックに分割し、
サブブロック2つ分のベースカラーにRGB 8bit、
サブブロックそれぞれに差分テーブルのインデックス 3bit、
16ピクセルそれぞれに2bitの、差分テーブルの要素を示すビット 2bit、
残りは、サブブロックの割り方に1bit、ベースカラーの表現方法に1bit、
となる。
base color = 8x3 = 24bit
color table = 3bit x 2 = 6bit
bits for color table = 2bit x 16 = 32 bit
mode flags = 2bit

解凍する場合、計算イメージとしては以下のようになる。
ピクセルの色 = ベースカラー + 差分テーブル[ 2ビットインデックス ]

どう圧縮するかが悩むところ。
差分テーブルは以下左から、テーブル番号、2bit値で11、10、00、01、
0 -8 -2 2 8
1 -17 -5 5 17
2 -29 -9 9 29
3 -42 -13 13 42
4 -60 -18 18 60
5 -80 -24 24 80
6 -106 -33 33 106
7 -183 -47 47 183

テーブル値をどう算出したか妄想すると、統計ではないかと。
計算すべきものは以下の3つ。
・各サブブロックのベースカラーの計算
・ベースカラーに対して、テーブルの決定
・テーブルとベースカラーに対して、2ビットインデックスの計算

発見的手法しかないのかこれは。

2011年5月9日月曜日

VBOの修正と頂点の転送

毎フレーム頂点を書き換える必要があるとして、
Vertex Buffer Object(VBO)の書き換えと、
毎フレーム頂点バッファを転送して描画するのはどちらが速いか。
データによりけりではある。

ここからは妄想。
----
VBOの書き換えを行った場合、
描画前にglFlushで書き換えを反映する必要があるGPUと、
そうでないGPUがある。Windows上のエミュレータは後者。
前者は描画時にバッファの書き込みを待たず、
後者は終わるまで待つ。

glFlushを呼ばない場合、
表示からするとバッファが壊れている。
このことから、VBOの書き換え時に
別のバッファを用意している。
仕様上はglFinishでなければ解決できない。
glFlushで上手くいっているように見えるのは、
単にglFlushに時間がかかって転送が完了しているだけなのか。
----
ここまで妄想。

glFlushを毎フレーム呼べば解決する。
しかし、重量級のglFlushは使いたくない、VBOの書き換えもしたい。
VBOのダブルバッファリングを行い、glFlushを呼ばない実装を試してみたところ、
一見上手く動作しているように見える。
swapBuffers等どこかのタイミングで、
そのフレームのコマンドが全て終了するのを待っている(glFinish)
と考えてよいものか。そうであるはずなのだが、自信を持てない。

Adreno SDKとAdreno Profiler

Radeon HD 5770 Windows XP上で、
PowerVR SDKのOpengl ES2エミュレータが動かなくなった。
Windows 7では元から動かない。
というのが以前の話。

代わりにAdreno SDKとProfilerを導入。
Adrenoでの開発はこちらの方がよいか、快適である。
AdrenoがATI Z430だっただけあり、Radeonとの相性がよいらしい。
ドキュメントもRadeon対応状況の記載に比べて、
Geforceは2,3個動作するのは確認したという感じになっている。

次はTegra2かと思うが、Radeonと相性悪そうだな。動くのかな。
Tegra2の性能が頭ひとつ出ているのだから早急にすることでもない。

PowerVRとeglChooseConfig

Galaxy Sでおきたこと。
eglChooseConfigで返ってきたconfigをそのまま使用すると,
eglCreateWindowSurfaceで、BAD_MATCHとなりこける。

問題解決のために検索していると、Motrola Droidでも
似た現象が起きているらしい。

PowerVR系は返ってきたconfigの中から、
depthとstencilが要求以上で、
RGBAが要求とマッチするものを選ぶ必要があるのではないか。
Adreno 200とTegra 250では起きていない。

eglChooseConfigの仕様ってそういうものでした?
要求を満たして使用可能なconfigを返すのではないのか。

Googleのサンプルにあるようにすればよい。