Adreno OpenGL ES 3.1 介绍(7)

175 篇文章 26 订阅
43 篇文章 6 订阅

4.2.3.3 设置图像

到目前为止,已经讨论了该示例如何使用计算着色器。本节将仔细研究图像单元和图像uniform 的配置方式。 回忆一下,着色器调用使用它们来存储其结果值。

与之前的示例一样,资源在第一次渲染时通过负责渲染帧的函数_rendering_handler进行初始化。这是设置图像uniform的方法:

    glGenTextures(1, &_texture);
    glBindTexture (GL_TEXTURE_2D, _texture);
    glTexStorage2D(GL_TEXTURE_2D,1, /* levels */ GL_RGBA8,
        rendertarget_width,
        rendertarget_height);
    /* Set up image bindings */
    glBindImageTexture(0, /* index */
        _texture,
        0, /* level */
        GL_FALSE, /* layered */
        0, /* layer */
        GL_WRITE_ONLY,
        GL_RGBA8);
    /* Point the image uniform at the new binding */
    glUseProgram(_program); 
    glUniform1i(_program_image_uniform_location,0); /* unit */

首先设置一个不变的纹理来保存将由计算着色器生成的数据。 仅需要基本的mipmap级别。 这将用作blit操作的读取缓冲区。

然后,调用glBindImageTexture将纹理对象绑定到索引为0的图像单元。图像的工作方式与纹理对象非常相似。 对于纹理,在着色器中对mipmap采样之前,请将纹理对象绑定到纹理单元之一,然后将采样器uniform设置为指向该纹理单元。 对于图像,该过程是类似的,并且glBindImageTexture的作用等同于glBindTexture。 唯一的区别是glBindImageTexture需要提供有关mipmap(或mipmap集)的更多详细信息(对于2D数组纹理等分层纹理目标),并提供有关使用图像的预期方式的提示。 上面的代码片段的最后一部分激活了一个程序对象,并配置了图像uniform以指向纹理图像单元0,该单元与glBindImageTexture调用所使用的纹理单元相同。

注意:此处并非必须调用glUniform1i,因为OpenGL ES着色器语言中所有图像uniform的默认设置为0,但是最好将其包括在内,因为忘记配置纹理采样器或图像uniform是一个难题。 频繁的编程错误。
4.2.3.4 渲染帧画面

一旦所有OpenGL ES对象都已初始化,则渲染帧的内容。 首先,将新的时间值分配给其中一个计算着色器uniform。 然后,调度计算作业:

    glUseProgram(_program); 
    glUniform1f(_program_time_uniform_location,
        float(current_time_msec) / 1000.0f);
    glDispatchCompute(_global_workgroup_size[0],
        _global_workgroup_size[1],
        1); /* num_groups_z */

重要的是要记住,OpenGL ES以异步方式工作。 这在图像的上下文中尤其重要,它允许着色器修改外部实体,例如纹理数据存储。 OpenGL ES不会自动将此类着色器更新与可能对同一对象进行的其他访问同步(对于OpenGL ES这样做会引入大量开销,这可能会严重影响性能)。 因此,在访问可能已从着色器内部修改的任何类型的存储时,请使用适当的同步方法。

在示例中,打算在帧缓冲区blit操作中使用计算作业的结果。 blit是启动计算作业之后代码中的下一步。 如果没有适当的同步,则blit操作可能会在从计算着色器完成对缓冲区更新的更新之前尝试从缓冲区读取。为了序列化这些操作,请发出以下调用:

glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

内存屏障可确保OpenGL ES将刷新硬件可能已用于图像存储操作的所有缓存,如果这些缓存可能影响后续的帧缓冲区操作。

最后一步是发出帧缓冲区blit,以将纹理内容传输到后缓冲区,如先前的示例中所做的那样:

glBlitFramebuffer(0, /* srcX0 */
    0, /* srcY0 */
    rendertarget_width,
    rendertarget_height,
    0, /* dstX0 */ 
    0, /* dstY0 */
    rendertarget_width,
    rendertarget_height,
    GL_COLOR_BUFFER_BIT,
    GL_NEAREST); /* filter */

4.3 对OpenGL ES实施

本节详细介绍了OpenGL ES 3.1上下文中Adreno体系结构的功能。

4.3.2 GL常量值

表 4-1 OpenGL ES 3.1 - GL_MAX 常量值
PnameAdreno 330Adreno 420
GL_MAX_3D_TEXTURE_SIZE819216384
GL_MAX_ARRAY_TEXTURE_LAYERS5122048
GL_MAX_COLOR_ATTACHMENTS48
GL_MAX_COMBINED_ATOMIC_COUNTERS048
GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS0230400
GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS230272230272
GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS024
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS3296
GL_MAX_COMBINED_UNIFORM_BLOCKS2884
GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS230400230400
GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS08
GL_MAX_COMPUTE_ATOMIC_COUNTERS08
GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS024
GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS016
GL_MAX_COMPUTE_UNIFORM_BLOCKS014
GL_MAX_COMPUTE_UNIFORM_COMPONENTS01024
GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS01024
GL_MAX_COMPUTE_WORK_GROUP_COUNT065535
GL_MAX_VIEWPORT_DIMS819216384

在这里插入图片描述

表 4-2 OpenGL ES 3.1中其他GL常量值
PnameAdreno 330Adreno 420
GL_ALIASED_LINE_WIDTH_RANGE11
GL_ALIASED_POINT_SIZE_RANGE11
GL_MIN_PROGRAM_TEXEL_OFFSET-8-8
GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT04
GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT3232
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值