Sign in to follow this  

Flooded by warnings when using RenderTargets as textures

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there! I have come across a problem when using render targets as textures: I have three render-target textures (created with D3DUSAGE_RENDERTARGET) RTColor, RTNormals and RTDepth. The first pass (filling the RTs) works fine, however the second pass, where I use those as textures floods me with this warning:
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.
I do the following:
device->GetRenderTarget(0, &RTBackbuffer);
device->SetRenderTarget(0, RTColor);
device->SetRenderTarget(1, RTNormals);
device->SetRenderTarget(2, RTDepth);

//clear render target and z-buffer
device->BeginScene();
//render my stuff using a shader here, works fine
device->EndScene();

device->SetRenderTarget(0, RTBackbuffer);
device->SetRenderTarget(1, NULL);
device->SetRenderTarget(2, NULL);

device->BeginScene();
//clear render target and z-buffer
//render a fullscreen quad, using the RTs as texture with "SimpleLight.fx"
device->EndScene();
device->Present(0,0,0,0);

That´s about all I do with the RTs for now. The shader ("SimpleLight.fx") mentioned in the source above looks like this:
float4 simpleLight_PS(in A2P v) : COLOR
{
    float4 diff = tex2D(colorSampler, v.uv);
    
    float depth = colorToFloat(tex2D(depthSampler, v.uv));
    depth = depth * (fFar -fNear) + fNear;
    float3 p = mul(float3(v.uv*2.0 -1.0, 1.0), mat_invProj);
    float3 viewPos = float3(p.xy / p.z * depth,depth);
    

    float3 lightViewPos = mul(float4(LightPos,1), mat_View).xyz;
    float3 Normal = tex2D(normalSampler, v.uv).xyz;
    
    float3 L = viewPos-lightViewPos;
    float nDotL = dot(Normal, normalize(L));
    
    return float4(diff * LightColor * nDotL, 1);      <<----- gives warnings
//    return colorToFloat(tex2D(depthSampler, v.uv));   <<---- works
//    return tex2D(colorSampler, v.uv);                 <<---- works
//    return tex2D(normalSampler, v.uv);                <<---- works
//    return tex2D(colorSampler, v.uv) *                <<---- works
//             tex2D(normalSampler, v.uv);
//    return tex2D(colorSampler, v.uv) *                <<---- works
//             colorToFloat(tex2D(depthSampler, v.uv));
//    return tex2D(colorSampler, v.uv) *               <<----- gives warnings
//             colorToFloat(tex2D(depthSampler, v.uv)) *;
//             tex2D(normalSampler, v.uv);
}

Okay, so I tried to make it simpler, as you can see in the source. Using less than all 3 RTs as textures in the shader works fine. So a look-up in one or two of them isn´t a problem, but using all three of them results in those warnings... Any help appreciated, thx for reading!

Share this post


Link to post
Share on other sites
The warning message is pretty clear :
as soon as you set one texture as a texture (SetTexture)
you should make sure any sublevel is not bound as rendertarget
so if you previously had a SetRendertarget(TextureLevel)
you have to explicitely SetRendertarget(NULL) or to another rendertarget.

Share this post


Link to post
Share on other sites
I'd like to add that this works the other way too. If you call SetTexture() or Effect->SetTexture(), and then call SetRenderTarget() using a surface from the texture, you're going to get the warning, since the texture is still bound. This could also be from the previous frame.

Be sure to call SetTexture(0, NULL) when you're done with it, or at the end of the frame.

Hope this helps.

Share this post


Link to post
Share on other sites
[edit]
Okay, I can use these textures now. I really had to call SetTexture(..., NULL) on the SimpleLight ID3DXEffect after rendering.
However I still don´t understand why I only got those warnings when using _all_ textures, but not if I only used 1 or 2 of them, regardless of which I used.

Share this post


Link to post
Share on other sites
The warnings are back, however I don´t have a clue why they reappeared...
this is the current source that deals with render targets and textures, there´s no other line of code in my project that sets any textures or render targets:

this->m_pRTBackBuffer = NULL;
HRESULT hr = this->m_pDirect3DDevice->GetRenderTarget(0, &this->m_pRTBackBuffer);
if(FAILED(hr))
{
MessageBox(NULL, "GetRenderTarget failed!", "RenderGeometryPass error!", MB_OK);
return -11;
}

hr = this->m_pDirect3DDevice->SetRenderTarget(0, this->m_pRTColorSurface);
if(FAILED(hr))
{
MessageBox(NULL, "SetRenderTarget for ColorTexture failed!", "RenderGeometryPass error!", MB_OK);
return -12;
}
this->m_pDirect3DDevice->SetRenderTarget(1, this->m_pRTNormalsSurface);
if(FAILED(hr))
{
MessageBox(NULL, "SetRenderTarget for NormalTexture failed!", "RenderGeometryPass error!", MB_OK);
return -12;
}
this->m_pDirect3DDevice->SetRenderTarget(2, this->m_pRTDepthSurface);
if(FAILED(hr))
{
MessageBox(NULL, "SetRenderTarget for DepthTexture failed!", "RenderGeometryPass error!", MB_OK);
return -12;
}
this->m_pDirect3DDevice->SetRenderTarget(3, this->m_pRTSpecularSurface);
if(FAILED(hr))
{
MessageBox(NULL, "SetRenderTarget for SpecTexture failed!", "RenderGeometryPass error!", MB_OK);
return -12;
}

this->m_pDirect3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0);
this->m_pDirect3DDevice->BeginScene();
// I render the first pass here
this->m_pDirect3DDevice->EndScene();


hr = this->m_pDirect3DDevice->SetRenderTarget(0, this->m_pRTBackBuffer);
if(FAILED(hr))
{
MessageBox(NULL, "Reverting to backbuffer failed!", "Renderer::RenderGeometryPass() error", MB_OK);
return -30;
}
this->m_pRTBackBuffer->Release();
this->m_pRTBackBuffer = NULL;

this->m_pDirect3DDevice->SetRenderTarget(1, NULL);
this->m_pDirect3DDevice->SetRenderTarget(2, NULL);
this->m_pDirect3DDevice->SetRenderTarget(3, NULL);

this->m_pDirect3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_TARGET, D3DCOLOR_XRGB(70, 70, 100), 1.0, 0);

//e is an ID3DXEffect containing the SimpleLight.fx shader from my first
// post

e->SetTexture("ColorMap", this->m_pRTColor);
e->SetTexture("DepthMap", this->m_pRTDepth);
e->SetTexture("NormalMap", this->m_pRTNormals);

e->SetTechnique("tec0");
this->m_pDirect3DDevice->SetStreamSource(0,this->m_pVBQuads,0,20);
this->m_pDirect3DDevice->SetVertexDeclaration(this->m_TransformedVerticesVD);
this->m_pDirect3DDevice->BeginScene();
//rendering one full-screen quad here
this->m_pDirect3DDevice->EndScene();
e->SetTexture("ColorMap", NULL);
e->SetTexture("DepthMap", NULL);
e->SetTexture("NormalMap", NULL);
this->m_pDirect3DDevice->Present(0,0,0,0);




I left out some lines that set floats and matrices for the shader, as I don´t think they´re related to the problem.
As you see I call SetTexture(..., NULL) for all the textures I set during the second pass.
The warnings are spilled at every DrawIndexedPrimitive() call during the first pass, where I use m_pRTColor, m_pRTNormals and m_pRTDepth as render targets.
Anything else I can do to be really sure those textures aren´t bound anymore, as it seems that SetTexture(...,NULL) didn´t do the trick.

PS: I still only get those warnings when I use all three textures at once, using one or two of them works fine.

Share this post


Link to post
Share on other sites
It's possible than calling Effect->SetTexture()
may just update the internal pointer to the texture inside the technique object and not call any of the setTexture method on the d3dDevice (waiting for the next begin call to really apply the states).
You can probably live with it, if you're annoyed by the debug spew
you can force the texture to be NULL outside the technique (do an explicit m_pDirect3DDevice->SetTexture(0..N, NULL) and remove the effect SetTextures which would then become redundant).

LeGreg

Share this post


Link to post
Share on other sites
Quote:
Original post by LeGreg
It's possible than calling Effect->SetTexture()
may just update the internal pointer to the texture inside the technique object and not call any of the setTexture method on the d3dDevice (waiting for the next begin call to really apply the states).
You can probably live with it, if you're annoyed by the debug spew
you can force the texture to be NULL outside the technique (do an explicit m_pDirect3DDevice->SetTexture(0..N, NULL) and remove the effect SetTextures which would then become redundant).

LeGreg


Thx! Calling SetTexture(...) of the device instead of the effect did the trick.

So it might be feasible to bind the samplers in the shader to a specific register? If I understand that binding to registers correctly that would mean, that if I bind a sampler in a shader to register s0 for example, calling m_pDirect3DDevice->SetTexture(0, NULL) should unbind the texture for that sampler bound to s0, right?
What I mean is: Does the sampler register sN correspond to the N in SetTexture(N, NULL) of the device?

If they do, I could just use SetTexture(...) of the device instead of the effect most of the time, at least for my lighting shaders, as I could just impose a standard in which register which texture has to be for them.


Share this post


Link to post
Share on other sites

This topic is 4199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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