Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


D3D resources and Multithreading


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 Tispe   Members   -  Reputation: 1047

Like
0Likes
Like

Posted 08 November 2012 - 01:15 AM

Hi

My program is using DX9 and can't share the Device among multiple threads. Which means I can't create resources on other threads.

I wanted to know if it is possible to create vertex, index buffers and textures on the main thread and then pass those resources to a worker thread that lock/read/write/unlock/release these resources while the main thread is rendering? These resources sent to the worker thread will not be in use intil the worker thread has finished and sent those resources back to the main thread.

Will this type of multithreading work for DX9? Or are resources created with the device unsafe for other threads?

Cheers!

Sponsor:

#2 Krohm   Crossbones+   -  Reputation: 3261

Like
0Likes
Like

Posted 08 November 2012 - 01:51 AM

I'd be careful in doing that. Even if the API allows it (D3DCREATE_MULTITHREADED) drivers might malfunction.
Yes, it's not supposed to happen. They're also not supposed to garble textures nor to crash but sometimes it happens and if you're dealing with people still on D3D9, I'd give up every thing I consider certain.
Now, I have been told this is fixed but multithreading was in its early ages and the official documentation about D3DCREATE_MULTITHREADED isn't very encouraging. D3D9 was way, way crude in its effective multi-threading capability.

Personally I would map/unmap/interact with D3D9 in the main thread and then pass the raw memory blob to the worker thread. This way D3D9 is out of the equation.

#3 Hodgman   Moderators   -  Reputation: 31938

Like
1Likes
Like

Posted 08 November 2012 - 02:13 AM

You can map them on the main thread, then have the worker fill them in, then unmap them on the main thread again...

#4 Tispe   Members   -  Reputation: 1047

Like
0Likes
Like

Posted 08 November 2012 - 02:20 AM

How do you "map/unmap" resources from main thread to worker thread? I have never heard of this before.

In my head I create a texture or a vertex buffer on the main thread, then push a pointer to the resource to a Critical_Section vector, retrieve that from the worker thread, copy data over send it back.

Some code might help me understand ;)


EDIT: Is it as simple as Addref(), Release() when sending and retrieving it?

Edited by Tispe, 08 November 2012 - 02:34 AM.


#5 Washu   Senior Moderators   -  Reputation: 5567

Like
1Likes
Like

Posted 08 November 2012 - 02:40 AM

When you map, or lock, a resource you typically get a pointer out of it. That pointer is not thread specific and thus you can pass it off to your worker thread for it to operate on.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.
ScapeCode - Blog | SlimDX


#6 Hodgman   Moderators   -  Reputation: 31938

Like
0Likes
Like

Posted 08 November 2012 - 02:45 AM

Sorry, by map/unmap, I meant lock/unlock. All D3D9 calls must occur on your main thread. The worker can generate data in between a call to lock and unlock.
e.g.
D3DLOCKED_RECT result = {};
texture->LockRect(0, &result, NULL, D3DLOCK_DISCARD);
SignalWorkerThreadToGenerateData( result );
... later ...
if( WorkerThreadIsDone() )
	texture->UnlockRect(0);


void* result = 0;
buffer->Lock(0, 0, &result, 0);
SignalWorkerThreadToGenerateData( result );
... later ...
if( WorkerThreadIsDone() )
	buffer->Unlock();

Edited by Hodgman, 08 November 2012 - 02:47 AM.


#7 Tispe   Members   -  Reputation: 1047

Like
0Likes
Like

Posted 08 November 2012 - 03:11 AM

Will this work with Texture->GetSurfaceLevel (0, &Surface) and then sending the LPDIRECT3DSURFACE9 to the worker thread? I really wish to use D3DXLoadSurfaceFromMemory to convert DXTn to ARGB on the worker thread.

Will it also work with the ID3DXBaseMesh::LockVertexBuffer method if I use the ID3DXMesh wrapper?

#8 Evil Steve   Members   -  Reputation: 1987

Like
0Likes
Like

Posted 08 November 2012 - 05:38 AM

No, you shouldn't be passing any D3D resources to the worker thread, which means not using D3DXLoadSurfaceFromMemory(). One (messy) option is to create your own class that inherits from IDirect3DSurface9, and pass an instance of that class to D3DXLoadSurfaceFromMemory(). Your class should implement all of the IDirect3DSurface9 functions.

You can then implement your class to store the ARGB pixel data internally, and then after calling D3DXLoadSurfaceFromMemory(), you can copy that ARGB data into the real surface (Which should be locked in the D3D thread and the pointer passed to the worker thread).

Or, just not use D3DXLoadSurfaceFromMemory() :)

Steve Macpherson
Systems Programmer

Rockstar North


#9 Tispe   Members   -  Reputation: 1047

Like
0Likes
Like

Posted 08 November 2012 - 05:57 AM

Question: Will locking any resource block rendering, can a locked texture be locked for several frames if it is not in use?

Baw, it seems Microsoft didn't have multithreading in mind when implementng D3DXLoadSurfaceFromMemory(). I hope I can get away with calling this a few times each frame.

It seems that I will have to scrap the whole idea of passing mapped/locked resource pointers to worker threads to keep things simple. I guess I can use GetTickCount() after each resource I process and check if elapsed time is not too much, that way I can skip processing to next frame to avoid huge drops in frame rate.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS