OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理
Posted
技术标签:
【中文标题】OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理【英文标题】:OpenGL - Accessing bindless textures inside glMultiDrawElementsIndirect without NV_gpu_shader5 【发布时间】:2022-01-19 10:12:59 【问题描述】:我正在使用glMultiDrawElementsIndirect
和ARB_bindless_texture
的组合来绘制东西。我使用内置的顶点着色器变量gl_DrawID
获取纹理句柄。据说这个变量是一个动态统一的表达式,这意味着我在访问着色器内的无绑定纹理时不必依赖NV_gpu_shader5
。它看起来像这样。
#version 460 core
out flat int MaterialIndex;
void main()
...
MaterialIndex = gl_DrawID;
#version 460 core
#extension GL_ARB_bindless_texture : require
struct Material
sampler2D Albedo;
ivec2 pad0;
;
layout(std140, binding = 1) uniform BindlessUBO
Material Materials[256];
bindlessUBO;
in flat int MaterialIndex;
void main()
Material material = bindlessUBO.Materials[MaterialIndex];
vec3 albedo = texture(material.Albedo, coords).rgb;
这适用于支持NV_gpu_shader5
的 NVIDIA RTX 3050 Ti。具有所有网格和纹理的模型在一次绘制调用中被正确绘制。但是,在不支持扩展的 AMD RX 5700XT 上,驱动程序会在几秒钟后崩溃。两个 GPU 都可以在没有任何纹理的情况下渲染模型。所以现在我的猜测是MaterialIndex
不是一个动态统一的表达式,即使它从一个表达式中获取它的值。将MaterialIndex
从顶点传递到片段着色器是否使其成为非 d.u.e?我怎样才能在片段着色器中的glMultiDrawElementsIndirect
中获取绘图命令的索引作为 d.u.e?没有NV_gpu_shader5
,有没有办法完成我想做的事情?
【问题讨论】:
您的一个着色器以 4.3 为目标而另一个以 4.6 为目标是否有特定原因?关于多绘制命令的动态统一的定义在版本之间略有变化,对于 4.6,我认为您的表达式是动态统一的,因为它在同一个调用组中具有相同的值。即使它不是动态统一的,我也不希望着色器崩溃而是返回垃圾。 @BDL 我的默认值始终是 4.3,但由于gl_DrawID
,我不得不使用 4.6。我都切换到了4.6。同样的问题。它实际上比崩溃更不确定的行为。取决于我看和移动的地方,我猜。有时它会冻结,有时整个电脑会崩溃。如果我将MaterialIndex
替换为常量,则它可以工作。
听起来像是 AMD 的驱动程序错误。
@BDL 原来是驱动问题。
@derhass 确实:)。
【参考方案1】:
从 AMD 驱动程序 19.12.2
升级到 21.12.1
后,该错误消失了。因此,使用flat
限定符将gl_DrawID
从顶点传递到片段着色器实际上确实将其保留为动态统一表达式,我不需要依赖NV_gpu_shader5
:)。
【讨论】:
以上是关于OpenGL - 在没有 NV_gpu_shader5 的情况下访问 glMultiDrawElementsIndirect 内的无绑定纹理的主要内容,如果未能解决你的问题,请参考以下文章