1

我在可视化项目中使用 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 驱动程序有“优化稀疏纹理”选项并且它已打开。这个设置是做什么的?有什么经验吗?
  • 有什么建议可以改善整个事情吗?
4

0 回答 0