D3D Shader/OpenGL」カテゴリーアーカイブ

Blender 2.6 の Export plug-in を作る (2) データアクセス

Blender の API は bpy で始まり、データアクセス手段は
bpy.data 以下に集約されています。

例えばシーン内のオブジェクトは bpy.data.objects で取れます。
下記のように Python Console で確認できます。
(太字がキー入力です)

>>> bpy.data.objects['Cube']
bpy.data.objects['Cube']

>>> bpy.data.objects.keys()
['Camera', 'Cube', 'Lamp']

>>> bpy.data.objects.values()
[bpy.data.objects['Camera'], bpy.data.objects['Cube'], bpy.dta.objects['Lamp']]

↑Python の辞書(連想配列)のように見えますがちょっと違います。

>>> bpy.data.objects


>>> bpy.data.objects[0]
bpy.data.objects['Camera']

>>> bpy.data.objects.find('Cube')
1

>>> bpy.data.objects[1:]
[bpy.data.objects['Cube'], bpy.dta.objects['Lamp']]

↑数値 index でもアクセス可能で要素の順番が固定。
find() を使うと index を取ることが可能です。
特に for in では要素が列挙され、配列のような振る舞いをします。

>>> for a in bpy.data.objects: print( a )



key を持つがシーケンスとして扱える特殊な collection となっています。
python に慣れてないせいもありますが、
辞書のつもりで script を読んでいると少々混乱します。

● Object Type

Object の種類は type プロパティで確認できます。

>>> for a in bpy.data.objects: print( a.type )
CAMERA
MESH
LAMP

bpy.types にデータの種類一覧があります。

Types (bpy.types)

この bpy.types が Maya でいう Node に相当するもののようです。
例えば ‘Cube’ は bpy.types.Mesh で、独自のインスタンスととデータは
Object.data からアクセスします。

>>> bpy.data.objects['Cube'].data.vertices[1].co
Vector((1.0, -1.0, -1.0))

Object 自体が階層構造を持てるので DagNode を兼ねています。
Maya ではインスタンスである Object とメソッドでである Function が
分離していましたが、Blender はそのようなことがなくシンプルです。

Object の階層は下記のようにたどることができます。
Maya のように Transform Node が別だったりしません。

def tree( obj ):
  print( obj )
  print( obj.matrix_local )
  for child in obj.children:
    tree( child )

def root():
  for obj in bpy.data.objects:
    if not obj.parent:
      tree( obj )

root()

root の object だけ得るには
[obj for obj in bpy.data.objects if not obj.parent]
で出来ます。

bpy.data.objects はすべてのオブジェクトを列挙しますが、
同時に data type ごとの collection も持っているようです。

>>> bpy.data.objects.keys()
['Camera', 'Cube', 'Lamp', 'Sphere', 'Suzanne']

>>> bpy.data.meshes.keys()
['Cube', 'Sphere', 'Suzanne']

bpy.data.meshes に入っているのはデータそのもの、Object.data です。
こちらは階層などの Node 情報を含んでいません。

>>> bpy.data.meshes['Cube'].vertices[1].co
Vector((1.0, -1.0, -1.0))

Object を削除しても Mesh は残っているようです。
この辺の Blender の内部挙動はまだ私の方がきちんと理解しておりません。

matrix_local はドキュメント Object(ID) では float array
と書かれてますが mathutils.Matrix を返すようです。

● Mesh のアクセス方法

Mesh には形状データが入っています。
頂点データ自体は Mesh.vertices ですが、下記ページの解説にあるように
edge, loop, polygon と 3種類のインデックスがあります。

Mesh(ID)

・MeshVertex : 頂点データそのもの
・MeshEdge : 2頂点の index
・MeshLoop : 1頂点 + edge の index
・MeshPolygon : n個の loop の index

mesh= Suzanne




mesh= Cube




mesh= Sphere




Mesh 内の MeshPolygon (Face) の列挙は下記の通り。

def shape( obj ):
  mesh= obj.data
  for poly in mesh.polygons:
    print( poly )

MeshPolygon に含まれる頂点 (Face Vertex) を得るには下記の通り。

# Loop を使った場合
def shape( obj ):
  mesh= obj.data
  for poly in mesh.polygons:
    for id in range( poly.loop_start, poly.loop_start + poly.loop_total ):
      print( mesh.verticies[ mesh.loops[ id ].vertex_index ].co )

MeshPolygon に含まれる MeshLoop をたどって MeshLoop.vertex_index を
参照しています。
なお、Loop を使わなくても MeshPolygon.vertices で直接頂点 index を
取れることがわかりました。

def shape( obj ):
  mesh= obj.data
  for poly in mesh.polygons:
    for ver in poly.vertices:
      print( mesh.vertices[ ver ].co )

ただし、mesh.loops の参照用 index 値 (「Loop を使った場合」の id ) は
uv など他のデータアクセスにも使います。
loop は Face Vertex 単位のデータとなり、Cube の場合 24 個あります。
一見複雑ですが「Loop を使った場合」の方が都合が良いようです。

● 法線

頂点データ MeshVertex に直接頂点法線が格納されています。
頂点座標が共有される場合法線も共有されており、この値は
ハードエッジになりません。

頂点とは別に MeshPolygon に面法線が格納されており、プロパティ
Mesh.use_smooth の値によってこの両者を使い分ける必要があるようです。

● UV / 頂点カラー

Mesh.uv_layers に格納されます。値そのものは MeshUVLoop.uv です。
uv_layers が MeshUVLoopLayer で data に MeshUVLoop が頂点分 (Loop 数分)
格納されます。

>>> len(bpy.data.objects['Cube'].data.uv_layers)
1

>>> len(bpy.data.objects['Cube'].data.uv_layers[0].data)
24

>>> bpy.data.objects['Cube'].data.uv_layers[0].data[0].uv
Vector((0.0), 0.0))

>>> bpy.data.objects['Cube'].data.uv_layers.active.data[0].uv
Vector((0.0), 0.0))

頂点カラーも全く同じで Mesh.vertex_colors に入ります。
今までの情報を取り出すコードがこれです。

def shape( obj ):
  print( 'mesh=', obj.name )
  mesh= obj.data
  uv_array= mesh.uv_layers.active.data if len(mesh.uv_layers) else None
  vcolor_array= mesh.vertex_colors.active.data if len(mesh.vertex_colors) else None
  for poly in mesh.polygons:
    for id in range( poly.loop_start, poly.loop_start + poly.loop_total ):
      vertex= mesh.vertices[ mesh.loops[ id ].vertex_index ]
      position= vertex.co
      normal= vertex.normal
      if not poly.use_smooth:
        normal= poly.normal
      print( 'pos=', position )
      print( 'normal=', normal )
      if uv_array:
        uv= uv_array[id].uv
        print( 'uv=', uv )
      if vcolor_array:
        vcolor= vcolor_array[id].color
        print( 'vcolor=', vcolor )


def tree( obj ):
  if obj.type == 'MESH':
      shape( obj )
  #print( 'matrix=', obj.matrix_local )
  for child in obj.children:
    tree( child )

def root():
  for obj in bpy.data.objects:
    if not obj.parent:
      tree( obj )

root()

それぞれ最初の(active な) UV set と VertexColor しか参照していないので注意してください。
uv_array, vcolor_array の参照に Loop と同じ id を使っていることがわかります。
Matrix 同様、ドキュメントではただの array ですが実際に返す値は
mathutils.Vector, mathutils.Color となっています。

続きます

関連エントリ
Blender 2.6 の Export plug-in を作る (1)

Blender 2.6 の Export plug-in を作る (1)

Blender を使った経験が全く無いので練習兼ねてプラグイン作ります。

Blender

Blender 2.65 を install 。
Script は python 3.3 で、plug-in (addon) もこれで記述するようです。

Scripts Development

本体に DirectX .x や fbx など多くの exporter addon が含まれているので、これらのスクリプトが参考になります。

Windows だとこの辺に入っています。
C:\Program Files\Blender Foundation\Blender\2.65\scripts\addons

●Python Console

Blender 上の 3D View など、Window を Python Console に切り替えられます。
直接コマンドを実行して動作確認ができるので便利です。

●スクリプトの置き場所

addon として作成した script は下記の場所に入れておきます。

◎ Windows 7/8

 C:\Users\<ユーザー名>\AppData\Roaming\Blender Foundation\Blender\2.65\scripts\addons

◎ MacOS X

 /Users/<ユーザー名>/Library/Application Support/Blender/2.65/scripts/addons

Add-Ons
Configuration & Data Paths

上記場所に入れたスクリプトでは最低限 bl_info の定義が必要です。
User Preferences の Addons を開くときに、フォルダ内の python ファイルから bl_info を検索して定義内容を取り込んでいるようです。
bl_info がなかったり定義にミスがあるとエラーになります。

Script meta informations

# test.py (Preference に列挙されるための最小限)

bl_info= {
  "name": "Test",
  "category": "Import-Export",
}

print( "on load message" );

●スクリプトの読み込み&実行

Blender のメニューから addon を有効にします。

   File → User Preferences … → Addons

上記の Addon スクリプト置き場に入っていて、かつ bl_info が定義されていればここに列挙されます。
左サイドの Categories で絞り込むと見つけやすくなります。
上の test.py なら “Import-Export” に入ります。

test.py である「Import-Export: Test」のチェックボックスを On にすると script が読み込まれて走ります。
ただし上の test.py は class を定義しておらず、内容が不完全なのでエラーになります。

●エラーコンソール

addon としてロードした script の print 出力 (stdout) は、
Blender 内の Python Console には表示されません。
エラーなどのログを見るにはコンソールを開きます。

Windows の場合、メニューの “Window” から

   Window → Toggle System Console

Maya でも別ウィンドウになっているあれ (Output Window) と同じです。

MacOS X/Linux の場合上記のメニューがないのでコマンドラインから起動します。
Finder からではなく、ターミナルを開いて blender コマンドを直接実行します。

$ /Applications/Blender/blender.app/Contents/MacOS/blender

The Console Window

これで上記 test.py を読み込もうとすると “on load message” が表示されたあと
エラーが出ていることを確認できます。

●コマンドの追加と実行

addon はコマンドの class を定義してシステムに登録する必要があります。

Preferences Addons のチェックボックスの on/off で script 内の
register()/unregister() が呼び出されています。
このタイミングで class を登録を行います。

# test.py (2)
import bpy

bl_info= {
  "name": "Test",
  "category": "Import-Export",
}

class ExportTest( bpy.types.Operator ):
    bl_label= 'export test'
    bl_idname= 'export.test_a6'

    def execute( self, context ):
        print( "exec-command" )
        return {'FINISHED'}

def unregister():
    bpy.utils.register_module(__name__)

def register():
    bpy.utils.unregister_module(__name__)

定義クラスは bl_label, bl_idname が必須で、bl_idname が識別子になっています。
(2) の test.py は Preferences Addos で正しくロードできます。

Preferences Addos の “Import-Export: Test” のチェックを入れると
register() が呼び出されて bl_idname で指定したコマンド名が有効になります。

Python Console を開いて export.test_a6() が実行できることを確認できます。
(↓太字は出力結果)

>>> bpy.ops.export.test_a6()
exec-command
{'NIFISHED'}

●Export Menu に追加する

付属の scripts/addons/io_scene_fbx を参考にしました。
io_export_direct_x.py の方は ExportHelper を使わずに実装されているようです。

# io_export_test_a6.py
import bpy
from bpy_extras.io_utils import ExportHelper

bl_info= {
  "name": "Export Test a6",
  "category": "Import-Export",
}

class ExportTestA6( bpy.types.Operator, ExportHelper ):
    bl_label= 'export test a6'
    bl_idname= 'export.test_a6'
    filename_ext= '.txt' # ←必須

    def execute( self, context ):
        print( 'file=' + self.filepath )
        return  {'FINISHED'}


def menu_func(self, context):
    self.layout.operator( ExportTestA6.bl_idname, text="Export Test a6 (.txt)" )

def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.INFO_MT_file_export.remove(menu_func)

def register():
    bpy.utils.register_module(__name__)
    bpy.types.INFO_MT_file_export.append(menu_func)

register()/unregister() の中で class だけでなく menu_func も登録しています。
この menu_func() はメニューの

   File → Export

のサブメニューを開くタイミングで呼ばれるようです。
self.layout.operator() の最初の引数が実行する class id、text が Menu のラベルです。
例えば menu_func() を

def menu_func(self, context):
    self.layout.operator( "export_scene.fbx", text="Export Test a6?" )

と書き換えると File → Export →「Export Test a6?」の選択で fbx の
export を呼び出せます。

●Export 時のオプション

Export 実行時に左側のサイドバーでオプション選択ができます。
例えば選択されたオブジェクトだけ Export したり、Axis を変更したりなど。
このようなプロパティは Export class に追加しておきます。

~

class ExportTestA6( bpy.types.Operator, ExportHelper ):
    bl_label= 'export test a6'
    bl_idname= 'export.test_a6'
    filename_ext= '.txt'

    # ↓追加
    flag_selected= BoolProperty( name= "Selected Objects",
                description= "Export selected objects",
                default= False )

    def execute( self, context ):
        print( 'file=' + self.filepath )
        print( 'flag=', self.flag_selected )
        return  {'FINISHED'}

~

これで File → Export →「Export Test a6」を選択すると、
Export ファイル選択画面となり、左サイドバーから「Selected Objects」の
チェックが可能となります。

右上の「export test a6」ボタンを押すと、コンソール出力で
入力したファイル名と “Selected Objects” のチェック状態が読み取れている事がわかります。

まだ必要最小限ですが addon 登録周りの挙動がわかったので、
次は内部データのアクセスを行います。

Qualcomm APQ8064 Krait/A6 swift の浮動小数点演算能力

Qualcomm の CPU Krait の浮動小数点演算の速度を調べてみました。

                 (1)     (2)     (3)      (4)    (5)
                 iPad3  Touch5   EVO 3D  iPad4 Butterfly
                 A5X     A5      8660     A6X    8064
                 C-A9    C-A9   Scorpion Swift   Krait
--------------------------------------------------------
a:mat44 neon_AQ  4.784   5.979   2.879   1.204   1.919
b:mat44 neon_BQ  2.408   3.008   1.146   1.266   1.273
c:mat44 neon_AD  4.781   5.974   3.079   1.554   2.453
d:mat44 neon_BD  2.406   3.007   1.440   1.344   2.041
e:fadds      A   4.010   5.013   3.460   2.882   3.791
f:fmuls      A   4.010   5.012   4.361   2.953   3.671
g:fmacs      A   4.012   5.011   4.034   5.763   7.334
h:vfma.f32   A   -----   -----   -----   5.765   3.725
i:vadd.f32 D A   4.111   5.136   3.493   2.877   3.706
j:vmul.f32 D A   4.110   5.136   3.502   2.950   3.667
k:vmla.f32 D A   4.512   5.650   3.638   2.951   7.557
l:vadd.f32 Q A   8.023  10.036   3.408   2.878   3.677
m:vmul.f32 Q A   8.022  10.028   3.427   2.952   3.647
n:vmla.f32 Q A   8.025  10.028   3.400   2.955   7.362
o:vfma.f32 D A   -----   -----   -----   2.494   3.676
p:fadds      B   4.014   5.013   5.972   5.757   4.664
q:fmuls      B   5.013   6.265   5.960   5.760   4.583
r:fmacs      B   8.023  10.024   8.573  11.521   8.266
s:vfma.f32   B   -----   -----   -----  11.519   4.611
t:vadd.f32 D B   4.113   5.137   5.945   2.881   4.746
u:vmul.f32 D B   4.118   5.145   5.098   2.951   4.680
v:vmla.f32 D B   9.027  11.278   8.498   5.757   8.361
w:vadd.f32 Q B   8.021  10.023   5.950   2.879   4.702
x:vmul.f32 Q B   8.029  10.023   5.095   2.951   4.595
y:vmla.f32 Q B   9.026  11.277   8.497   5.762   8.464
z:vfma.f32 D B   -----   -----   -----   5.759   4.660
--------------------------------------------------------
↑数値は実行時間(秒) 数値が小さい方が速い


(1)=Apple iPad 3           A5X      ARM Cortex-A9 x2  1.0GHz
(2)=Apple iPod touch 5     A5       ARM Cortex-A9 x2  0.8GHz
(3)=HTC EVO 3D ISW12HT     MSM8660  Scorpion      x2  1.2GHz
(4)=Apple iPad 4           A6X      A6 (swift)    x2    ?GHz
(5)=HTC J butterfly HTL21  APQ8064  Krait         x4  1.5GHz

(1)~(4) は過去の計測値です。
SDK や OS などの条件が完全に同一ではないのと、計測方法にも
いろいろミスや勘違いが含まれてる可能性があります。
予めご了承ください。

またアプリケーションの実速度ではなく CPU 単体の能力やパイプラインを
調べるのが目的なので、オンキャッシュ前提で意味のない演算を走らせています。

● a:~d: NEON を使った Matrix 4×4 同士の乗算

A はパイプライン最適化なし、B はインターリーブしたものです。
Q=128bit(float x4), D=64bit(float x2) 命令です。
64bit の方が実行命令数が倍になります。
具体的な違いは下記の通り。

; AQ
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	q8,q0,d8[0]
    vmla.f32	q8,q1,d8[1]
    vmla.f32	q8,q2,d9[0]
    vmla.f32	q8,q3,d9[1]
    vstmia	%2!, {d16,d17}
    ~

; BQ
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	q8,q0,d8[0]
    vmul.f32	q9,q0,d10[0]
    vmul.f32	q10,q0,d12[0]
    vmul.f32	q11,q0,d14[0]
    ~

; BD
    vldmia	%0, {d0-d7}
    vldmia	%1, {d8-d15}
    vmul.f32	d16,d0,d8[0]
    vmul.f32	d17,d1,d8[0]
    vmla.f32	d16,d2,d8[1]
    vmla.f32	d17,d3,d8[1]
    vmla.f32	d16,d4,d9[0]
    vmla.f32	d17,d5,d9[0]
    vmla.f32	d16,d6,d9[1]
    vmla.f32	d17,d7,d9[1]
    vstmia	%2!, {d16,d17}
    ~

● e:~z: VFP/NEON の命令単体の実行

vfma は VFPv4 の新しい命令なので、CPU A6(Swift), Krait のみ
実行できます。(Cortex-A9/Scorpion は VFPv3)

無印 = VFP スカラー (float x1)
D    = NEON d レジスタ 64bit (float x2)
Q    = NEON q レジスタ 128bit (float x4)

A は in/out が完全に別レジスタです。
B は 4 命令毎のインターリブで、レイテンシが大きい場合は
A よりもストールする可能性が高くなります。

// A
#define NEON_OPSETv1_8D(op)	\
	op " d0, d1, d1 \n"	\
	op " d2, d1, d1 \n"	\
	op " d3, d1, d1 \n"	\
	op " d4, d1, d1 \n"	\
	op " d5, d1, d1 \n"	\
	op " d6, d1, d1 \n"	\
	op " d7, d1, d1 \n"	\
	op " d8, d1, d1 \n"

// B
#define NEON_OPSETv2_8D(op)	\
	op " d0, d1, d5 \n"	\
	op " d2, d1, d6 \n"	\
	op " d3, d1, d7 \n"	\
	op " d4, d1, d8 \n"	\
	op " d5, d1, d0 \n"	\
	op " d6, d1, d2 \n"	\
	op " d7, d1, d3 \n"	\
	op " d8, d1, d4 \n"

● ALU

(1)/(2) Cortex-A9 の NEON は 64bit (float x2) なので
j: と m: のように D , Q で倍近い差が生じています。

(3) Qualcomm は Scorpion でも NEON が 128bit なので、
j: と m: の差がなく Q では Cortex-A9 の倍の速度が出ています。

(4)/(5) Scorpion 同様 D,Q の差がほとんど無く、NEON が 128bit
だと考えられます。

● Pipeline

(3) の Scorpion は 128bit NEON かつクロックが高いこともあり、
(1)/(2) の Cortex-A9 と比べると全体的に fp 性能が高くなっています。

ですが e:~o: の A に比べて p:~z: の落ち込みが起きており、
低クロックの Cortex-A9 より遅くなっているケースがあります。
Cortex-A9 の場合一部の命令以外は A と B の差が生じていません。

Scorpion は pipeline のステージが深いこと、Cortex-A9 も積和の
fmacs/vmla ではレイテンシが大きいことがわかります。

(4) の A6(Swift) は NEON の場合 A/B の差がほとんど無く、
全体的にスループットが高くなっています。
NEON も out of order で実行していると考えられます。

ただし VFP のスカラーの方が B で遅くなっているため、
レジスタリネーミングは 64bit 単位ではないかと思います。
特にスカラーの積和命令が極端に苦手です。

おそらく fmacs/vmla/vfma の sレジスタアクセスは d 全体を
置き換えるベクタ命令に置き換えた方が高速化できると思われます。

(5) の Krait は Scorpion と比べて明らかにパイプラインの実行効率が
高くなっています。
A/B の差は小さくなっており A6(swift) 同様 out-of-order か latency が
少ないと考えられます。特に a:~d: で差が顕著です。
それでも A6 には敵いません。

特徴的なのは vmla が遅いことで、VFP v4 の vfma と大きな開きがあります。
HW Native なのは vfma の方で、vmla は演算結果の互換性のために mul,add
2命令に展開している可能性があります。
よって、Krait ではできる限り vfma を使った方が良いことになります。

● Krait

Scorpion は浮動小数点演算能力が非常に高いのですが、
ピーク性能を引き出すのはあまり容易ではありませんでした。
その点 Krait は改良されているようです。

ただし整数演算やアプリケーション全体の実行速度ではまだ
大きな差を検出できていません。
Android NDK r8c/r8d では clang (LLVM) が追加されているので、
コンパイラを変えるとまた違った結果になる可能性があります。

また Scorpion にはなかった Quad core なので、システム全体の
速度では最も演算能力が高いことは間違いありません。
同じ Quad core でも Tegra3 などの Cortex-A9 とは世代が異なっており
特に浮動小数点演算能力は 2倍になります。

前回書いたように APQ8064 の Adreno 320 GPU の方もかなり速いのですが、
ベンチマークに使用しているアプリが安定して動作せず計測できていません。
まだ安定しない原因がわかっておりません。

関連エントリ
Adreno 320 Snapdragon S4 Pro APQ8064
iPhone 5 / A6 の CPU 速度 その 3
iPhone 5 / A6 の浮動小数点演算
Snapdragon の本当の浮動小数点演算能力
ARM Cortex-A8 の NEON と浮動小数演算最適化

Adreno 320 Snapdragon S4 Pro APQ8064

HTC J butterfly HTL21 (AQP8064) を手に入れたので、
今更ながらやっと Krait と Adreno 320 を試せるようになりました。

Krait は Qualcomm が開発した ARMv7A CPU の CPU core で
Scorpion の後継にあたります。
ARM でいえば Cortex-A15 の世代に相当し、Apple A6/A6X の CPU core も同様に
この世代に属します。

これら ARM, Qualcomm, Apple 3つの CPU は同じ ARMv7-A の命令
アーキテクチャでアプリケーションに互換性がありますが、
Intel と AMD のように設計や性能は異なります。

ARM            Qualcomm    Apple
---------------------------------------------------------
Cortex-A8/A9   Scorpion                    vfpv3   ~2012
Cortex-A15     Krait       Apple A6        vfpv4   2012~

この中で Krait が最も先に登場しており、日本でも 5月の HTC J 以降
Snapdragon S4 MSM8960/8260A/8660A 搭載機種が増えています。
むしろ LTE では Krait でないスマートフォンの方が少ないかもしれません。

Snapdragon S4 Pro APQ8064 のもう一つ新しい点は、GPU も世代交代していることです。
GPU Adreno 320 はハードウエア的には OpenGL ES 3.0 に対応しており、
こちらも他社に先駆けて手に入る状態となりました。

実際に調べてみると、OpenGL ES 3.0 の新しい圧縮テクスチャ形式である
ETC2 / EAC に対応していることがわかります。

TextureFormat 26
tc[00]=87f9  GL_3DC_X_AMD
tc[01]=87fa  GL_3DC_XY_AMD
tc[02]=8c92  GL_ATC_RGB_AMD
tc[03]=8c93  GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
tc[04]=87ee  GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
tc[05]=8d64  GL_ETC1_RGB8_OES
tc[06]=8b90  GL_PALETTE4_RGB8_OES
tc[07]=8b91  GL_PALETTE4_RGBA8_OES
tc[08]=8b92  GL_PALETTE4_R5_G6_B5_OES
tc[09]=8b93  GL_PALETTE4_RGBA4_OES
tc[10]=8b94  GL_PALETTE4_RGB5_A1_OES
tc[11]=8b95  GL_PALETTE8_RGB8_OES
tc[12]=8b96  GL_PALETTE8_RGBA8_OES
tc[13]=8b97  GL_PALETTE8_R5_G6_B5_OES
tc[14]=8b98  GL_PALETTE8_RGBA4_OES
tc[15]=8b99  GL_PALETTE8_RGB5_A1_OES
tc[16]=9270  GL_COMPRESSED_R11_EAC
tc[17]=9271  GL_COMPRESSED_SIGNED_R11_EAC
tc[18]=9272  GL_COMPRESSED_RG11_EAC
tc[19]=9273  GL_COMPRESSED_SIGNED_RG11_EAC
tc[20]=9274  GL_COMPRESSED_RGB8_ETC2
tc[21]=9275  GL_COMPRESSED_SRGB8_ETC2
tc[22]=9276  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[23]=9277  GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
tc[24]=9278  GL_COMPRESSED_RGBA8_ETC2_EAC
tc[25]=9279  GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC

OpenGL ES 2.0 のままでも列挙されるので、すでに利用できる状態となっています。
ETC1 も同列に列挙されるのは OpenGL ES 2.0 API だからだと思われます。

また GPU Extension に GL_EXT_sRGB が増えています。
sRGB 対応もやはり OpenGL ES 3.0 の新機能です。

Extension の詳細は下記のページに追加しました。

OpenGL ES Extension (Mobile GPU)

GPU 比較はこちら

Mobile GPU の比較

いつものベンチマークはデータをとっている最中です。
使った感じは GPU が非常に速いです。
一番重いケースでも 30fps を余裕で超えており、とても Full HD (1920×1080)
でレンダリングしているとは思えません。

傾向としては Adreno 220 と同じでシェーダーの演算負荷に強く、同じ
Unified Shader ながら PowerVR のように面積が増えても極端に処理落ちしません。
演算精度によるペナルティが無いため、プログラマにとっては非常に扱いやすく
かつ演算精度が高いのでレンダリング結果も綺麗です。

ピクセルシェーダーの命令が少なく演算負荷が軽いケースでは PowerVR が
飛び抜けていますが、ピクセル(フラグメント)の演算量が多い場合はおそらく
A5X の PowerVR SGX543MP4 より速く、A6X の SGX554MP4 に近い数値が出るようです。
もちろん条件によるので万能ではありません。

CPU のデータも計測中ですが CPU core 単体では A6/A6X よりも遅いようです。
やはり A6/A6X は速いです。
その代わり core 数が A6/A6X の 2倍 (Quad core) なので、
総合的な能力では十分だと思います。

関連エントリ
iPad 4 Apple A6X GPU PowerVR SGX554 MP4 の速度
iPhone 5 / A6 の CPU 速度 その 3
iPhone 5 / A6 の CPU 速度 その 2
OpenGL / OpenGL ES ETC1 の互換性と KTX の落とし穴
OpenGL 4.3/ES 3.0 ETC2 Texture 圧縮の仕組み (PVRTC2,ASTC)
OpenGL 4.3 と GL_ARB_ES3_compatibility

Silicon Studio MOBILE GPUMARK のスコア比較

ベンチマークソフトを手持ちのデバイスで試してみました。

Sillicon Studio MOBILE GPUMARK

MOBILE GPUMARK                             GEMS   DP   NB   GPU Total
---------------------------------------------------------------------
iPhone5             A6  PowerVR SGX543MP3   751  902  474  4068  6195
iPad4               A6X PowerVR SGX554MP4   665  729  429  3943  5757
iPad mini           A5  PowerVR SGX543MP2   582  695  362  2852  4491
Nexus 7             Tegra3 ULP GeForce(12)  362  623  231  3271  4487
EVO 3D ISW12HT      MSM8660 Adreno220       431  564  245  2235  3475
iPod touch5         A5  PowerVR SGX543MP2   385  450  239  2338  3412
Galaxy S2 SC-02C    Exynos4210 Mali-400MP4  577  730  174  1196  2677
Optimus Pad L-06C   Tegra2 ULP GeForce(8)   121  220   81  1838  2260
Galaxy Nexus SC-04D OMAP4460 PowerVR SGX540 160  161   63  1273  1657
HONEYBEE 101K       APE5R PowerVR SGX543MP  407  572  240 10673 11892 ※無効

・数値が大きいほうが高速。スコアは v1.0 時のもの
・GEMS=RIGID GEMS, DP=DEAD PARKING, NB= NATURAL BONE, GPU=GPU BENCHMARK
・CPU はすべて dual core 以上

iPad4 より iPhone5 の方が良い結果でした。
画面の解像度が小さい方が多少有利に働くのかもしれません。

SC-04D は非常に低速で、ひと通り完了を待つだけでもかなり時間がかかりました。
見かけの速度は速いですが、SGX540 はやはりひと世代前の GPU であることがわかります。
Galaxy S2 はそこそこのスコアですがディザがかかったような画面に見えるのが気になりました。

HONEYBEE 101K が突出した値に見えますが実は描画が正しく行われておりません。
もともとこの端末は OpenGL ES 2.0 で問題が生じることが多かったのですが、
GEMS,DP,NB の描画はラスタ状に一瞬見える程度でほとんど暗転しており、まるで
V-Sync を待たずにフレームバッファがクリアされているような画面になっています。
よってこのスコアは無効です。

GPU BENCHMARK の内容をさらに詳しく比較したのが下記の表です。

GPU BENCHMARK                 fill high many vert spec  pix norm  420  800 1280
-------------------------------------------------------------------------------
iPhone5      PVR SGX543MP3     538   82  242 1013  871  343  310  364  203  102
iPad4        PVR SGX554MP4     403  137  296  765  726  412  393  234  269  172
iPad mini    PVR SGX543MP2     484   62  158  640  560  241  222  274  144   67
Nexus 7      Tegra3 ULP GF(12) 185   56  116  828  571  288  235  667  218  107
EVO 3D       8660 Adreno220    283   98  123  384  378  320  279  191  132   47
iPod touch5  PVR SGX543MP2     286   39  130  601  513  183  164  243  123   56
Galaxy S2    4210 Mali-400MP4  253   37   26  193  138  159  145  196   29   20
Optimus Pad  Tegra2 ULP GF(8)   75   22   77  572  409  125  102  317   98   41
Galaxy Nexus 4460 PVR SGX540    87   31   48  302  265  190  131  134   62   26
HONEYBEE101K PVR SGX543MP     7768   72   91 1038  595  385  416  161  102   45

・数値が大きいほうが高速。スコアは v1.0 時のもの
・fill=Fill Test, high=High Polygon Model, many=Many Models
・vert=Per Vertex Lighting, spec=Per Vertex Lighting & Specular
・pix=Per Pixel Lighting & Specular, norm=Per Pixel Lighting & Specular & Normal Map
・420=YEBIS Resolution 420x234, 800=YEBIS Resolution 800x450, 1280=YEBIS Resolution 1280x720

PowerVR 系は頂点(vert,spec)とピクセル(pix,norm)のスコアに極端な差が
ついていることがわかります。
Unified Shader である PowerVR 系はピクセル負荷が下がった分だけ頂点性能が
大きく向上します。

同じ Unified ながら全く性質が異なるのが Adreno 220 系で、
頂点(vert,spec)とピクセル(pix,norm)の差がわずかです。
全体の負荷を下げてもピーク性能が上がらない代わりに、ある程度複雑な
ピクセルシェーダーを走らせても性能が落ちにくい傾向があります。

Discrete Shader である Tegra は頂点性能が非常に高いことがわかります。
ピクセル負荷に影響を受けず、Tegra2 でもアンバランスに見えるほど
頂点スコアが高くなっています。
Tegra3 はピクセルも強化されていますが、PowerVR とは異なり
シェーダーの演算能力よりも fill が弱点になっているようです。

Tegra と正反対なのが同じ Discrete の Mali-400MP4 です。
4 core あるのはピクセルユニットだけなので、どうしても相対的に頂点性能が
足りないようです。
spec, pix を比べるとわかりますが、頂点でライティングするよりもむしろ
ピクセルでライティングした方が速くなっています。
GEMS, DP だけを見ると上位に食い込むスコアなので、NB を含めて
ハイポリ系が大きくスコアを落とす原因となっているようです。

HONEYBEE 101K では 420,800,1280 (YEBIS) の描画が完全に壊れていました。
よってこのスコアは正しくないことに注意してください。
それ以外は一見正しく描画されていましたが fill の値だけなぜか突出しています。
この機種だけ Android 2.3 であることも何か関係しているかもしれません。

実際のラインキングを見ると Snapdragon S4 (Adreno225/320) がかなり
上位を占めているようです。

MOBILE GPUMARK – RANKING

ポストエフェクトなどスクリーン系エフェクトは TBDR の PowerVR 等とは
相性がよくなく、Mobile 系 GPU ではあまり用いられていませんでした。
このソフトでは非常によく動いており各種効果による違いもよくわかります。

PowerVR はかなり特徴が偏っているため、PC と同じアプローチだと他の GPU と
あまり差がつかないかもしれません。その点 Tegra の方が素直です。
また highp 演算が多い場合やピクセルの演算命令が複雑な場合は Adreno が有利です。

今後は様々な GPU が登場し、レンダリング手法も幅が広がってくるものと思われます。
Adreno 320 では TBR だけでなく Direct Rendering Mode も使い分けられるので、
このようなケースでも今まで以上に最適化が可能となるようです。

新しい世代の Adreno 320/Mali-T604 をまだ入手できていないので、
機会があればぜひ比べてみたいと思います。

関連エントリ
iPad 4 Apple A6X GPU PowerVR SGX554 MP4 の速度