imageStore не пишет при использовании двух SSBO в вычислительном шейдере

Я заметил ошибку в одном из моих вычислительных шейдеров при попытке запустить его на моем ATI HD 5770.
Я обнаружил, что проблемы начинаются, когда я получаю доступ к более чем одному SSB в шейдере, несмотря на то, что GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS равно 8.

После некоторой возни я уменьшил проблемный шейдер до этого MWE:

#version 430
layout(local_size_x = 1) in;

buffer A { float a[]; };
buffer B { uint b[]; };
layout(r32i) uniform iimage2D outputImage;

void main() {
a[0] = -2;
b.length();
imageStore(outputImage, ivec2(gl_GlobalInvocationID.xy),
ivec4(a[0], 0, 0, 0));
}

Когда я запускаю этот шейдер как есть, я не вижу никаких изменений от imageStore,
При удалении b.length();Я получаю желаемый результат -2 на изображении.

Значение a[0] изменено на -2 в обоих случаях шейдер определенно работает.

Нет ошибок компиляции / компоновщика для шейдера в обоих случаях и glGetError также не возвращает ошибку.

Я что-то здесь не так делаю?

Это ошибка (драйвера)? В конце концов, этого не происходит на других моих (NVidia) картах.

Для полноты картины я использовал этот «минимальный» файл C ++ для запуска шейдера:

#include <cassert>
#include <QGuiApplication>
#include <QOpenGLShaderProgram>
#include <QOffscreenSurface>
#include <QOpenGLBuffer>
#include <QOpenGLContext>
#include <QOpenGLTexture>
#include <QOpenGLFunctions_4_3_Compatibility>
#include <vector>
#include <iostream>
#include <iterator>

int main(int argc, char* argv[]) {
QGuiApplication app(argc, argv);
QOffscreenSurface surface;
surface.create();

QOpenGLContext context;
context.create();
context.makeCurrent(&surface);

QOpenGLShaderProgram program;
program.addShaderFromSourceFile(QOpenGLShader::Compute, "shader.comp");
bool programIsLinked = program.link();
assert(programIsLinked);

QSize size(2, 2);

QOpenGLBuffer bufferA;
bufferA.create();
bufferA.bind();
std::vector<GLfloat> valuesOfBufferA(1, 2);
bufferA.allocate(&valuesOfBufferA.front(),
sizeof(valuesOfBufferA.front()) * valuesOfBufferA.size());
bufferA.release();

QOpenGLTexture texture(QOpenGLTexture::Target2D);
texture.create();
texture.setFormat(QOpenGLTexture::R32I);
texture.setSize(size.width(), size.height());
texture.bind();
texture.allocateStorage();
std::vector<GLint> data;
data.resize(size.width() * size.height(), -1);
texture.setData(QOpenGLTexture::Red_Integer, QOpenGLTexture::Int32,
data.data());
texture.release();

QOpenGLFunctions_4_3_Compatibility* qOGL =
context.versionFunctions<QOpenGLFunctions_4_3_Compatibility>();
qOGL->initializeOpenGLFunctions();

program.bind();

qOGL->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bufferA.bufferId());
qOGL->glBindImageTexture(0, texture.textureId(), 0, GL_FALSE, 0,
GL_WRITE_ONLY, texture.format());

qOGL->glDispatchCompute(size.width(), size.height(), 1);

qOGL->glMemoryBarrier(GL_ALL_BARRIER_BITS);
// for good measure :)
qOGL->glFinish();

data.clear();
data.resize(size.width() * size.height(), 0);
glBindTexture(GL_TEXTURE_2D, texture.textureId());
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_INT, data.data());
glBindTexture(GL_TEXTURE_2D, 0);

bufferA.bind();
bufferA.read(0, valuesOfBufferA.data(),
sizeof(valuesOfBufferA.front()) * valuesOfBufferA.size());
bufferA.release();

assert(GL_NO_ERROR == glGetError());

std::cout << valuesOfBufferA.front() << "\n";

std::copy(data.begin(), data.end(),
std::ostream_iterator<GLint>(std::cout, " "));
std::cout << "\n";
}

Обновить

Кажется, есть похожая проблема с imageLoad где он всегда возвращает 0 с использованием более 2 SSBO, 3 с использованием 2 SSBO и правильное значение для менее 2 SSBO. Обе проблемы возникают даже на самом новом драйвере (15,7, раньше был 15,5).

2

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]