Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Having trouble with imageBuffers

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    9

    Having trouble with imageBuffers

    I'm in the middle of implementing linked-list transparency, and so I wrote a simple test program as a proof of concept for using texture buffers. Unfortunately, I'm having trouble getting it to work properly.

    What the code is supposed to do is generate a 2D color gradient and display it on the screen. It does this with two separate shader invocations: in the first invocation, the fragment shader writes a color to the texture buffer that varies with gl_FragCoord.xy; the buffer location written to is gl_FragCoord.x + (gl_FragCoord.y * viewport_width). The second shader invocation merely reads from the same buffer and writes out to the framebuffer.

    What I end up seeing instead is a small, horizontal line of pixels at the bottom-left of the screen - only a tiny section at the beginning of the buffer is being properly written (or read?). Through some finagling with the shader code, I found that the line is 64 pixels long. If I try to read the buffer into main memory to inspect it, I end up with a region of memory containing some data that appears more or less random.

    I've been trying to figure out what's going wrong for quite a while now, so if anyone has encountered a similar problem before or has further suggestions for debugging, I'd be most grateful.

    System specs:
    Ubuntu Linux 11.04 64-bit
    Radeon HD 5450
    Catalyst v12.6



    This is the shader I am using. The first invocation writes the pixel rank to a bufferTexture object (w_buffer). That object is then bound to r_buffer, and the second invocation reads from it and draws those pixels to the screen.

    #version 420

    #include <gtest/SmallImage.h>


    layout(binding = SMALL_IMAGE_READ_UNIT, rgba8) readonly uniform image2D r_image;

    layout(binding = SMALL_IMAGE_WRITE_UNIT, rgba8) writeonly uniform image2D w_image;


    layout(binding = SMALL_BUFFER_READ_UNIT, rgba8) readonly uniform imageBuffer r_buffer;

    layout(binding = SMALL_BUFFER_WRITE_UNIT, rgba8) writeonly uniform imageBuffer w_buffer;


    subroutine void actual_main(void);
    subroutine uniform actual_main exec;

    subroutine vec4 imageReader(ivec2 coords);
    subroutine uniform imageReader imRd;

    subroutine void imageWriter(ivec2 coords, vec4 value);
    subroutine uniform imageWriter imWt;

    uniform uint viewport_height;
    uniform uint viewport_width;


    //NOTE: bottom-left pixel is at (0,0)
    layout(pixel_center_integer) in vec4 gl_FragCoord;


    smooth in vec2 texture_coords;
    out vec4 out_color;

    /*
    * Subroutines that abstract image acess away from buffer/2d format
    */

    //image2d
    subroutine(imageReader) vec4 read2D(ivec2 coords)
    {
    return imageLoad(r_image, coords);
    }

    subroutine(imageWriter) void write2D(ivec2 coords, vec4 color)
    {
    imageStore(w_image, coords, color);
    }


    //buffers
    int pixelToBufferCoords(ivec2 coords)
    {
    return coords.x + (coords.y * int(viewport_width));
    }

    subroutine(imageReader) vec4 readBuffer(ivec2 coords)
    {
    return imageLoad(r_buffer, pixelToBufferCoords(coords));
    }

    subroutine(imageWriter) void writeBuffer(ivec2 coords, vec4 color)
    {
    imageStore(w_buffer, pixelToBufferCoords(coords), color);
    }



    /*
    * Subroutines set for test functionality
    */
    subroutine(actual_main) void loadImageOrigin(void)
    {
    vec4 loaded = imRd(ivec2(int(gl_FragCoord.x),
    int(gl_FragCoord.y)));
    out_color = vec4(1.0,0.0,0.0,1.0);/*loaded.r,
    loaded.g,
    gl_FragCoord.y/1200.0,
    1);*/
    }


    subroutine(actual_main) void pixelRank(void)
    {
    vec4 color = vec4(0.0f, 0.0f, 0.0f, 1.0f);
    color.r = gl_FragCoord.x/viewport_width);
    color.b = gl_FragCoord.y/viewport_height);
    color.g = 1.0f;
    imWt(ivec2(int(gl_FragCoord.x),
    int(gl_FragCoord.y)),
    color);
    }

    subroutine(actual_main) void readPixels(void)
    {
    vec4 loaded = imRd(ivec2(int(gl_FragCoord.x),
    int(gl_FragCoord.y)));
    out_color = vec4(loaded.r,
    loaded.g,
    loaded.b,
    1.0);
    }


    void main(void)
    {
    exec();
    }


    This is my draw-loop. ReportGLErrors is just a macro that records any openGLerrors to disk.

    WHILE_YNTEST(handler,nameWriter)
    {
    float64 time = (float64) timer.GetTime();

    rend->InitFrame(time);

    /*
    * Refresh the texture if the viewport has changed size
    */
    Height h = getViewportHeight();
    Width w = getViewportWidth();
    if(4*h.value*w.value != my_buff->getSize()) {
    my_buff = GLBufferTexturePtr(vms_new GLBufferTexture(GL_RGBA8,
    4*w.value*h.value));
    lfReportGLerrors(&error);

    my_buff->initialize();
    lfReportGLerrors(&error);
    }

    /*
    * To each pixel, write a color based on pixel rank
    */
    my_buff->bindToImageUnit(SMALL_BUFFER_WRITE_UNIT, GL_WRITE_ONLY);
    lfReportGLerrors(&error);

    sits->setSub("pixelRank");
    lfReportGLerrors(&error);
    sits->renderWrapper(fullscreen_quad, ctx, time);
    lfReportGLerrors(&error);

    /*
    * Now show the image
    */
    my_buff->bindToImageUnit(SMALL_BUFFER_READ_UNIT, GL_READ_ONLY);

    sits->setSub("readPixels");
    lfReportGLerrors(&error);
    sits->renderWrapper(fullscreen_quad, ctx, time);
    lfReportGLerrors(&error);

    rend->EndFrame(time);

    //cap framerate at 100fps
    boost::this_thread::sleep(boost:osix_time::milliseconds(10));
    }

  2. #2
    Junior Member Newbie
    Join Date
    May 2009
    Posts
    13
    just out of curiosity, do u set viewport_width uniform?

  3. #3
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    9
    Quote Originally Posted by xahir View Post
    just out of curiosity, do u set viewport_width uniform?
    Yup. And I know that it's the correct value, because when I set the imageRead/Write subroutines to use an image2D instead of an imageBuffer, I get a smooth gradient along the X-axis that goes from no red to all red.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •