Well I know the Holly Grail is not a background loading thread($#$@#$%).

Started by
2 comments, last by ankhd 9 years, 10 months ago

Hello all.

I was thinking all my problems solved if I just loaded all my textures and meshes in a back ground
thread then my load bar would render and up date in the main thread. Alas my hopes are dashed, For an easy ride.

I was wondering if I'm doing it correct.

These are the steps
main app init d3d
main loads menu

main starts new thread running

main renders load bar

background thread lock device loads a block of data, updates the loadbar by its pointer then
leaves the lock sleep(2000) then repeats till no data to load.

So my thread loads blocks of data at a time between Enter and Leave Calls to the device
But I have a block that has a lot of things(meshes and textures to load) and this lags the main app down.

But if I remove the Enter and Leave Calls to the device it loads and does not block but the load time goes from
2 minutes to 4.5 minutes. it takes 2 minutes to load with the locking calls and also 2 minute with no threading used
oh and if I place a lock at the start and then load all data then unlock at the end
the main app is frozen until loading is done 2 minutes.

what should I look at doing
sleep(10); in main after present not do anything but lag 10 ms extra

should I have a Lock and unclock call around all the data

I know you can't do this in the second thread with out a lock
D3D10_PASS_DESC PassDesc;
Tech->GetPassByIndex( 0 )->GetDesc( &PassDesc );

this is how I'm going about getting the device to lock. I'm not even sure if this is correct there is not alot of info on it.
At device create
ID3D10Multithread *mt;
Device->QueryInterface(IID_ID3D10Multithread, (void **)&mt);

backGroundThread()
{
mt->Enter();
loadbar->Progress(numitems);//this is in main getting rendered as its doing this does it need a lock
//it can update fine with no locking not sure if I should or not any ideas?????
load meshes textures anything.
mt->Leave();

Sleep(2000);

mt->Enter();//Big data block = long wait time
loadbar->Progress(numitems);//this is in main getting rendered as its doing this does it need a lock
//it can update fine with no locking not sure if I should or not any ideas?????
load meshes textures anything.
mt->Leave();

do next blcok
}

Advertisement

This is a whole lot simpler in D3D11. In D3D11 all functions on the device (e.g. the ones for creating textures) are thread safe. All functions on the device context are not thread safe, those are the functions used for rendering. The only thing to watch out for is that Map() requires the device context, so you shouldn't use it during resource creation.

The documentation says that D3D10 simply takes a lock for every API call unless D3D10_CREATE_DEVICE_SINGLETHREADED is specified. So I think you still don't need your own locks. I'd try not using ID3D10Multithread on the loader thread at all.

If you want to manually lock for some reason, don't hold the lock for more than a few milliseconds at a time off the main thread. You really don't want to hold it when doing a file read for example as that can easily take hundreds of milliseconds, which will block the render thread for several frames.

Hi. and thanks for the help.

Im getting a invalid param only when I place this bit of the code in the back ground thread


ID3D10EffectTechnique *Tech = cFXManager::GetTechnique(0);

//

//ID3D10EffectTechnique *Tech = cFXManager::GetTechnique(1);

// Create the input layout

D3D10_PASS_DESC PassDesc;

ID3D10EffectPass* pass = Tech->GetPassByIndex( 0 );

if(pass == NULL)

{

//this does not print when in back ground thread???????? and the break points don't work

OutputDebugString("NULL PASS, PSystem Failed GetPassByIndex");

MessageBox(NULL,

" PSystem Failed GetPassByIndex", "InitDevice", MB_OK);

return;

}

//error

HRESULT hr = pass->GetDesc( &PassDesc );

//sometimes passes and other time it fails

if( FAILED( hr ) )

{

std::stringstream ss;

ss <<

"PSystem Failed GetPassByIndex GetDesc\nHRESULT HR = ";

ss << hr;

ss <<

"\n";

OutputDebugString(ss.str().c_str());

MessageBox(NULL,ss.str().c_str(),

"InitDevice", MB_OK);

return;

}

hr = md3dDevice->CreateInputLayout( ParticleVertex::VertexParticleLayout, ParticleVertex::GetNumElements(), PassDesc.pIAInputSignature,

PassDesc.IAInputSignatureSize, &mpVertexInputLayout );

if( FAILED( hr ) )

{

fails here all the time(unless I use Sleep(20) in the main Apps Render) invalid Param 3rd param, only when I dont place a device->enter() before it

}

the thing is that other parts of the loading code has the same type code and it all passes.

jut this one needs the lock placed before I can enter it to stop failing.

conclusion you must design your app from the start to be threaded so you don't have code that uses map and fx in the loading thread(bugger).

The back ground thread runs slower then it does if the code was just loaded in the main app. Reason is that the device is in use in the main apps thread doing rendering.

and if I place a Sleep(20); in the main apps render function the load time is cut down by 1 minute, I don't like doing this but Its only going while the apps in the menu system anyway.

other then the above bit of code its working ok for a hack.

Nope just looking over my code while writting this and I see ID3D10EffectTechnique *Tech = cFXManager::GetTechnique(0); This Is my bit of code and

it's being used in both threads at the same time hehehe.

I think I need a lock on that class only, I'll Go and setup a mutex on the FX Class and see what I get.

One question is How Do I lock the whole class do I lock function calls or variables, so research need I think. Now this in going to be a under taking

I never liked my fx class anyway I made the misstake of putting all my shaders in on class even the ones that are not used in the app and they all get to load and compile

before I can use the class. Im thinking I will need to redesign this class to only load shaders I want in any app and to multi thread safe it.

Well I'll be seeing you all in a month or more lol. thanks for the help.

any suggestions. Other then whipping my self and putting salt on the wound.

Ok.

I only needed to create a new GetTechnique(fxtype, 0);the old one was changeing my FXClass currentState to the new state. Now it just gets the state it needs and leave class in its set state;

which will lead to me being able to load only the shaders I need per app.

My FX class is a lot more modular then I thought it was.

So now I can Remove all the devices Enter() and Leave() in the loading code, and let the device do its fantastic job. I salute the creaters of the device Because I just Thrashed the hell out of it and it held up hu.

But I needed a Sleep still this is ok its only in the ui system it was running a 6ms per frame not its 26

but the 4.5 minute load time is down to 2.3 minutes I can Live with this.

the only thing is you have to wait for the loading any way because it only takes a minute to create an new game but it gets hidden when the game starts its loading.

This topic is closed to new replies.

Advertisement