<div dir="ltr">Hello list,<div><br></div><div>after about 3 days of debugging, I was able to isolate a rather weird behavior in Mesa GL.</div><div>The gist of it is the following: When I create a buffer object and allocate uninitilaized</div>
<div>memory for it (glBufferData() with nullptr as 'data'), then glCopyBufferSubData() data into</div><div>it from another buffer object, then subsequently fill a part of it with glBufferSubData(),</div><div>this new data isn't visible to the buffer object. In fact, it seems that the SubData'ed bytes</div>
<div>are completely lost. Any further data uploads however work as expected. I will attach</div><div>a small C test case below that demonstrates this behavior.</div><div><br></div><div>I realize that I am working with an old Mesa release (on Fedora 19), but I'm afraid of</div>
<div>upgrading my system to the newest distro release as I might break my working environment.</div><div>That's why I would like to kindly ask if someone could verify that this problem still persists</div><div>on the newest Mesa code, in which case I would go ahead and file a bug report. At the</div>
<div>same time, maybe someone could spot a critical mistake in my code that would explain</div><div>this strange behavior I'm seeing. I think the code paths I'm hitting here in the driver are</div><div>sufficiently obscure though.</div>
<div><br></div><div>I should probably mention that my card is a Mobility Radeon HD 3650 (ie. r600).</div><div><br></div><div>Here's the code sample (you can replace the GL setup code with your own):</div><div><br></div>
<div><div>#include <stdlib.h></div><div>#include <string.h></div><div> </div><div>#include <GL/glew.h></div><div>#include <SDL2/SDL.h></div><div> </div><div>static SDL_Window *win;</div><div>static SDL_GLContext *ctx;</div>
<div> </div><div>void setupGL()</div><div>{</div><div> SDL_Init(SDL_INIT_VIDEO);</div><div> win = SDL_CreateWindow("CopyBufferBug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 64, 64, SDL_WINDOW_OPENGL);</div>
<div> ctx = SDL_GL_CreateContext(win);</div><div> glewInit();</div><div>}</div><div> </div><div>static void teardownGL()</div><div>{</div><div> SDL_GL_DeleteContext(ctx);</div><div> SDL_DestroyWindow(win);</div>
<div> </div><div> SDL_Quit();</div><div>}</div><div> </div><div>int main(int argc, char *argv[])</div><div>{</div><div> setupGL();</div><div> </div><div> /* These don't matter I think */</div><div>
#define BLOCK_SIZE 128</div><div> #define BUFFER1_SIZE BLOCK_SIZE</div><div> #define BUFFER2_SIZE BLOCK_SIZE</div><div> #define BUFFER1_TARGET GL_COPY_READ_BUFFER</div><div> #define BUFFER2_TARGET GL_COPY_WRITE_BUFFER</div>
<div> #define BUFFER1_USAGE GL_DYNAMIC_DRAW</div><div> #define BUFFER2_USAGE GL_DYNAMIC_DRAW</div><div> </div><div> GLuint buffers[2];</div><div> glGenBuffers(2, buffers);</div><div> </div><div>
/* We allocate both buffers with undefined memory */</div><div> glBindBuffer(BUFFER1_TARGET, buffers[0]);</div><div> glBufferData(BUFFER1_TARGET, BUFFER1_SIZE, 0, BUFFER1_USAGE);</div><div> </div><div>
glBindBuffer(BUFFER2_TARGET, buffers[1]);</div><div> glBufferData(BUFFER2_TARGET, BUFFER2_SIZE, 0, BUFFER2_USAGE);</div><div> </div><div> /* Then copy (undefined) bytes from the first into the second buffer */</div>
<div> /* Note: If I comment this line out, everything works */</div><div> glCopyBufferSubData(BUFFER1_TARGET, BUFFER2_TARGET, 0, 0, BUFFER1_SIZE);</div><div> </div><div> /* Generate random string */</div>
<div> FILE *rand = fopen("/dev/urandom", "r");</div><div> char data[BLOCK_SIZE];</div><div> fread(data, 1, sizeof(data), rand);</div><div> fclose(rand);</div><div> </div><div>
/* We fill the second buffer with defined data */</div><div> /* Note: If I execute this call twice (just copy paste the line), everything works */</div><div> glBufferSubData(BUFFER2_TARGET, 0, sizeof(data), data);</div>
<div> </div><div> /* Then download it again to compare its contents against our test string */</div><div> char data2[BLOCK_SIZE];</div><div> glGetBufferSubData(BUFFER2_TARGET, 0, sizeof(data2), data2);</div>
<div> </div><div> if (memcmp(data, data2, sizeof(data)))</div><div> printf("Data does NOT match up!\n");</div><div> else</div><div> printf("Data matches.\n");</div>
<div> </div><div> glDeleteBuffers(2, buffers);</div><div> </div><div> teardownGL();</div><div> </div><div> return 0;</div><div>}</div></div><div><br></div><div>Thank you very much for your time.</div>
<div>Jonas</div></div>