http://bugs.winehq.org/show_bug.cgi?id=11584
--- Comment #72 from Stefan Dösinger stefandoesinger@gmx.at 2008-06-08 08:24:44 --- I looked a bit at the code, and tried to find a reason for the failure when Vitaliy tried to revert the patch. The situation the reverting causes is that IWineD3DTexture::PreLoad is called without an existing texture.
PreLoad calls BindTexture, which finds that no texture exists. It creates a gl texture and calls SetGlTextureDesc on the surface.
SetGlTextureDesc calls ModifyLocation(INTEXTURE, FALSE), which is correct. This makes sure the texture location is reloaded when something else asks to load it.
SetGlTextureDesc calls AddDirtyRect, supposdately to set the dirty rectangle. AddDirtyRect calls ModifyLocation(INSYSMEM, TRUE). This will make PreLoad load the surface from the sysmem copy, rather than the drawable. Not good. I think the AddDirtyRect call in this case is wrong, and a leftover from older times.
SetGlTextureDesc updates the texture addressing flags(GL_TEXTURE_RECTANGLE_ARB vs normal textures), removes the gl-texture-is-allocated flag. All OK here.
Back to PreLoad: The palettized change returns FALSE - palettized surfaces aren't renderable. Let's assume no sRGB change for now, to keep the matter simple. I *think* that an sRGB change works out correctly as well, once this bug is fixed. I am not even sure if I can construct a situation where an sRGB flag change occurs the first time the texture is loaded...
Surface::LoadTexture is called. It does color keying checks and then calls LoadLocation(INTEXTURE).
LoadLocation should run into the read_from_framebuffer call because the most up to date location is the drawable, and we want to read the contents from there into the texture. However, due to the above AddDirtyRect call it doesn't. But let's assume it would.
read_from_framebuffer calls ActivateContext(dest surface). This is OK - the surface is already active, so ActivateContext returns immediately. It doesn't though, if there is a thread switch at the same time, that is the problem with the other PreLoad call.
After that, it checks if a glTexImage2D call is needed to allocate the mipmap sublevel - yes, because setGLtextureDesc unset the flag as it is supposed to.
After that the content is read back.