Nano Hash - криптовалюты, майнинг, программирование

OpenGL imageSize всегда равен нулю

Я написал простой тестовый пример, чтобы получить высоту изображения в вычислительном шейдере и записать ее в SSBO. Я использовал код SSBO раньше и знаю эта часть работает нормально. Я использовал apitrace для проверки состояния во время вызова glDispatchCompute и вижу как исходную текстуру, так и изображение, привязанное к правильному блоку изображения. Однако imageSize всегда возвращает ноль (на выходе все нули, за исключением некоторых оставшихся -1 в конце, потому что деление с размером рабочей группы округляется в меньшую сторону). Ошибки OpenGL не выдаются.

Я основал этот тестовый пример на одном из моих предыдущих вопросов, который включал код для привязки SSBO к вычислительному шейдеру (здесь я использую его для получения отладочного вывода из вычислительного шейдера).

class ComputeShaderWindow : public QOpenGLWindow {
  public:
    void initializeGL() {
        // Create the opengl functions object
        gl = context()->versionFunctions<QOpenGLFunctions_4_3_Core>();
        m_compute_program = new QOpenGLShaderProgram(this);
        auto compute_shader_s = fs::readFile(
                                    "test_assets/example_compute_shader.comp");
        QImage img("test_assets/input/out.png");
        // Adds the compute shader, then links and binds it
        m_compute_program->addShaderFromSourceCode(QOpenGLShader::Compute,
                compute_shader_s);
        m_compute_program->link();
        m_compute_program->bind();

        GLuint frame;

        // Create the texture
        gl->glGenTextures(1, &frame);

        // Bind the texture
        gl->glBindTexture(GL_TEXTURE_2D, frame);

        // Fill the texture with the image
        gl->glTexImage2D(GL_TEXTURE_2D,
                         0,
                         GL_RGB8,
                         img.width(),
                         img.height(),
                         0,
                         GL_BGRA,
                         GL_UNSIGNED_BYTE,
                         img.bits());
        GLuint image_unit = 1;
        // Get the location of the image uniform
        GLuint uniform_location = gl->glGetUniformLocation(
                                      m_compute_program->programId(),
                                      "video_frame");
        // Set location to 0 (a unique value that we choose)
        gl->glUniform1i(uniform_location, image_unit);
        // Bind layer of texture to image unit
        gl->glBindImageTexture(image_unit,
                               frame,
                               0,
                               GL_FALSE,
                               0,
                               GL_READ_ONLY,
                               GL_RGBA8UI);
        // We should only need the bit for shader image access,
        // but for the purpose of this example, I set all the bits
        // just to be safe
        gl->glMemoryBarrier(GL_ALL_BARRIER_BITS);

        // SSBO stuff to get output from the shader
        GLfloat* default_values = new GLfloat[NUM_INVOCATIONS];
        std::fill(default_values, default_values + NUM_INVOCATIONS, -1.0);
        GLuint ssbo;
        gl->glGenBuffers(1, &ssbo);
        gl->glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
        gl->glBufferData(GL_SHADER_STORAGE_BUFFER,
                         NUM_INVOCATIONS * sizeof(float),
                         &default_values[0],
                         GL_STATIC_DRAW);
        gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
        gl->glDispatchCompute(NUM_INVOCATIONS / WORKGROUP_SIZE, 1, 1);
        gl->glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
        gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);

        // Now read from the buffer so that we can check its values
        GLfloat* read_data = (GLfloat*) gl->glMapBuffer(GL_SHADER_STORAGE_BUFFER,
                             GL_READ_ONLY);
        std::vector<GLfloat> buffer_data(NUM_INVOCATIONS);

        // Read from buffer
        for (int i = 0; i < NUM_INVOCATIONS; i++) {
            DEBUG(read_data[i]);
        }
        DEBUG("Done!");

        gl->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
        assert(gl->glGetError() == GL_NO_ERROR);
    }

    void resizeGL(int width, int height) {

    }

    void paintGL() {

    }

    void teardownGL() {

    }

  private:
    QOpenGLFunctions_4_3_Core* gl;
    QOpenGLShaderProgram* m_compute_program;
    static constexpr int NUM_INVOCATIONS = 9000;
    static constexpr int WORKGROUP_SIZE = 128;
};

Что касается вычислительного шейдера:

#version 430 core

layout(local_size_x = 128) in;

layout(rgba8ui, binding = 1) readonly uniform uimage2D video_frame;

layout(std430, binding = 0) writeonly buffer SSBO {
    float data[];
};

void main() {
    uint ident = int(gl_GlobalInvocationID);
    uint num_workgroups = int(gl_WorkGroupID);
    // Write the height of the image into the buffer
    data[ident] = float(imageSize(video_frame).y);
}

Ответы:


1

Оказывается, я забыл параметры текстуры:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Не знаю, почему это прерывает вызовы imageSize().

27.07.2016
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..