简体   繁体   English

使用具有多个采样器制服的单个纹理图像单元

[英]Using a single texture image unit with multiple sampler uniforms

I am writing a batching system which tracks currently bound textures in order to avoid unnecessary glBindTexture() calls. 我正在编写一个批处理系统,它跟踪当前绑定的纹理,以避免不必要的glBindTexture()调用。 I'm not sure if I need to keep track of which textures have already been used by a particular batch so that if a texture is used twice, it will be bound to a different TIU for the second sampler which requires it. 我不确定是否需要跟踪特定批次已经使用了哪些纹理,这样如果纹理被使用了两次,它将被绑定到需要它的第二个采样器的不同TIU。

Is it acceptable for an OpenGL application to use the same texture image unit for multiple samplers within the same shader stage? OpenGL应用程序是否可以在同一着色器阶段为多个采样器使用相同的纹理图像单元? What about samplers in different shader stages? 那些不同着色器阶段的采样器呢? For example: 例如:

Fragment shader: 片段着色器:

...
uniform sampler2D samp1;
uniform sampler2D samp2;

void main() { ... }

Main program: 主程序:

...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_id);
glUniform1i(samp1_location, 0);
glUniform1i(samp2_location, 0);
...

I don't see any reason why this shouldn't work, but what about if the shader program also included a vertex shader like this: 我没有看到为什么这不起作用的任何原因,但是如果着色器程序还包括这样的顶点着色器:

Vertex shader: 顶点着色器:

...
uniform sampler2D samp1;

void main() { ... }

In this case, OpenGL is supposed to treat both instances of samp1 as referencing the same location. 在这种情况下,OpenGL应该将samp1两个实例视为引用相同的位置。 Therefore, the same texture unit is being used in the vertex and fragment shaders. 因此,在顶点和片段着色器中使用相同的纹理单元。 I have read that using the same texture in two different shader stages counts doubly against GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS but this would seem to contradict that. 我已经读过在两个不同的着色器阶段使用相同的纹理对GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS进行双重GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS但这似乎与此相矛盾。

In a quick test on my hardware (HD 6870), all of the following scenarios worked as expected: 在我的硬件(HD 6870)上进行快速测试时,以下所有方案均按预期工作:

  • 1 TIU used for 2 sampler uniforms in same shader stage 1个TIU用于同一着色器阶段的2个采样器制服
  • 1 TIU used for 1 sampler uniform which is used in 2 shader stages 1 TIU用于1个采样器制服,用于2个着色器阶段
  • 1 TIU used for 2 sampler uniforms, each occurring in a different stage. 1个TIU用于2个采样器制服,每个制服发生在不同的阶段。

However, I don't know if this is behavior that I should expect on all hardware/drivers, or if there are performance implications. 但是,我不知道这是否是我应该期望在所有硬件/驱动程序上的行为,或者是否存在性能影响。

Hopefully this will clear up some of your confusion, I used an older version of the spec. 希望这会清除你的一些困惑,我使用旧版本的规范。 for simplicity, newer versions have two additional stages (tessellation control / evaluation) so the discussion is a little more complicated. 为简单起见,较新版本有两个额外阶段(曲面细分控制/评估),因此讨论稍微复杂一些。

OpenGL 3.3 (Core Profile) - 2.11. OpenGL 3.3(核心专业版) - 2.11。 Vertex Shaders - pp. 80 顶点着色器 - 第80页

Texture Access 纹理访问

Shaders have the ability to do a lookup into a texture map. 着色器能够查找纹理贴图。 The maximum number of texture image units available to vertex, geometry, or fragment shaders are respectively the values of the implementation-dependent constants GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS , GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS , and GL_MAX_TEXTURE_IMAGE_UNITS . 可用于顶点,几何或片段着色器的纹理图像单元的最大数量分别是依赖于实现的常量GL_MAX_VERTEX_TEXTURE_IMAGE_UNITSGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITSGL_MAX_TEXTURE_IMAGE_UNITS The vertex shader, geometry shader, and fragment shader combined cannot use more than the value of GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS texture image units. 顶点着色器,几何着色器和片段着色器组合使用不能超过GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS纹理图像单元的值。 If more than one of the vertex shader, geometry shader, and fragment processing stage access the same texture image unit, each such access counts separately against the GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS limit. 如果顶点着色器,几何着色器和片段处理阶段中的多个访问同一纹理图像单元,则每个此类访问将与GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS限制分开计算。

The limit is imposed based on the number of unique samplers used in each stage. 基于每个阶段中使用的唯一采样器的数量来施加限制。 Two sampler uniforms with different names but which reference the same texture unit are effectively the same as far as usage determination is concerned. 两个具有不同名称但引用相同纹理单元的采样器制服在使用确定方面实际上是相同的。 Usage refers to doing something like texture (sampler, coords) , if that was not already obvious. 用法指的是做一些像texture (sampler, coords) ,如果那不是很明显的话。 Merely declaring a sampler and assigning it a value is not going to bring you any closer to the implementation-defined limit, you actually have to use the sampler at run-time and if it has the same value as another used sampler in the same stage it does not count. 仅仅声明一个采样器并为其赋值不会使您更接近实现定义的限制,您实际上必须在运行时使用采样器,并且它与同一阶段中的另一个使用的采样器具有相同的值它不算数。

As for using the same texture object multiple times, no this is not what the GL_MAX_..._IMAGE_UNITS limit is all about. 至于多次使用相同的纹理对象,这不是GL_MAX_..._IMAGE_UNITS限制的全部内容。 You could bind the same texture to all 48 texture units (minimum implementation requirement in GL3.3 - this effectively mandates at least 16 textures per-stage) if you wanted, this limit refers to the number of different samplers you use (again, see above) in a shader stage. 您可以将相同的纹理绑定到所有48个纹理单元(GL3.3中的最低实现要求 - 这有效地要求每个阶段至少16个纹理)如果您愿意,此限制是指您使用的不同采样器的数量(再次,请参阅在着色器阶段。 You might actually want to bind the same texture to multiple texture units if you need to use it once with nearest neighbor filtering and another time with linear or a different wrap state. 实际上,您可能希望将相同的纹理绑定到多个纹理单元,如果您需要使用最近邻居过滤一次,另一次使用线性或不同的包裹状态。

If you want to know what behavior to expect on all drivers/hardware, always consult the formal OpenGL specification. 如果您想知道所有驱动程序/硬件的行为,请始终参考正式的OpenGL规范。 I cherry picked the relevant information for you, but it would do you well to learn how to search through it for important details in the future. 我为您挑选了相关信息,但是如果您将来了解如何搜索重要细节,那将会很好。 Every specification since OpenGL 1.0 is freely available from: http://www.opengl.org/registry/ . 自OpenGL 1.0以来的每个规范都可以从http://www.opengl.org/registry/免费获得。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM