我正在IOS上玩一些技巧来尝试构建CPU-GPU混合JPEG编码器。从我对CPU的测试中,我相信使用GPU进行DCT和量化步骤很有意义,并且应该显着提高性能(压缩大量的JPEG是我应用程序中的瓶颈)。通过转换反馈,这应该是可行的,因为我已经使用它来在GPGPU计算中获得很好的结果。棘手的部分是如何有效地获取数据(RGBA的无符号int8)。
如上所述,我曾经使用openGL ES 3.0进行GPGPU计算,所以我只有浮点纹理的经验,这是由
设置的glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F,WIDTH,HEIGHT,0,GL_RGBA,GL_GLOAT,data);
并通过
传递给着色器texelFetch()
但现在我的输入数据存储为无符号字节数组(或uint8),我需要每次按顺序提取64个字节。我想我可以将它们作为无符号字节的纹理获取,或者更有效地获取,作为无符号整数的纹理然后用位移来分隔它们。
我的问题是,我怎么做其中任何一个?更具体地说,我应该如何为glTexImage2D()设置 internalFormat ,格式和类型?我尝试了很多组合,但它们在着色器中只提供了0(我仔细检查了数据源它们是非零)。
答案 0 :(得分:0)
在ES 3中,请认真考虑创建像素解压缩缓冲区并对其进行映射,以获得制定像素数据的位置。这将至少保存一个驱动程序内部memcpy
,可以显着减少同步。请参阅GL_PIXEL_UNPACK_BUFFER
和glBindBuffer
上的gl[Un]MapBuffer[Range]
;你最终得到一个glTexImage2D(..., (void *)0);
来指定像素解包缓冲区作为源,类似于绑定缓冲区被指定为属性,元素等的源的方式。请参阅glFenceSync
进行同步假设你使用GL_MAP_UNSYNCHRONIZED_BIT
从而打算自己处理同步。
对于全整数RGBA(无缩放),使用GL_RGBA8UI
作为内部格式,GL_RGBA_INTEGER
作为格式,GL_UNSIGNED_BYTE
作为类型;然后声明usampler2d
('u'表示无符号,隐式整数)并使用标准texture(sampler, coordinate)
进行采样。
您还需要GL_CLAMP_TO_EDGE
和GL_NEAREST
纹理参数。
编辑:也有可能值得一提,来自usampler2d
的值属于uvec4
类型,因此它们是不可或缺的。与ES 2不同,ES 3具有真正的整数,包括按位运算符 - ES 2允许它们由浮点模拟(对于我们这些来自90年代的人来说,这确实是一个意想不到的未来)。因此,从我最近的仿真项目中得到的一个简单且足够微不足道的片段:
vec4 rgb_sample(usampler2D sampler, vec2 coordinate)
{
uint texValue = texture(sampler, coordinate).r;
return vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0);
}
当然,将TTL样式的RGB-in-one-byte单通道纹理打包为适合gl_FragColor
的格式(依赖饱和度)。