Texture Deletion Race Condition

Started by
6 comments, last by Geometrian 9 years, 11 months ago

Hi,

I built a small demo using the Kinect for PC that simply reconstructs 3D position and color. Time was short, and the simplest solution just took the raw client-side data and copied it into a new texture for every frame.

The way this worked in the main loop was as follows:


--Grab new data from Kinect (client-side bytes)

--Allocate new OpenGL textures and glTexImage2D the new data into them

--glFlush and glFinish all the things (just in case)

--Draw the frame using the new textures (vertex shader sorcery)

--glFlush and glFinish all the things (just in case)

--Flip buffers

--glFlush and glFinish all the things (just in case) (again)

--Delete the new textures (and delete the client side data)


The above was my debugging attempt, and it's obviously redundant with all its flushes/finishes. Even with this code, however, I would get an error where the texture would essentially not exist every n ~= 15 frames. It would just appear black.

My workaround at the time was to just queue the last 10 frames for deletion (so each frame it would delete the texture used 10 frames ago). This "fixed" the problem. However, I want to know why the original issue occurred. Some thoughts/notes:

--I want to say it's not because the client-side data is being deleted before being copied into the texture; the client side data was deleted at the end of a frame, after the object has been drawn. The flushes everywhere and the buffer flipping should prevent it being a pipelining issue. However, I can't think of what else it could be.

--It's not some compiler reordering breaking it. Without optimizations, the problem still occurred.

--The draw-the-frame step actually draws different views into three separate windows, with a shared OpenGL context. The issue only seemed to affect one window at a time, which I found odd.

--The issue was not data from the Kinect being broken. This is evidenced by, among other things, queueing for deletion fixing the problem. Also, the Kinect copies its data into a client-side array which is reused, but this array is copied into a freshly-allocated client-side array associated with each texture. When the new OpenGL texture is created, the data is pulled from this newly-allocated array, which persists for the length of the frame and until the texture is deleted.

--My drivers are up-to-date; the GPU is NVIDIA GeForce 580M.


I feel like it's some driver-related pipelining issue related to texture upload, but I'm not completely sure. Ideas?

Thanks,
-G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Advertisement

Hmmm... are you using a PBO to hold the texture data ? In this case calling glTexImage2D could result in an asynchronous DMA transfer. I'm not sure if the DMA transfer is part of the command pipeline (->glFlush/glFinish).

Nope. As I wrote, time was short. PBOs aren't used.

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

My money is on some stupid mistake (not judging, everyone makes them!). Calling glDeleteBuffers when I meant glDeleteTextures created some pretty subtle issues in my engine recently, it's probably something along those lines.

why are you reallocating/deleting textures? Can't you just issue glteximage2d writes to the same texture over and over? This writing would create a lock and stall on gpu, that should get you safe.

from your loop there is iimmediate issueing of those instructions (as you concepted it) :

-Delete the new textures (and delete the client side data)

done properly I gess, deleting CPU pointer of a tex resource issues whole reorganizing on GPU , but followed straight by a:

-Grab new data from Kinect (client-side bytes)

ok some cpu job during gpu heavily freeing a big resource, but followed straight by a

-Allocate new OpenGL textures and glTexImage2D the new data into them

this is such a "rape" for gpu it may overact due to some handling of heavy corruption like issues. Driver is freeing a resource while requested allocating a resource and writing to the resource right after another, what may very break some of its managment and optimization policy.

I found a silly bug related to the way I was handling mipmapping, but I have no evidence the problems were related.

The deletion/reallocation was mainly for simplicity. I understood then as now that it's generally a bad approach--but I was still expecting it to be correct.

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

no, never debug absolutely terrible (impossible) driver usage. Especialy on highly optimized restriction-policy forcing platforms such as consoles are.

I'd expect to be able to allocate and delete textures when I choose. It's pretty simple stuff. Even if I'm doing it frequently, this shouldn't affect whether it works. I feel like that's a pretty reasonable expectation.

Note: I was using a development version of the Kinect 1, that allows writing in C++ on a PC, not a console.

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

This topic is closed to new replies.

Advertisement