glMapBufferRange 冻结 OpenGL 驱动程序
glMapBufferRange freezing OpenGL driver
在使用计算着色器生成一组数据并将其存储在着色器存储缓冲区后,我尝试从该缓冲区读取数据以使用代码打印出数据:
#define INDEX_AT(x,y,z,i) (xyzToId(Vec3i((x), (y), (z)),\
Vec3i(NUM_RAYS_X,\
NUM_RAYS_Y,\
POINTS_ON_RAY))\
* 3 + (i))
PRINT_GL_ERRORS();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, dPositionBuffer);
float* data_ptr = NULL;
for (int ray_i = 0; ray_i < POINTS_ON_RAY; ray_i++)
{
for (int y = 0; y < NUM_RAYS_Y; y++)
{
int x = 0;
data_ptr = NULL;
data_ptr = (float*)glMapBufferRange(
GL_SHADER_STORAGE_BUFFER,
INDEX_AT(x, y, ray_i, 0) * sizeof(float),
3 * (NUM_RAYS_X) * sizeof(float),
GL_MAP_READ_BIT);
if (data_ptr == NULL)
{
PRINT_GL_ERRORS();
return false;
}
else
{
for (int x = 0; x < NUM_RAYS_X; x++)
{
std::cout << "("
<< data_ptr[x * 3 + 0] << ","
<< data_ptr[x * 3 + 1] << ","
<< data_ptr[x * 3 + 2] << ") , ";
}
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
PRINT_GL_ERRORS();
std::cout << std::endl;
}
std::cout << "\n" << std::endl;
}
其中函数 xyzToId 将三维坐标转换为一维索引。
然而,当我尝试 运行 时,程序在调用 glMapBufferRange 时崩溃,给出错误消息:
The NVIDIA OpenGL driver lost connection with the display driver due to exceeding the Windows Time-Out limit and is unable to continue.
The application must close.
Error code: 7
Would you like to visit
http://nvidia.custhelp.com/cgi-bin/nvidia.cfg/php/enduser/std_adp.php?p_faqid=3007
for help?
我映射的缓冲区根本不是很大,只有 768 个浮点数,之前在不同的着色器存储缓冲区(只有两个浮点数)上调用 glMapBuffer 没有问题。我似乎无法在网上找到与此错误相关的任何信息,而且我所阅读的有关 glMapBufferRange 速度的所有信息都表明,这种大小的缓冲区应该只需要几十毫秒的时间来映射,而不是两秒程序崩溃的超时时间。
我是否遗漏了一些关于 glMapBufferRange 应该如何使用的信息?
这是一个不相关的错误。今天我了解到 OpenGL 有时会缓冲命令,并且一些操作(如映射缓冲区)会强制它完成其队列中的所有命令。在这种情况下,它是实际调度计算着色器本身的动作。
今天我还了解到,越界索引着色器存储缓冲区将导致 OpenGL 驱动程序冻结,就像它需要很长时间才能完成一样。
总而言之,这主要是错误伪装成不同的错误并在错误的位置弹出的情况。
在使用计算着色器生成一组数据并将其存储在着色器存储缓冲区后,我尝试从该缓冲区读取数据以使用代码打印出数据:
#define INDEX_AT(x,y,z,i) (xyzToId(Vec3i((x), (y), (z)),\
Vec3i(NUM_RAYS_X,\
NUM_RAYS_Y,\
POINTS_ON_RAY))\
* 3 + (i))
PRINT_GL_ERRORS();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, dPositionBuffer);
float* data_ptr = NULL;
for (int ray_i = 0; ray_i < POINTS_ON_RAY; ray_i++)
{
for (int y = 0; y < NUM_RAYS_Y; y++)
{
int x = 0;
data_ptr = NULL;
data_ptr = (float*)glMapBufferRange(
GL_SHADER_STORAGE_BUFFER,
INDEX_AT(x, y, ray_i, 0) * sizeof(float),
3 * (NUM_RAYS_X) * sizeof(float),
GL_MAP_READ_BIT);
if (data_ptr == NULL)
{
PRINT_GL_ERRORS();
return false;
}
else
{
for (int x = 0; x < NUM_RAYS_X; x++)
{
std::cout << "("
<< data_ptr[x * 3 + 0] << ","
<< data_ptr[x * 3 + 1] << ","
<< data_ptr[x * 3 + 2] << ") , ";
}
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
PRINT_GL_ERRORS();
std::cout << std::endl;
}
std::cout << "\n" << std::endl;
}
其中函数 xyzToId 将三维坐标转换为一维索引。
然而,当我尝试 运行 时,程序在调用 glMapBufferRange 时崩溃,给出错误消息:
The NVIDIA OpenGL driver lost connection with the display driver due to exceeding the Windows Time-Out limit and is unable to continue.
The application must close.
Error code: 7
Would you like to visit
http://nvidia.custhelp.com/cgi-bin/nvidia.cfg/php/enduser/std_adp.php?p_faqid=3007
for help?
我映射的缓冲区根本不是很大,只有 768 个浮点数,之前在不同的着色器存储缓冲区(只有两个浮点数)上调用 glMapBuffer 没有问题。我似乎无法在网上找到与此错误相关的任何信息,而且我所阅读的有关 glMapBufferRange 速度的所有信息都表明,这种大小的缓冲区应该只需要几十毫秒的时间来映射,而不是两秒程序崩溃的超时时间。
我是否遗漏了一些关于 glMapBufferRange 应该如何使用的信息?
这是一个不相关的错误。今天我了解到 OpenGL 有时会缓冲命令,并且一些操作(如映射缓冲区)会强制它完成其队列中的所有命令。在这种情况下,它是实际调度计算着色器本身的动作。
今天我还了解到,越界索引着色器存储缓冲区将导致 OpenGL 驱动程序冻结,就像它需要很长时间才能完成一样。
总而言之,这主要是错误伪装成不同的错误并在错误的位置弹出的情况。