Gabriel Ribeiro
Gabriel Ribeiro

Reputation: 1

Problem Writing to an Image Texture Using a Compute Shader

I'm building a sparse voxel octree game engine and I'm having problems writing in a compute shader. I simplified my algorithm because I only need to write to the texture. Here is what I tried:

Preparing/Sending texture data to GPU:

import numpy as np
from OpenGL.GL import *
from test_frame import Test
class ComputeShader:
    def __init__(self, app, data):
        self.app = app
        self.program = app.shader_program.programs['svo_comp'][0] 
        self.data = data
        self.output = Test(np.zeros(data.shape[0], dtype='uint32'), 0)
        self.true = False
        


    def update(self, uniforms=None):
        x_num_groups, y_num_groups, z_num_groups = (self.data.shape[0] + 255) // 256, 1, 1
        
        glUseProgram(self.program)

        self.output.bind_as_image()
        if uniforms:
            for mesh_uniform in uniforms:
                mesh_uniform.uploadData()
        
        glDispatchCompute(x_num_groups, y_num_groups, z_num_groups)
        error = glGetError()
        if error != GL_NO_ERROR:
            print(f"OpenGL Error: {error}")
        glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)    
        if not self.true:
    
            self.output.get_data()
            self.true = True

        self.output.unbind_as_image()

Here we use the Test class, which is a simplified version of my texture class:

from OpenGL.GL import *
import numpy as np
class Test:
    def __init__(self, data, binding):
        self.textRef = glGenTextures(1)
        self.data = data
        self.binding = binding
        glBindTexture(GL_TEXTURE_1D, self.textRef)
        glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, data.shape[0], 0,  GL_RED_INTEGER, GL_UNSIGNED_INT, data)
        
        glBindTexture(GL_TEXTURE_1D, 0)
    
    
    def bind_as_image(self):
        glBindTexture(GL_TEXTURE_1D, self.textRef)
        glBindImageTexture(self.binding, self.textRef, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI)
    
    def unbind_as_image(self):
        glBindImageTexture(self.binding, 0, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI)

    def get_data(self):
        glBindTexture(GL_TEXTURE_1D, self.textRef)
        buffer = np.zeros(self.data.shape[0], dtype='uint32')
        glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, buffer)
        glBindTexture(GL_TEXTURE_1D, 0)
        print(f'write output: {buffer}')
        return buffer

Finally, this is the compute shader:

#version 450
layout (local_size_x = 256) in;
layout(r32ui, binding = 0) uniform writeonly uimage1D debug;

void main(){
        uint index = gl_GlobalInvocationID.x;
        uvec4 value = uvec4(index, 0, 0, 0);
        imageStore(debug, int(index), value);

       
} 

Note that in the Test class, there is a print statement for the data extraction that was supposed to show the index of the array, but it retrieves an array full of zeros:

write output: [0 0 0 ... 0 0 0]

Upvotes: 0

Views: 53

Answers (0)

Related Questions