我在可视化项目中使用 ARB_sparse_texture OpenGL 扩展。我在 glTexturePageCommitmentEXT 调用时遇到随机异常。当我在 NVidia Mosaic 模式下运行我的应用程序时,它会导致计算机重新启动。
我这样调用 glTexturePageCommitmentEXT :
glTexturePageCommitmentEXT( textureId, level, 0, 0, layer, width, height, 1, false );
其中 textureId 指向生成的稀疏纹理:
const PageSizeT & pageSize = pageSizes( internalFormat );
pageSizeX = pageSize.x[pageSizeIndex_];
pageSizeY = pageSize.y[pageSizeIndex_];
pageSizeZ = pageSize.z[pageSizeIndex_];
glGenTextures( 1, &id );
glBindTexture( GL_TEXTURE_2D_ARRAY, id );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SPARSE_ARB, GL_TRUE );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, pageSizeIndex_ );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0 );
glTexStorage3D( GL_TEXTURE_2D_ARRAY, levels, internalFormat, width, height, layers );
handle = glGetTextureHandleARB( id );
glMakeTextureHandleResidentARB( handle );
glBindTexture( GL_TEXTURE_2D_ARRAY, 0 );
level 是 mipmap 级别,0 和 0 x 和 y 偏移量,layer 是 GL_TEXTURE_2D_ARRAY 中切片的索引,width 和 height 是 mipmap 级别中的纹理大小
std::max( (int)textureWidth_ >> level_, 1 )
1是深度。最后一个参数(false)是我要求扩展取消提交给定纹理区域的地方。为了提交纹理特定区域,我对这个函数进行了类似的调用,最后一个参数设置为 true。
glTexturePageCommitmentEXT( textureId, level, 0, 0, layer, width, height, 1, false );
- 我有 12 个屏幕在 NVidia Mosaic 模式下运行。
- 我的电脑上安装了 3 个 NVidia Quadro M6000。
我有一个片段着色器来告诉应用程序这个纹理的哪个部分/mipmap 级别是可见的:
布局(std430,绑定 = 4)缓冲区 TexUsage { uint texUsage []; //[ layer{level, level, level..}...] };
atomicAdd(texUsage[layer * levelCount + int(textureQueryLod(tex, texCoord.xy).y)], 1);
当我找到图层的 mipmap 级别时的每一帧都是可见的,我通过上述步骤提交并创建一个 Framebuffer:
glGenFramebuffers(1, &id);
glBindFramebuffer(GL_FRAMEBUFFER, id); glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureId, level, layer);
// 做一些绘图
glBindFramebuffer(GL_FRAMEBUFFER, 0);
或者,如果我发现一个层的 mipmap 级别不再可见,我使用上面的代码取消提交它。
在我遇到这种随机崩溃后,我尝试了:
- 使用较小的纹理 256x256x100 => 崩溃。
- 不使用稀疏纹理 => 我没有崩溃。
- 试图隔离删除 mipmap 级别的问题(通过将级别设置为 1)=> 没有帮助。
- 尝试禁用马赛克模式并强制 1 个 GPU 而不是 3 个 GPU 来完成工作 => 有些更好,至少我得到了 glTexturePageCommitmentEXT(..., false) 调用的异常。但仍然有随机崩溃。
我的问题:
- 我该如何解决这个问题?
- 怎么了?
- 为什么我没有得到任何 glError?
- 为什么它只能在 1 个 GPU 处于活动状态(马赛克被禁用)时抛出异常?
- 这如何导致计算机重新启动,我该如何防止它?
- 我看到 NVidia 驱动程序有“优化稀疏纹理”选项并且它已打开。这个设置是做什么的?有什么经验吗?
- 有什么建议可以改善整个事情吗?