OpenGL一覧

Jetson TK1でGLXでOpenGLを使ってみる

前回はEGLで組んでみましたが、折角普通のLinux,OpenGLが使えるボードということで、X11とGLXで前回同様のアプリケーションを作成してみようと思います。

NVIDIAでLinux OpenGL といえば、関数エントリが共有ライブラリに準備されていることで有名です。この組み込み用ではどうであるか確認してみます。

$ nm -Do /usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1

## 一部抜粋  ###

/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:00067478 T glActiveStencilFaceEXT
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0005ec80 T glActiveTexture
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:00064688 T glActiveTextureARB
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006b58c T glActiveVaryingNV
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0005d82c T glAlphaFunc
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006ed38 T glAlphaFuncx
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:000656d4 T glAreProgramsResidentNV
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0005e4d8 T glAreTexturesResident
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:00064568 T glAreTexturesResidentEXT
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0005e19c T glArrayElement
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006440c T glArrayElementEXT
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006aa24 T glAttachObjectARB
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:000603f8 T glAttachShader
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0005b800 T glBegin
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:00061498 T glBeginConditionalRender
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006b154 T glBeginConditionalRenderNV
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:0006b10c T glBeginConditionalRenderNVX
/usr/lib/arm-linux-gnueabihf/tegra/libGL.so.1:00066d08 T glBeginOcclusionQueryNV

今回のボードでも前例通り各関数の実体が含まれるようです。
そこで、GLヘッダを読み込む前に、 GL_GLEXT_PROTOTYPES (1) を定義して extern宣言させた状態にしておきます。

早速プログラムを示します。

このプログラムを実行してみたのがこんな感じです。
Ubuntu-screenshot-glx

GL_RENDERER: GK20A/AXI
GL_VENDOR: NVIDIA Corporation
GL_VERSION: 4.4.0 NVIDIA 19.3
FPS: 1294.80
FPS: 1151.00
FPS: 1046.20
FPS: 1073.00
FPS: 1049.40
FPS: 1051.40
FPS: 987.60
FPS: 995.60
FPS: 1008.20
FPS: 1582.60

平均するとおよそ1000ちょいのFPSといったところでしょうか。前回のEGLに比べると多少パフォーマンスがよい傾向にありそうです。
VSyncをオフにしてみようと思ったのですが、 glXSwapIntervalEXT がこの環境では使用できず試してみることは出来ませんでした。コンテキストは予想通り最新の 4.4 が取得されました。

プログラムコードがglVertexAttribPointerでクライアント配列を渡している部分があったり、毎描画フレームで無駄な処理をしているところが多いので、もしかするとCPU側でバラツキの要因を持っているのかもしれません。


Jetson TK1のOpenGL Extensionリスト

NVIDIA GTC Japan 2014 に参加してきました。そしてJETSON TK1を触ることが出来たので、Tegra K1 の OpenGL Extension リストを取得してみました。噂通り標準のOpenGLサポートしていることがうかがえます。たくさんの拡張名が出てきました。
ついでに、NVIDIA拡張も色々と入っているようで…。

GL_AMD_multi_draw_indirect
GL_AMD_seamless_cubemap_per_texture
GL_ARB_arrays_of_arrays
GL_ARB_base_instance
GL_ARB_bindless_texture
GL_ARB_blend_func_extended
GL_ARB_buffer_storage
GL_ARB_clear_buffer_object
GL_ARB_clear_texture
GL_ARB_color_buffer_float
GL_ARB_compatibility
GL_ARB_compressed_texture_pixel_storage
GL_ARB_conservative_depth
GL_ARB_compute_shader
GL_ARB_compute_variable_group_size
GL_ARB_copy_buffer
GL_ARB_copy_image
GL_ARB_debug_output
GL_ARB_depth_buffer_float
GL_ARB_depth_clamp
GL_ARB_depth_texture
GL_ARB_draw_buffers
GL_ARB_draw_buffers_blend
GL_ARB_draw_indirect
GL_ARB_draw_elements_base_vertex
GL_ARB_draw_instanced
GL_ARB_enhanced_layouts
GL_ARB_ES2_compatibility
GL_ARB_ES3_compatibility
GL_ARB_explicit_attrib_location
GL_ARB_explicit_uniform_location
GL_ARB_fragment_coord_conventions
GL_ARB_fragment_layer_viewport
GL_ARB_fragment_program
GL_ARB_fragment_program_shadow
GL_ARB_fragment_shader
GL_ARB_framebuffer_no_attachments
GL_ARB_framebuffer_object
GL_ARB_framebuffer_sRGB
GL_ARB_geometry_shader4
GL_ARB_get_program_binary
GL_ARB_gpu_shader5
GL_ARB_gpu_shader_fp64
GL_ARB_half_float_pixel
GL_ARB_half_float_vertex
GL_ARB_imaging
GL_ARB_indirect_parameters
GL_ARB_instanced_arrays
GL_ARB_internalformat_query
GL_ARB_internalformat_query2
GL_ARB_invalidate_subdata
GL_ARB_map_buffer_alignment
GL_ARB_map_buffer_range
GL_ARB_multi_bind
GL_ARB_multi_draw_indirect
GL_ARB_multisample
GL_ARB_multitexture
GL_ARB_occlusion_query
GL_ARB_occlusion_query2
GL_ARB_pixel_buffer_object
GL_ARB_point_parameters
GL_ARB_point_sprite
GL_ARB_program_interface_query
GL_ARB_provoking_vertex
GL_ARB_robust_buffer_access_behavior
GL_ARB_robustness
GL_ARB_sample_shading
GL_ARB_sampler_objects
GL_ARB_seamless_cube_map
GL_ARB_seamless_cubemap_per_texture
GL_ARB_separate_shader_objects
GL_ARB_shader_atomic_counters
GL_ARB_shader_bit_encoding
GL_ARB_shader_draw_parameters
GL_ARB_shader_group_vote
GL_ARB_shader_image_load_store
GL_ARB_shader_image_size
GL_ARB_shader_objects
GL_ARB_shader_precision
GL_ARB_query_buffer_object
GL_ARB_shader_storage_buffer_object
GL_ARB_shader_subroutine
GL_ARB_shader_texture_lod
GL_ARB_shading_language_100
GL_ARB_shading_language_420pack
GL_ARB_shading_language_include
GL_ARB_shading_language_packing
GL_ARB_shadow
GL_ARB_stencil_texturing
GL_ARB_sync
GL_ARB_tessellation_shader
GL_ARB_texture_border_clamp
GL_ARB_texture_buffer_object
GL_ARB_texture_buffer_object_rgb32
GL_ARB_texture_buffer_range
GL_ARB_texture_compression
GL_ARB_texture_compression_bptc
GL_ARB_texture_compression_rgtc
GL_ARB_texture_cube_map
GL_ARB_texture_cube_map_array
GL_ARB_texture_env_add
GL_ARB_texture_env_combine
GL_ARB_texture_env_crossbar
GL_ARB_texture_env_dot3
GL_ARB_texture_float
GL_ARB_texture_gather
GL_ARB_texture_mirror_clamp_to_edge
GL_ARB_texture_mirrored_repeat
GL_ARB_texture_multisample
GL_ARB_texture_non_power_of_two
GL_ARB_texture_query_levels
GL_ARB_texture_query_lod
GL_ARB_texture_rectangle
GL_ARB_texture_rg
GL_ARB_texture_rgb10_a2ui
GL_ARB_texture_stencil8
GL_ARB_texture_storage
GL_ARB_texture_storage_multisample
GL_ARB_texture_swizzle
GL_ARB_texture_view
GL_ARB_timer_query
GL_ARB_transform_feedback2
GL_ARB_transform_feedback3
GL_ARB_transform_feedback_instanced
GL_ARB_transpose_matrix
GL_ARB_uniform_buffer_object
GL_ARB_vertex_array_bgra
GL_ARB_vertex_array_object
GL_ARB_vertex_attrib_64bit
GL_ARB_vertex_attrib_binding
GL_ARB_vertex_buffer_object
GL_ARB_vertex_program
GL_ARB_vertex_shader
GL_ARB_vertex_type_10f_11f_11f_rev
GL_ARB_vertex_type_2_10_10_10_rev
GL_ARB_viewport_array
GL_ARB_window_pos
GL_ATI_draw_buffers
GL_ATI_texture_float
GL_ATI_texture_mirror_once
GL_S3_s3tc
GL_EXT_texture_env_add
GL_EXT_abgr
GL_EXT_bgra
GL_EXT_bindable_uniform
GL_EXT_blend_color
GL_EXT_blend_equation_separate
GL_EXT_blend_func_separate
GL_EXT_blend_minmax
GL_EXT_blend_subtract
GL_EXT_compiled_vertex_array
GL_EXT_Cg_shader
GL_EXT_depth_bounds_test
GL_EXT_direct_state_access
GL_EXT_draw_buffers2
GL_EXT_draw_instanced
GL_EXT_draw_range_elements
GL_EXT_fog_coord
GL_EXT_framebuffer_blit
GL_EXT_framebuffer_multisample
GL_EXTX_framebuffer_mixed_formats
GL_EXT_framebuffer_multisample_blit_scaled
GL_EXT_framebuffer_object
GL_EXT_framebuffer_sRGB
GL_EXT_geometry_shader4
GL_EXT_gpu_program_parameters
GL_EXT_gpu_shader4
GL_EXT_multi_draw_arrays
GL_EXT_packed_depth_stencil
GL_EXT_packed_float
GL_EXT_packed_pixels
GL_EXT_pixel_buffer_object
GL_EXT_point_parameters
GL_EXT_provoking_vertex
GL_EXT_rescale_normal
GL_EXT_secondary_color
GL_EXT_separate_shader_objects
GL_EXT_separate_specular_color
GL_EXT_shader_image_load_store
GL_EXT_shader_integer_mix
GL_EXT_shadow_funcs
GL_EXT_stencil_two_side
GL_EXT_stencil_wrap
GL_EXT_texture3D
GL_EXT_texture_array
GL_EXT_texture_buffer_object
GL_EXT_texture_compression_dxt1
GL_EXT_texture_compression_latc
GL_EXT_texture_compression_rgtc
GL_EXT_texture_compression_s3tc
GL_EXT_texture_cube_map
GL_EXT_texture_edge_clamp
GL_EXT_texture_env_combine
GL_EXT_texture_env_dot3
GL_EXT_texture_filter_anisotropic
GL_EXT_texture_integer
GL_EXT_texture_lod
GL_EXT_texture_lod_bias
GL_EXT_texture_mirror_clamp
GL_EXT_texture_object
GL_EXT_texture_shared_exponent
GL_EXT_texture_sRGB
GL_EXT_texture_sRGB_decode
GL_EXT_texture_storage
GL_EXT_texture_swizzle
GL_EXT_timer_query
GL_EXT_transform_feedback2
GL_EXT_vertex_array
GL_EXT_vertex_array_bgra
GL_EXT_vertex_attrib_64bit
GL_EXT_x11_sync_object
GL_EXT_import_sync_object
GL_IBM_rasterpos_clip
GL_IBM_texture_mirrored_repeat
GL_KHR_debug
GL_KHR_texture_compression_astc_ldr
GL_KTX_buffer_region
GL_NV_bindless_multi_draw_indirect
GL_NV_bindless_texture
GL_NV_blend_equation_advanced
GL_NV_blend_equation_advanced_coherent
GL_NV_blend_square
GL_NV_compute_program5
GL_NV_conditional_render
GL_NV_copy_depth_to_color
GL_NV_copy_image
GL_NV_depth_buffer_float
GL_NV_depth_clamp
GL_NV_draw_texture
GL_NV_ES1_1_compatibility
GL_NV_explicit_multisample
GL_NV_fence
GL_NV_float_buffer
GL_NV_fog_distance
GL_NV_fragment_program
GL_NV_fragment_program_option
GL_NV_fragment_program2
GL_NV_framebuffer_multisample_coverage
GL_NV_geometry_shader4
GL_NV_gpu_program4
GL_NV_gpu_program4_1
GL_NV_gpu_program5
GL_NV_gpu_program5_mem_extended
GL_NV_gpu_program_fp64
GL_NV_gpu_shader5
GL_NV_half_float
GL_NV_light_max_exponent
GL_NV_multisample_coverage
GL_NV_multisample_filter_hint
GL_NV_occlusion_query
GL_NV_packed_depth_stencil
GL_NV_parameter_buffer_object
GL_NV_parameter_buffer_object2
GL_NV_path_rendering
GL_NV_pixel_data_range
GL_NV_point_sprite
GL_NV_primitive_restart
GL_NV_register_combiners
GL_NV_register_combiners2
GL_NV_shader_atomic_counters
GL_NV_shader_atomic_float
GL_NV_shader_buffer_load
GL_NV_shader_storage_buffer_object
GL_NV_texgen_reflection
GL_NV_texture_barrier
GL_NV_texture_compression_vtc
GL_NV_texture_env_combine4
GL_NV_texture_expand_normal
GL_NV_texture_multisample
GL_NV_texture_rectangle
GL_NV_texture_shader
GL_NV_texture_shader2
GL_NV_texture_shader3
GL_NV_transform_feedback
GL_NV_transform_feedback2
GL_NV_vdpau_interop
GL_NV_vertex_array_range
GL_NV_vertex_array_range2
GL_NV_vertex_attrib_integer_64bit
GL_NV_vertex_buffer_unified_memory
GL_NV_vertex_program
GL_NV_vertex_program1_1
GL_NV_vertex_program2
GL_NV_vertex_program2_option
GL_NV_vertex_program3
GL_NVX_conditional_render
GL_NVX_nvenc_interop
GL_NVX_shader_thread_group
GL_NVX_shader_thread_shuffle
GL_SGIS_generate_mipmap
GL_SGIS_texture_lod
GL_SGIX_depth_texture
GL_SGIX_shadow
GL_SUN_slice_accum

標準のOpenGLが動くためか、EGLのライブラリは v2 までのものしか含まれていない様子。
スペック上は GLES 3.0 サポートだったような気がしますが、これはまぁフルスペックの GL 4.4 内の GL_ARB_ES3_compatibility があるからこちらで対応よろしくってことでしょうか。


OpenGLでMSAA

以前にDirectX11でMSAAというタイトルでテクスチャに対するMSAAをやってみましたが今回はそれのOpenGL版をやってみたいと思います。結果はこんな感じです。画像を切った貼ったしたので、ねつ造と言われてしまうかも・・・。

ogl-msaa-result

必要になるGL拡張

最近のOpenGL対応ボードならば問題ないと思いますが、OpenGL 2.1対応とか言われているボードでは下記の拡張が存在するか確認が必要です。

  • GL_EXT_framebuffer_blit
  • GL_EXT_framebuffer_multisample

これが NVの拡張であってもとりあえず使えるには使えると思います。

手順

まず、FBOが2つ必要になります。内訳としては次のような感じです。

  • MSAA描画するFramebufferObject(fbo)を作成する.
  • MSAA処理されたテクスチャを得るためのfboを作成する

描画時の流れはこんな感じです。

  1. MSAAのFBOをバインドして描画を行う
  2. MSAAのFBOから通常FBOへBlitFramebuffer
  3. 通常FBOの中にアタッチされているテクスチャを使用

このBlitFramebufferという処理がDirectXでいうところの Resolve関数になるかなと思います。
この処理によって通常のテクスチャとしてMSAAがかかった描画結果を使用することができます。
DirectX時はテクスチャに対して Resolve 出来ましたが GLではそれが直テクスチャ指定できないので一度FBOを作る必要があるようです。

プログラムコード

まずMSAAのFBOを作るところです。
MSAAの場合はテクスチャをアタッチするのではなくレンダーバッファをMSAA用のものを作成し、それを使用するようにします。

Resolve先のFBOを作成します。

描画の時の Resolve関連はこんな感じになります。

注意点など

glBlitFramebufferのバッファフラグは OR 結合で複数指定は出来ないようなので注意しましょう。
MSAAの動作確認時には、小さいテクスチャに対して描画してそれを拡大して貼るのがおすすめです。また、元々は水平垂直のポリゴンを回転させて斜めになるようにして描画したものを使用するとMSAAのかかり具合の確認がしやすいです。

確認の際にはテクスチャフィルタをポイントサンプルとなるようにしておくことや、ドットバイドットの表示をしておくことも忘れがち&やっちゃいがちなので注意しましょう。
(現にDX11のときにはうまくできたのに、GL版実装中で自分が↑をやっちゃいました)


XPERIA Z1 Compact (4.3)で GL Extension

XPERIA Z1 Compact (Android 4.3) にて GL Extension のリストを取得してみました。

OpenGL ES 3.0 V@53.0 AU@04.03.00.146.083 (CL@)
Qualcomm Adreno (TM) 330

GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_discard_framebuffer
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_texture_filter_anisotropic
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_EXT_disjoint_timer_query

微妙にですが S4 のものと比べて extension の個数が減っています・・・。


GalaxyS4 Kitkat (4.4) で GL extension

GalaxyS4 について kitkatに更新してからGL Extensionのリストを取得してみました。

OpenGL ES 3.0 V@45.0 AU@  (CL@3869936)
Qualcomm  Adreno (TM) 320

GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_discard_framebuffer
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_sRGB_write_control
GL_EXT_texture_sRGB_decode
GL_EXT_texture_filter_anisotropic
GL_EXT_multisampled_render_to_texture
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_EXT_disjoint_timer_query

Ubuntuで EGL使えるか?

先日NVIDIAのドライバをインストールした Ubuntu ですが、なんとEGLやGLES2についてのライブラリをもっているようでした。(331.20ではダメだった・・・)

これは X 上で EGL & GLES2が使えるんじゃないかと思い試してみることにしました。

続きを読む


OpenGL の ComputeShader

今回はようやくOpenGLでのComputeShaderを扱ってみます。意外とOpenGLでのComputeShaderって話題になっていないようで、ワクワクしています。

手順

VertexShader, FragmentShader などを生成するように、ComputeShader を生成します。ComputeShaderもまたGLSLで記述するので、今までのシェーダーを生成するような感じでプログラムを記述します。ひとつ違うのは出力する箇所でしょうか、今まではピクセルに出力する感じで out 変数に入れていましたが、ComputeShader では imageXXX というサンプラーっぽい型のuniform変数に値を書き込んでいく感じになります。

C++側のコードは以下のような感じになります。通常のシェーダーと同じようにGLSLをコンパイルして ShaderProgram を作成します。

ComputeShaderからの結果を格納するためのテクスチャを用意しておきます。
このときいつも通りにテクスチャを用意した後、下記のAPIにて設定しておきます。これが Shader Image load store 拡張のAPIになります。これによりテクスチャをUAV化というか書き込み先として利用できるようになります。

通常のメインループにおいては、以下のような感じでコンピュートシェーダーを実行し、結果をテクスチャとして利用して貼り付けています。コンピュートシェーダーの実行は glDispatchCompute で行います。

GL_computeshader

今回は gl_GlobalInvocationID を使って処理しているだけですが、各処理ブロックを識別するのに使える変数がもっとたくさんあります。これらの意味を理解して適切に使っていかないと折角の演算力を生かし切ることができません。
CUDAやDirectComputeのほうでもこれらのパラメータに相当するものがあるようなので、またそれらを試してみたときにどういう対応なのか、どの部分を指し示すのかをまとめてみたいと思います。


OpenGLでComputeShaderを使う前に

OpenGLでComputeShader を使う前に実は知っておくべきことが意外とある、ということで今回はその内容についてです。

ComputeShader は演算のためのシェーダーです。その演算内容をどこかに書き出さなければなりません。OpenGLでは、2種類ほどあるようでそれが以下の物に該当するようです。

  • Shader Image load store
  • Shader Storage buffer object (ssbo)

前者はOpenGL 4.2で取り入れられたもので、後者は 4.3 ではいったもののようです。

Shader Image load storeは、フォーマットが決められた出力先へ記録することができるようです。たとえば float4つの値を2次元テクスチャに記録するとか、そんな感じです。DirectXのほうはよくわかっていませんが RWTexture2D とかそういう系列のものに近いんじゃないかと思います。

Shader Storage buffer object (SSBOと略するらしい) は、フォーマットは比較的自由でGLのシェーダーの中からは Read/WriteできるUniform Buffer Object(UBO)のようなものとしてアクセスができる物のようです。DirectX11のほうでいえば、RWStructuredBuffer に相当するといったところでしょうか。

一方DirectXのRWByteAddressBuffer に相当する物はちょっとわかりませんでした。あまり一般的に使われる物ではない、という位置づけでOpenGLでは入っていないのでしょうか。知っている人がいたら教えて下さい。

言い忘れていましたが、これらUAV相当ということでひとまとめにしてもいいのかもしれません。


GLSLのシェーダーリフレクション (2)

OpenGL (GLSL) のユニフォームブロックでのシェーダーリフレクションを試してみました。
ここで使った vertexShader, fragment shaderは以下のようなものです。

これらのシェーダーについて情報を出してみるとこのような感じになりました。
まずはシェーダーユニフォームの一覧.

ユニフォームブロックの中身のメンバには、ロケーションIDは振られていないことが確認できます。ユニフォームのインデックスは振られており、情報はこちら軽油で取得できるようです。
そして、ユニフォームブロックに関して情報を取得してみます。

ユニフォームブロック内でのシェーダー定数のオフセットが取得できました。
ユニフォームブロック内に構造体を配置しても、従来のシェーダー定数の場合と変わらないような名前でオフセットやデータ型を取得できることがわかります。

std140 とかレイアウト指定をしない場合、シェーダーによって(環境によって?)定数の位置が変わりそうです。
そのため、UBOを複数のシェーダーで使い回すのは難しそうです。この場合結局定数毎に書き込む位置を見てバッファ内のデータ更新という手続きをとるので、あまりUBOによる描画効率化に繋がらないように感じます。

ユニフォームブロック内の定数であっても GL_ACTIVE_UNIFORMS にて有効なユニフォーム変数としてカウントされていることに少々驚きました。ただしユニフォームブロック内の変数名からは有効なロケーションが取得できません。ユニフォームブロック内の変数についてはロケーション=-1となっているようです。


GLSLのシェーダーリフレクション

GLSLいじりの過程で、シェーダーリフレクションっぽいことをやってみたのでその調査結果です。

OpenGLでは別に他のライブラリに依存することなく、シェーダーリフレクションの機能を持っています。普段ではuniform変数のロケーション情報を名前から取得しているかと思いますが、その延長上でいろいろな情報をとれるようになっています。

そこで次のようなシェーダープログラム(抜粋)で、どのように情報がとれてくるか試してみました。

結果はこんな感じでした。ドライバの状態によっては別の結果を返してきそうな気配も・・・。AMDやIntelで試してみたいところです。

NVIDIA 331.65 のドライバの結果。

ここからわかることは、次のような感じかと。

  • 配列の場合には [0] とか付加されて返ってくる. (NVIDIAの場合限定かも?)
  • サイズとして配列のサイズ(長さ)が返ってくる
  • 構造体メンバの場合は、構造体変数名が間に挟まっている
  • 構造体だからといって、1つのuniform location に集約されるわけではない

GLSLは構造体使えるから、お?とおもっていたのですが、実際のところは内部のメンバに対して1つずつロケーションが与えられているようです。

次回には、Uniform Blockでのリフレクションのチェックをしてみたいと思います。