github で apitest をフォローしていますが、レンダラーで非常に奇妙な動作が見られます。
仮想ページが正しい画像データを受信していないようです。
元の画像は 500x311 です:
スパース テクスチャを使用してこの画像をレンダリングする場合、バッキング ストアのサイズを 512x384 (ページ サイズの倍数) に変更する必要があります。結果は次のようになります。
ご覧のとおり、サブイメージの一部 (サブサブイメージ) が個々の仮想ページにロードされたように見えます。
これをテストするために、画像を 1 つの仮想ページ (256x128) のサイズにトリミングしました。結果は次のとおりです。
予想通り、単一の仮想ページには正確で正確なトリミングされた画像が埋め込まれていました。
最後に、切り抜きサイズを 2 つの仮想ページに相当する 256x256 に増やしました。結果は次のとおりです。
これは、Virtual_Page_Size より大きい量の texelData で texSubimage を呼び出すとエラーが発生することを証明しています。
仮想ページサイズより大きいデータを glsubimage に渡すときは注意が必要ですか? apitest にはこれに関するロジックが見当たらないので、これはドライバーの問題である可能性があると思います。または、私は何か大きなものを見逃しています。
ここにいくつかのコードがあります:
テクスチャを Texture Array に保存し、単純化するために配列をただの texture2d に変えました。どちらもまったく同じ結果になります。テクスチャ メモリの割り当ては次のとおりです。
_check_gl_error();
glGenTextures(1, &mTexId);
glBindTexture(GL_TEXTURE_2D, mTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
// TODO: This could be done once per internal format. For now, just do it every time.
GLint indexCount = 0,
xSize = 0,
ySize = 0,
zSize = 0;
GLint bestIndex = -1,
bestXSize = 0,
bestYSize = 0;
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &indexCount);
if(indexCount == 0) {
fprintf(stdout, "No Virtual Page Sizes for given format");
fflush(stdout);
}
_check_gl_error();
for (GLint i = 0; i < indexCount; ++i) {
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, i);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &xSize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &ySize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &zSize);
// For our purposes, the "best" format is the one that winds up with Z=1 and the largest x and y sizes.
if (zSize == 1) {
if (xSize >= bestXSize && ySize >= bestYSize) {
bestIndex = i;
bestXSize = xSize;
bestYSize = ySize;
}
}
}
_check_gl_error();
mXTileSize = bestXSize;
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, bestIndex);
_check_gl_error();
//Need to ensure that the texture is a multiple of the tile size.
physicalWidth = roundUpToMultiple(width, bestXSize);
physicalHeight = roundUpToMultiple(height, bestYSize);
// We've set all the necessary parameters, now it's time to create the sparse texture.
glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, physicalWidth, physicalHeight);
_check_gl_error();
for (GLsizei i = 0; i < slices; ++i) {
mFreeList.push(i);
}
_check_gl_error();
mHandle = glGetTextureHandleARB(mTexId);
_check_gl_error();
glMakeTextureHandleResidentARB(mHandle);
_check_gl_error();
mWidth = physicalWidth;
mHeight = physicalHeight;
mLevels = levels;
割り当て後は次のようになります。
glTextureSubImage2DEXT(mTexId, GL_TEXTURE_2D, level, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
幅と高さをバッキング ストアの物理的な幅と、受信する画像コンテンツの幅/高さにしてみました。どちらも望ましい結果を生み出しません。今のところ mip レベルは除外します。ミップ レベルとテクスチャ アレイを使用していたとき、異なる結果が得られましたが、動作は似ていました。
また、画像はSOILからロードされ、スパーステクスチャを実装する前は非常にうまく機能していました(スパース前にバインドレスを実装しました)。