Sign in to follow this  
Shael

CgFX Mid-Pass Parameter Updating

Recommended Posts

What is the proper way in CgFX to commit changes mid-pass? Eg. the functionality that DirectX effects do when calling effect->CommitChanges()

It seems the only way to update the changes (specifically textures) is to call cgSetPassState() each time. This seems wrong to me though, wouldn't it be slow? I've also tried cgUpdatePassParameters() but it doesn't update the textures.

The other problem I'm getting is a warning from Direct3D:

Quote:
Direct3D9: (WARN) :Can not render to a render target that is also used as a texture. A render target was detected as bound, but couldn't detect if texture was actually used in rendering.


It would seem that after using my render target as a texture input for another shader it is not being unbinded before it gets used as a render target again.

Has anyone come across these problems before and found a solution?

Cheers

Share this post


Link to post
Share on other sites
I don't know what is cgfx equivalent for dx effect CommitChanges.
But as for warning you should set other render target surface as current
one before you use its texture, something like:

dev->SetRenderTarget(0, surface1);
DrawThings();
dev->SetRenderTarget(0, surface2);
dev->SetTexture(surface1Texture);//or cgFX->SetTexture(surface1Texture) whatever
DrawSomethingElse();

Share this post


Link to post
Share on other sites
The thing is, I set the render targets that I need to use as textures to NULL before using them, and any other RT's back to NULL when I'm finished with a particular pass or technique so it beyond me why its doing this. It would seem Cg has some issues with textures or something and the nvidia forum has really poor support :/

Share this post


Link to post
Share on other sites
You should be doing something like this:

init time

hr = dev->CreateTexture(
RTSize.x, RTSize.y, 1, D3DUSAGE_RENDERTARGET, rtFormat, D3DPOOL_DEFAULT, &RTTexture, 0);
if(FAILED(hr))
{
ErrBox("Creating RTTexture failed!!!");
DebugBreak();
return;
}

hr = RTTexture->GetSurfaceLevel(0, &RTSurface);
if(FAILED(hr))
{
ErrBox("Get RTTexture surface failed!!!");
DebugBreak();
return;
}
// if necessary create depth buffer that will be used
// with your RT surface
hr = dev->CreateTexture(
RTSize.x, RTSize.y, 1, D3DUSAGE_DEPTHSTENCIL, dsFormat, D3DPOOL_DEFAULT, &DSTexture, 0);
if(FAILED(hr))
{
ErrBox("Creating DSTexture failed!!!");
DebugBreak();
return false;
}
hr = DSTexture->GetSurfaceLevel(0, &DSSurface);
if(FAILED(hr))
{
ErrBox("Get DSTexture surface failed!!!");
DebugBreak();
return false;
}





rener time

dev->Clear(0, 0, clearFlags, targetColor, 1.0f, 0L);
dev->BeginScene();
...
...
// before render to your rt obtain previous surfaces
// to save its content for later usage
LPDIRECT3DSURFACE9 bb, ds;
dev->GetRenderTarget(0, &bb);
dev->GetDepthStencilSurface(&ds);
// now set your rt
dev->SetRenderTarget(0, RTSurface);
dev->SetDepthStencilSurface(DSSurface);
dev->Clear(0, 0, clearFlags, rtTargetColor, 1.0f, 0L);
SetCGShader();
DrawSomething();

// now restore "old" surfaces
dev->SetRenderTarget(0, bb);
dev->SetDepthStencilSurface(ds);
dev->Clear(0, 0, clearFlags, targetColor, 1.0f, 0L);//clear if needed
bb->Release();
ds->Release();

//now you can use safely your rt texture
CGShader->SetTexture(RTTexture);
DrawSomethingAgain();
...
...
dev->EndScene();
dev->Present(0,0,0,0);





EDIT: concerning creating additional depth buffer, if device/hardware doesnt support ds buffer as texture try IDirect3DDevice9::CreateDepthStencilSurface.

Share this post


Link to post
Share on other sites
Quote:
Quote:
Direct3D9: (WARN) :Can not render to a render target that is also used as a texture. A render target was detected as bound, but couldn't detect if texture was actually used in rendering.

It would seem that after using my render target as a texture input for another shader it is not being unbinded before it gets used as a render target again.
Has anyone come across these problems before and found a solution?
Cheers

Never used CgFX, but the warning is familiar. It happened in the following context (DirectX 9, HLSL with effect framework)

- Using two render-targets in a ping-pong fashion
- Using a vertex shader that applies a texture fetch (tex2Dlod, SM 3.0)
- Did call effect->Begin(D3DXFX_DONOTSAVESTATE), so render states were not automatically reset after effect->End()
- AFAIR the warning occured when issueing another draw call after I have swapped the render-targets, even when setting the textures to NULL.

A close look at PIX revealed that setting the textures to NULL was not enough: There was still a "texture" set, namely D3DVERTEXTEXTURESAMPLER0. Obviously this is the fixed function pipeline equivalent of tex2Dlod. Inserting the following line after the aforementioned effect made the warning disappear:

device->SetTexture(D3DVERTEXTEXTURESAMPLER0, NULL);

(or using the effect with auto-reset, i.e. effect->Begin(0))

Can't say if this will solve your problem: If you have a similar vertex shader make sure to reset the render-state in question. A look at PIX should show you which one.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this