0

我在使用 OpenGL 缓冲区时遇到了一些奇怪的困难。我试图将问题缩小到最少的源代码,所以我创建了在每次迭代中递增 FloatBuffer 的每个数字的程序。当我向 FloatBuffer 添加少于 2^16 个浮点数时,一切正常,但是当我添加 >= 2^16 个数字时,这些数字不会增加,并且在每次迭代中都保持不变。

渲染器:

public class Renderer extends AbstractRenderer {
    int computeShaderProgram;
    int[] locBuffer = new int[2];
    FloatBuffer data;
    int numbersCount = 65_536, round = 0; // 65_535 - OK, 65_536 - wrong

    @Override
    public void init() {
        computeShaderProgram = ShaderUtils.loadProgram(null, null, null, null, null,
                "/main/computeBuffer");
        glGenBuffers(locBuffer);
        // dataSizeInBytes = count of numbers to sort * (float=4B + padding=3*4B)
        int dataSizeInBytes = numbersCount * (1 + 3) * 4;

        data = ByteBuffer.allocateDirect(dataSizeInBytes)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        initBuffer();
        printBuffer(data);

        glBindBuffer(GL_SHADER_STORAGE_BUFFER, locBuffer[0]);
        glBufferData(GL_SHADER_STORAGE_BUFFER, data, GL_DYNAMIC_DRAW);
        glShaderStorageBlockBinding(computeShaderProgram, 0, 0);

        glViewport(0, 0, width, height);
    }

    private void initBuffer() {
        data.rewind();
        Random r = new Random();
        for (int i = 0; i < numbersCount; i++) {
            data.put(i*4,  r.nextFloat());
        }
    }

    @Override
    public void display() {
        if (round < 5) {
            glUseProgram(computeShaderProgram);
            glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, locBuffer[0]);
            glDispatchCompute(numbersCount, 1, 1);
            glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
            glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, data);
            printBuffer(data);
            round++;
        }
    }

    ...
}

计算缓冲区

#version 430
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_storage_buffer_object : enable

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(binding = 0) buffer Input {
    float elements[];
}input_data;

void main () {
    input_data.elements[gl_WorkGroupID.x ] = input_data.elements[gl_WorkGroupID.x] + 1;
}
4

1 回答 1

1
glDispatchCompute(numbersCount, 1, 1);

You must not dispatch a compute shader workgroup count exceeding the corresponding GL_MAX_GL_MAX_COMPUTE_WORK_GROUP_COUNT for each dimension. The spec guarantees that limit to be at least 65535, so it is very likely that you just exceed the limit on your implementation. Actually, you should be getting a GL_INVALID_VALUE error for that call, and you should really consider using a debug context and debug message callback to have such obvious errors easily spotted during development.

于 2020-05-14T20:27:03.643 回答