月別アーカイブ: 2013年6月

NVIDIA Tegra4 の OpenGL ES 2.0 Extension

REGRA Tablet AT703 より、Tegra4 の GL Extension です。

Extension:
GL_OES_rgb8_rgba8
GL_OES_EGL_sync
GL_OES_surfaceless_context
GL_OES_fbo_render_mipmap
GL_NV_depth_nonliner
GL_NV_draw_path
GL_NV_draw_texture
GL_NV_texture_npot_2D_mipmap
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_vertex_half_float
GL_OES_mapbuffer
GL_NV_draw_buffers
GL_NV_multiview_draw_buffers
GL_EXT_color_buffer_half_float
GL_EXT_packed_float
GL_EXT_texture_rg
GL_OES_texture_half_float
GL_NV_texture_array
GL_OES_compressed_ETC1_RGB8_texture
GL_EXT_texture_compression_latc
GL_NV_texture_compression_latc
GL_EXT_texture_compression_dxt1
GL_EXT_texture_compression_s3tc
GL_NV_texture_compression_s3tc
GL_EXT_texture_filter_anisotropic
GL_NV_get_tex_image
GL_NV_read_buffer
GL_NV_shader_framebuffer_fetch
GL_NV_copy_image
GL_NV_fbo_color_attachments
GL_EXT_bgra
GL_EXT_texture_format_BGRA8888
GL_EXT_read_format_bgra
GL_EXT_unpack_subimage
GL_NV_pack_subimage
GL_NV_texture_compression_s3tc_update
GL_NV_read_depth
GL_NV_read_stencil
GL_NV_uniform_buffer_object
GL_NV_map_buffer_range
GL_EXT_robustness
GL_OES_standard_derivatives
GL_NV_EGL_stream_consumer_external
GL_EXT_separate_shader_objects
GL_NV_copy_buffer
GL_NV_3dvision_settings
GL_EXT_debug_marker
GL_EXT_debug_label
GL_KHR_debug
GL_EXT_texture_storage
GL_NV_pixel_buffer_object
GL_NV_framebuffer_blit
GL_NV_non_square_matrices
GL_NV_explicit_attrib_location
GL_OES_vertex_array_object
GL_NV_smooth_points_lines
GL_OES_texture_half_float_linear
GL_NV_texture_border_clamp
GL_OES_depth_texture
GL_OES_depth_texture_cube_map
GL_NV_shadow_samplers_cube
GL_NV_shadow_samplers_array
GL_EXT_shadow_samplers
GL_OES_depth24
GL_EXT_sRGB
GL_NV_sRGB_formats
GL_NV_generate_mipmap_sRGB
GL_EXT_occlusion_query_boolean
GL_NV_occlusion_query_samples
GL_NV_timer_query
GL_NV_framebuffer_multisamples
GL_EXT_frag_depth
GL_NV_instanced_arrays
GL_NV_draw_instanced
GL_NV_secure_context

以前の Tegra2/3 と比べて Extension の数が大幅に増えています。
Tegra3 (Nexus 7) 比で 1.7倍、初期の Tegra2 の 2倍くらいあります。

Tegra2/3 (ULP GeForce) の単なる強化版ではなく、GPU 機能そのものが
大きく変わっていることがわかります。

また NV 拡張機能の割合が非常に多くなっています。
51% も占めており、ハードウエアを使いこなすために NVIDIA がかなり力を
入れている様子が伺えます。

ただ開発サイドとしては、独自拡張よりも他社 GPU との互換性が高まった
ことの方が嬉しいというのが本音です。
例えばこれとか。

GL_OES_depth24
GL_OES_depth_texture

今まで見てきた OpenGL ES 2.0 GPU で 24bit depth が使えなかったのは
Tegra2/3 だけでした。
Tegra4 以降は広い空間のレンダリングも 24bit 前提で作ることができます。
depth_texture も同じで、ShadpwMap を使う場合 Tegra2/3 の場合だけ
別処理が必要でした。

Tegra4 はこれらの欠点を補うどころか、むしろ積極的に機能拡張が
行われているようです。

GL_EXT_shadow_samplers

OpenGL ES 3.0 では標準となる機能ですが、PowerVR SGX 5XT など一部の
GPU ではすでに使えるようになっています。
ただしフィルタリングがかかりませんでした。
未確認ですが Tegra4 はおそらく PCF に対応していると考えられます。

他にも sRGB や draw_instanced など、OpenGL ES 3.0 に対応していないものの
同等の描画が出来るだけの拡張が施されていることがわかります。

他の GPU との比較はこちら↓から。

CPU/GPU OpenGL ES Extension (Mobile GPU)

関連エントリ
Nexus 10 GPU Mali-T604
3DMark Android 版の結果から
HiSilicon K3V2 の GPU
2013/01/09:Qualcomm APQ8064 GPU Adreno 320 の速度

C++11 Lambda function ラムダ関数

C++11 では関数の中で関数オブジェクトの宣言ができるようになっています。
スクリプト系言語などでもよく見る書き方で、下記は関数を値として代入しています。

void func_test()
{
  auto func_obj= []( int a ){
    return a + 100;
  };

  func_obj( 23 );
}

関数ポインタとの違いは、関数や式の中に実体をインラインで無名宣言できることと、
実行コードだけでなく、オブジェクトの中にデータ領域も併せ持つことです。
要するに関数オブジェクトで、以前だと下記のような書き方をしていました。

void func()
{
  struct LocalFuncT {
     int operator()( int a ){
       return a + 100;
     }
  };
  LocalFuncT func_obj= LocalFuncT();

  func_obj( 23 );
}

ただし関数内で宣言された class ↑は template に渡すことができないなど
制限があります。(VisualC++ ではできました)

C++11 ではこの制限が撤廃されると同時に、Lambda 関数としてより簡単に
宣言して使えるようになっています。

template
struct CallbackObject {
  FT Func;
  CallbackObject( FT func ) : Func( func )
  {
  }
  int operator()( int a )
  {
    return  Func( a );
  }
};
template
CallbackObject CreateCallback( FT func )
{
  return  CallbackObject( func );
}

int s_func( int a )
{
  return a + 200;
}

struct FuncObject {
  int operator()( int a )
  {
     returtn a + 300;
  }
};

void func_test()
{
  CreateCallback( s_func )( 12 );  // pointer
  CreateCallback( FuncObject() )( 12 ); // object
  CreateCallback( []( int a ){ return a + 100; } )( 12 ); // lambda
}

今まで関数オブジェクトを扱っていた部分を Lambda 関数で置き換えられます。
オブジェクトなので引数の型を取り出そうとしてもそのままでは関数の型には
マッチしませんが、operator() は取れるようです。

template
struct CallbackObject {
  TT* This;
  FT  Func;
  CallbackObject( TT* t, FT func ) : This( t ), Func( func ) {}
  int operator()( int a )
  {
    return  (This->*Func)( a );
  }
};
template
CallbackObject CreateCallback( TT* t, FT func )
{
  return  CallbackObject( t, func );
}

struct func_class {
  void func_test()
  {
    auto func_obj2= [=]( int a ){ dump(this); return a + 400; };

    func_obj2( 12 );

    func_obj2.operator()( 12 );

    typedef decltype( func_obj2 )  FUNC_T2;
    CreateCallback( &func_obj2, &FUNC_T2::operator() )( 12 );
  }
};

特徴的なのはクロジャーとして変数を自動的に取り込めることで、
関数オブジェクトのメンバとして格納されています。
実際に vc/gcc でキャプチャなしの場合 struct {} 同様に sizeof() が 1 を返しており、
キャプチャ変数が存在する場合はキャプチャ分のサイズになります。

this はキャプチャ変数とみなされるため、自分自身へアクセスする方法は無いようです。
つまりキャプチャ変数に対する暗黙の “this->” が存在しており、
this も this->this 相当となっています。
キャプチャはコピー ([=]) または参照 ([&]) となり、
move ([&&]?) にはならないようです。

関連エントリ
C++11 Variadic Templates 可変長引数のテンプレート
スレッド同期命令の比較 C++11 とコンパイラ
C++11 Rvalue Reference 右辺値参照