在openGL ES 3.0

时间:2016-04-08 09:40:42

标签: opengl-es opengl-es-3.0

我正在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(我仔细检查了数据源它们是非零)。

1 个答案:

答案 0 :(得分:0)

在ES 3中,请认真考虑创建像素解压缩缓冲区并对其进行映射,以获得制定像素数据的位置。这将至少保存一个驱动程序内部memcpy,可以显着减少同步。请参阅GL_PIXEL_UNPACK_BUFFERglBindBuffer上的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_EDGEGL_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的格式(依赖饱和度)。