我在 github 上关注 apitest,并在我的渲染器中看到一些非常奇怪的行为。
虚拟页面似乎没有收到正确的图像数据。
原始图像为 500x311:
当我使用稀疏纹理渲染此图像时,我必须将后备存储的大小调整为 512x384(作为页面大小的倍数),我的结果是:
如您所见,看起来子图像的一部分(子子图像)已加载到每个单独的虚拟页面。
为了测试这一点,我将图像裁剪为只有 1 个虚拟页面 (256x128) 的大小:结果如下:
正如预期的那样,单个虚拟页面充满了精确、正确、裁剪的图像。
最后,我将裁剪大小增加到 2 个虚拟页面,256x256,一个在另一个之上。结果如下:
这证明使用大于 Virtual_Page_Size 的 texelData 量调用 texSubimage 会导致错误。
将数据传递给大于虚拟页面大小的 glsubimage 时是否需要小心?我在 apitest 中看不到这方面的逻辑,所以认为这可能是驱动程序问题。或者我错过了一些重要的东西。
这是一些代码:
我将纹理存储在纹理数组中,为了简化,将数组变成了一个纹理 2d。两者都产生相同的确切结果。这是纹理内存分配:
_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 级别。当我使用 Mip 级别和纹理数组时,我得到了不同的结果,但行为相似。
此外,图像是从 SOIL 加载的,在我实现稀疏纹理之前,效果很好(在稀疏之前我实现了无绑定)。