首页 > 解决方案 > 无法使用特定索引(Android11、Pixel3)进行 imageLoad()

问题描述

我遇到了一个问题,我无法在“imageBuffer”的特定地址读取值。

一个数组有粒子位置,第一个和第二个元素有一个数组的长度,如果我尝试使用数组长度的第一个元素,它总是为零,以下返回。

int total_particle = int(imageLoad(particle_pos_in, 0).x);

这是 imageBuffer 的输入。

glUseProgram(h_Shader_Program[Shader_Program_PARTICLE_MOVE]);

// PCA Image2D
glBindImageTexture(ToInt(COMPUTE_FACE_TEXTURE::OBSTACLE_IN),
                   startexture->texture[TEXTURES_TBO_OBSTACLE_POSITION_IN].texture_id, 0, false, 0, GL_READ_ONLY, GL_RGBA32F);
glBindImageTexture(ToInt(COMPUTE_FACE_TEXTURE::PARTICLE_POWER_IN),
                   startexture->texture[TEXTURES_TBO_PARTICLE_POWER_IN].texture_id, 0, false, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(ToInt(COMPUTE_FACE_TEXTURE::PARTICLE_POSITION_IN),
                   startexture->texture[TEXTURES_TBO_PARTICLE_POSITION_IN].texture_id, 0, false, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(ToInt(COMPUTE_FACE_TEXTURE::PARTICLE_POSITION_OUT),
                   startexture->texture[TEXTURES_TBO_PARTICLE_POSITION_OUT].texture_id, 0, false, 0, GL_WRITE_ONLY, GL_RGBA32F);
starfbo->bindVBO(GL_TEXTURE_BUFFER_EXT, VBO_COMPUTE_PARTICLE_POSITION_IN);

float *cs_shader_particle_position_in = (float *) glMapBufferRange(GL_TEXTURE_BUFFER_EXT,
                                        0,
                                        sizeof(float) * particle_position.size()
                                                          * 2 /*xy*/,
                                        GL_MAP_WRITE_BIT);


cs_shader_particle_position_in[0] = 
cs_shader_particle_position_in[1] = particle_position.size();

for(int idx=1; idx <= particle_position.size(); idx++) {
    cs_shader_particle_position_in[idx*2+0] = particle_position[idx-1].x;
    cs_shader_particle_position_in[idx*2+1] = particle_position[idx-1].y;
}
glUnmapBuffer(GL_TEXTURE_BUFFER_EXT);

计算我可以读取第一个索引的着色器。

layout(local_size_x = 100) in; // If I use x=1 y=1 z=1 work group size, it works properly.
layout(binding=0, rgba32f) uniform highp readonly imageBuffer obs_pos_in;
layout(binding=1, r32f) uniform highp readonly imageBuffer power_in;
layout(binding=2, r32f) uniform highp readonly imageBuffer particle_pos_in;
layout(binding=3, rgba32f) uniform highp writeonly imageBuffer position_out;

.....
int tid = int(gl_GlobalInvocationID.x);

int total_particle = int(imageLoad(particle_pos_in, 0).x);
** this total_particle seems always 0**

for(int idx=1; idx <= total_particle; idx++) {
    vec2 particle_pos = vec2(imageLoad(particle_pos_in, int(idx*2 +0)).x,
                             imageLoad(particle_pos_in, int(idx*2 +1)).x);

    // some calculation here using particle_pos
}
.....

//final output
imageStore(position_out, int(tid), vec4(position.x, position.y, power.x, power.y));

glDispatchCompute(TOTAL_PARTICLE/100, 1, 1);
glMemoryBarrier(....) 

//use(copy) the output here for

您可以假设 TOTAL_PARTICLE 为 100K,因此有1000 个工作组,每个工作组有 100 次调用。

也许我应该确保我访问的地址,但这个地址永远不会写在这里,也不会写在其他调用中。

注意

  1. 如果我使用 1 个大小的工作组(x=1,y=1 和 z=1),它工作正常

  2. 而不是第一个元素,使用统一的 vec4 可以正常工作。

  3. 上面的代码适用于大多数设备(10+ Android 设备),但是,Android11 的设备(Pixel3)(Android10 很好)。

  4. 这是一个测试代码,我有很多计算着色器程序,但只有使用 const integer index 访问 imageBuffer 才会在设备上出现问题。

标签: androidopengl-escompute-shaderopengl-es-3.1

解决方案


推荐阅读