Opengl 从uint64\t图像句柄创建图像2D

Opengl 从uint64\t图像句柄创建图像2D,opengl,glsl,nvidia,Opengl,Glsl,Nvidia,要在OpenGL中使用无绑定图像,需要使用glGetImageHandleARB创建GLuint64句柄。然后,您可以将此句柄设置为统一的image2D变量,并使用图像,就像使用旧方法绑定它一样。没问题。使用纹理/采样器,还可以将(纹理)控制柄不设置为sampler2D,而是设置为普通统一的uint64_t变量。然后,可以使用此句柄在运行时使用构造函数sampler2D(句柄)来“构造”采样器对象 采样器使用64位整数句柄表示,可以是 使用构造函数与64位整数进行转换 及 图像使用64位整数句

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

采样器使用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);着色器代码中的某个地方。

使用的语法错误。将uint64\t强制转换为图像的正确语法为:

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

需要多次指定格式。我不知道为什么,也不知道为什么需要指定格式。规范在这方面非常模糊。

图像可以由计算着色器写入,而纹理是只读的。扩展规范没有提到您正在使用的
samperType(uint64_t)
imageType(uint64_t)
构造函数。扩展提供了如下构造函数:
any image type(uvec2)//将一对32位无符号整数转换为图像类型
。它根本没有提到
uint64\u t
,它不是GLSL核心的一种类型,在这个扩展中也没有定义。没错,uint64\u t是在特定于供应商的扩展GL\u NV\u gpu\u着色器5中定义的。然而,这并不能改变问题。甚至写入image2D(uvec2(0));产生从“uint64_t”到“int”的异常“隐式转换”。这确实解决了问题。非常感谢你!太糟糕了,编译器不能给出一个有用的错误消息。我希望能给你一个拥抱。你刚刚结束了长达数小时的斗争。奉耶稣的名,愿恩典与平安归与你们。