locking

Started by
4 comments, last by griffin2000 17 years, 9 months ago
Can someone explain to me the purpose of locking textures. I keep hearing about it so it must be a pretty powerful tool but I don't know anything about it.
Advertisement
Locking a texture (or any resource) gives you access to the raw data representing the resource. For textures, it gives you a pointer to the texels on the surface, and allows you to draw directly onto it. The most common uses for textures is for filling the texture with data just after you create it (If you're not use D3DXCreateTextureFromFile()), and for doing procedural textures.
The DirectX implementation is based on COM, which happens to be a thread-capable architecture. In a multithreaded environment, writing to a buffer is typically protected by a mutex or critical section to prevent deadlocks where multiple threads are concurrently writing to the same block of memory (and potentially overwriting each other, and other nasty interactions).

.Lock() essentially creates a critical section, then provides raw pointer access to the underlying block of memory. While you have .Lock()ed a texture (or vertex/index buffer, for example), no other piece of code (running in another thread) can .Lock() it.

Further Reading
MSDN: Locking Resources (Direct3D)
MSDN: Critical Section Objects
MSDN: Wait Functions
Wikipedia: Critical Section
Wikipedia: Lock
Yeah the key point is that the graphics card (the GPU) is running asynchronously from your PC's CPU. When you say "pDev->DrawIndexedPrimitive(...);" it is not rendered immediately while you are in the that function. All that function does is put a command in a ring-buffer which your GPU will perform at some later point in the frame (dependent on how busy your GPU is). If you could just go in and edit vertices and textures arbritarilly this could cause huge problems as the GPU could be trying to render with those resources as you are screwing with them. The Lock function ensures the GPU is not using those resources, so it must be called before you access them. It can potentially be a big performance hit (if you are locking resources each frame to edit them), as if the GPU is using them it will stall the CPU until the resource is free.
That's a little bit over my head but I'm trying to follow along. Can someone give me an example. To kinda flesh out the idea for me.
For all intents and purposes the Lock() functions is just means to access the actual data for a texture or vertex buffer. E.g.:


	g_pd3dDevice->CreateTexture(RANDOM_TEXTURE_SIZE,RANDOM_TEXTURE_SIZE,RANDOM_TEXTURE_LEVELS,D3DUSAGE_DYNAMIC,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&g_pRandomTexture,NULL);	D3DLOCKED_RECT randrect;	for(int l=0;l<RANDOM_TEXTURE_LEVELS;l++)	{		g_pRandomTexture->LockRect(l,&randrect,NULL,0);		UINT *pRandPixels=(UINT *)randrect.pBits;		//Fill in data in pRandPixels..		g_pRandomTexture->UnlockRect(l);		levelSize/=2;	}


If you only do this at startup, then thats pretty much all you need to know. If on the other hand your locking every frame then it could be a significant chunk of your frame your wasting stalled inside of Lock(). And you should consider double buffering or using other functions that don't require locking (or using a pixel shader for procedural textures).

[Edited by - griffin2000 on July 27, 2006 4:43:57 PM]

This topic is closed to new replies.

Advertisement