从uint64_t图像句柄

时间:2015-09-02 09:26:37

标签: opengl glsl nvidia

要在OpenGL中使用无绑定图像,您需要使用 glGetImageHandleARB 创建一个GLuint64句柄。然后,您可以将此句柄设置为统一的image2D变量,并使用该图像,就像您以旧方式绑定它一样。没问题。使用纹理/采样器,还可以将(纹理)句柄设置为不使用sampler2D,而是设置为简单统一的uint64_t变量。然后,可以使用此句柄在运行时使用构造函数 sampler2D(句柄)“构造”一个​​sampler对象。

The extension description says:

  

采样器使用64位整数句柄表示,可能是   使用构造函数转换为64位整数和从64位整数转换而来。

  

图像使用64位整数句柄表示,可能是   使用构造函数转换为64位整数和从64位整数转换而来。

所以我认为图像的构造与采样器的构造方式相同,但事实并非如此。示例代码:

#version 450
#extension GL_ARB_bindless_texture : enable
#extension GL_NV_gpu_shader5 : enable

layout(bindless_image, rgba8) uniform image2D myBindlessImage;

uniform uint64_t textureHandle;
uniform uint64_t imageHandle;

void main()
{
    sampler2D mySampler = sampler2D(textureHandle); // works like a charm
    ... = texture(mySampler, texCoord);

    ... = imageLoad(myBindlessImage, texCoordI); // works like a charm

    layout(rgba8) image2D myImage = image2D(imageHandle); // error C7011: implicit cast from "uint64_t" to "int"
    ... = imageLoad(myImage, texCoordI);
}

显然,扩展描述中提到的image2D(uint64_t)构造函数和image2D(uvec2)构造函数都不为编译器所知。我在这里遗漏了什么,或者现在根本没有实施,虽然它应该是?我现在使用的视频驱动程序是Nvidia的355.82。如果有人能够了解这是否适用于任何其他司机/供应商的卡,我会很高兴。

顺便说一下,为什么我需要这个功能:与纹理手柄相比,图像手柄不能识别整个底层数据,只能识别一个纹理级别。如果要在着色器中执行任何mipmap或其他分层工作并需要绑定几个/所有纹理级别,则可以在缓冲区中提供所有级别的句柄,然后根据需要在着色器运行时构造它们。现在,您必须为n个纹理级别定义n个不同的统一图像2D,这是相当繁琐的,特别是如果图像大小发生变化。

附录:重现编译错误的最快方法是在着色器代码中的某处放置 image2D(0lu);

1 个答案:

答案 0 :(得分:1)

您使用的语法错误。将uint64_t强制转换为图像的正确语法是:

layout(rgba8) image2D myImage = layout(rgba8) image2D(imageHandle);

需要多次指定格式。我不知道为什么,也不知道为什么甚至需要指定格式。该规范对此非常模糊。