2017-12-21 5 views
0

OpenTKでC#を使用してOpenGL APIにアクセスしています。私のプロジェクトでは、テッセレーションを使用して高さマップを描画しています。私のテッセレーションコントロールシェーダは正方形を64個の四角形のグリッドに分割し、私のテッセレーション評価シェーダはそれらのポイントに垂直方向のオフセットを追加します。垂直方向のオフセットは、このような均一なフロートバッファに格納されています。私は、AMDのRadeon 8250 GPUと私のラップトップ上でプロジェクトを実行するときNvidia GPUのバッファサイズが均一

uniform float HeightmapBuffer[65 * 65]; 

すべてが、正常に動作します。問題はNvidiaグラフィックカードで実行しようとすると始まります。私は古いGT 430とブランドの新しいGTX 1060を試してみましたが、結果は同じです。

Tessellation evaluation info 
---------------------------- 
0(13) : error C5041: cannot locate suitable resource to bind variable "HeightmapBuffer". Possibly large array. 

私はこの問題を調査したように、私は両方のNvidiaのチップにAMDと65.54 kBの上〜500メガバイトを返すGL_MAX_UNIFORM_BLOCK_SIZE変数を見つけました。私の配列は実際には16.9 kBしか使用しないので、少し奇妙です。したがって、 "ブロックサイズ"が実際に1つの変数のサイズを制限するかどうかはわかりません。 1つのシェーダーに渡されるすべてのユニフォームのサイズが制限されるのでしょうか?それでも、私のプログラムが65 kBを使うとは思えません。

私はまた、テクスチャを使用して「共通の」道を行くことを試みますが、私は、補間に問題があったと思うので、一緒に隣接する二つのハイトマップを配置する際に、境界が一致しませんでした。反対側に一様なバッファ配列があれば、物事は完全に機能します。

のでGL_MAX_UNIFORM_BLOCK_SIZEの実際の意味は何ですか?なぜNvidia GPUのこの価値は低いのですか?私のシェーダに大きな配列を渡す方法はありますか?

+1

あなたは '4バイト* 4 * 65 * 65' =' 67.6 KiB'を持っているので、 'float'ユニフォームは実際に' vec4'の大きさです。 – genpfault

+0

Hrm、私はGL仕様でその情報を調達するのに苦労しているので、塩の穀物でそれを取る。私はES 2.0仕様を覚えているかもしれません。 – genpfault

+0

[大規模配列のジオメトリシェーダのエラー](https://stackoverflow.com/questions/29262469/error-in-geometry-shader-from-large-array)の可能な複製 – Gusman

答えて

3

この問題を調査したところ、AMDでは〜500MB、両方のNVIDIAチップで65.54KBを返す変数GL_MAX_UNIFORM_BLOCK_SIZEが見つかりました。

GL_MAX_UNIFORM_BLOCK_SIZEは間違っています。これはUniform Buffer Objectsにのみ適用されます。

あなただけの均一なブロックの外

uniform float HeightmapBuffer[65 * 65]; 

配列を宣言。これをテッセレーション評価シェーダで使用するように見えるので、関連する制限はMAX_TESS_EVALUATION_UNIFORM_COMPONENTSです(プログラマブルステージごとに個別の制限があります)。 vec4 4つの成分、float一つだけを消費するように、この成分限界は、フロート要素のわずか数をカウントします。あなたの特定のケース、最新のGL仕様で

、[GL 4.6コアプロファイル](https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf) この記事の執筆時点では、ちょうどそのため1024年の最小値(= 4kiB)を保証し、そしてあなたは方法ですその制限を超えて

データのような量のために、プレーンユニフォームを使用するために実際には非常に悪い考えです。 UBOsTexture Buffer ObjectsShader Storage Buffer Objects、またはプレーンテクスチャを使用して配列を保存することを検討する必要があります。あなたのシナリオでは、UBOがおそらく最も自然な選択となるでしょう。

+0

@PeterMcG:この質問には明らかにコントロール評価ではなく、テッセレーション評価シェーダについてです。デフォルトの統一ブロックは、 'GL_MAX_UNIFORM_BLOCK_SIZE'の意味で統一ブロックではなく、UBOにのみ適用されます。命名は不幸なことかもしれませんが、その仕様は非常に明確です。 – derhass

関連する問題