gpt4 book ai didi

opengl - 带字节的着色器存储缓冲区对象

转载 作者:行者123 更新时间:2023-12-05 08:27:40 24 4
gpt4 key购买 nike

我正在开发一个计算着色器,输出被写入 SSBO .现在,这个缓冲区的使用者是 CUDA,它希望它包含无符号字节。我目前看不到如何在 SSBO 中为每个索引写入一个字节的方法。使用纹理或图像处理规范化 float 到无符号字节的转换通过 OpenGL。例如,我可以附加一个内部格式为 R8 的纹理并存储每个条目的字节。但是 SSBO 不可能有这样的事情。这是否意味着除了 bool 数据类型外,SSBO 中的所有数字存储类型至少可以是 4仅每个条目的字节数?

实际上,我希望能够做到以下几点:

计算着色器:

  #version 430 core
layout (local_size_x = 8,local_size_y = 8 ) in;
struct SSBOBlock
{
byte mydata;
};


layout(std430,binding = BUFFER_OUTPUT) writeonly buffer bBuffer
{

SSBOBlock Ouput[];

} Out;


void main()
{
//..... Compute shader stuff...
//.......
Out.Ouput[globalIndex].mydata = val;//where val is normalized float
}

最佳答案

对于标量,GPU 上公开的最小类型往往是 32 位。甚至您提到的 bool 类型实际上也是 32 位的。像 C 这样的语言通常也是如此; bool 值不需要超过 1 位,但即便如此,bool 也不是“给我可用的最小数据类型”的同义词。

然而,您可以使用一些内部函数来打包和解包数据类型,我将在下面展示如何使用它们的示例:

#version 420 core
layout (local_size_x = 8,local_size_y = 8 ) in;
struct SSBOBlock
{
uint mydata;
};


layout(std430,binding = BUFFER_OUTPUT) writeonly buffer bBuffer
{

SSBOBlock Ouput[];

} Out;


void main()
{
//..... Compute shader stuff...
//.......
Out.Output [globalIndex].mydata = packUnorm4x8 (val)
// where val is a 4-component unsigned normalized vector to pack into globalIndex
}

您的示例着色器显示尝试将单个标量写入“字节”数据类型,这是不可能的,您将不得不以某种方式修改它以使用引用一组 4 个标量的索引。在最坏的情况下,这可能意味着解包三个值,然后重新打包整个内容,只为了编写一个标量。

此内部函数在 GL_ARB_shading_languge_packing 的扩展规范中进行了讨论并且是 GL 4.2 及更高版本的核心。


即使您使用的实现不支持该扩展,扩展规范的文本中也会准确解释每个扩展的作用。 packUnorm4x8 的等效操作是:

uint fixed_val = round(clamp(float_val, 0, +1) * 255.0);

为了正确打包每个组件,需要进行一些位移,但这些都是微不足道的。

关于opengl - 带字节的着色器存储缓冲区对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33098745/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com