1

我在 IOS 上玩一些技巧来尝试构建一个 CPU-GPU-hybrid JPEG 编码器。从我对 CPU 的测试来看,我相信使用 GPU 来执行 DCT 和量化步骤很有意义,并且应该会显着提高性能(压缩大量 JPEG 是我应用程序的瓶颈)。有了变换反馈,这应该是可行的,因为我已经用它在 GPGPU 计算中获得了很好的结果。棘手的部分是如何有效地获取数据(RGBA 的无符号整数)。

如前所述,我曾经使用 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(我仔细检查了数据源,它们不是零)。

4

1 回答 1

0

在 ES 3 中,认真考虑创建一个像素解包缓冲区并对其进行映射,以便获得一个位置来制定您的像素数据。这至少会节省驱动程序内部memcpy,并且可以显着用于减少同步。参见和;GL_PIXEL_UNPACK_BUFFER_ 您最终将使用 a将像素解包缓冲区指定为源,类似于将绑定缓冲区指定为属性、元素等的源的方式。请参阅同步假设您使用并因此打算自己处理同步。glBindBuffergl[Un]MapBuffer[Range]glTexImage2D(..., (void *)0);glFenceSyncGL_MAP_UNSYNCHRONIZED_BIT

对于全整数 RGBA(无缩放)GL_RGBA8UI,用作内部格式、GL_RGBA_INTEGER格式、GL_UNSIGNED_BYTE类型;然后声明一个usampler2d('u' 表示无符号,隐式整数)并使用标准texture(sampler, coordinate)进行采样。

您还需要GL_CLAMP_TO_EDGEGL_NEAREST纹理参数。

编辑:也可能值得一提的是,来自 a 的值usampler2d是 type 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 单字节单通道纹理解压缩为适合的格式gl_FragColor(依赖于饱和度)。

于 2016-04-08T13:07:06.400 回答