Jump to content
  • Advertisement
Sign in to follow this  
AntiMoron

my `Render To Texture ` code won't work....

This topic is 1367 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

Hello guys,I was getting started to write a simple maze game one month ago.
And I really want to add some effect using Render to texture.

But some unknown problem occured. The screen won't render anything...!!!



I've done render to texture before.But this time,It failed...I don't know what am I doing wrong.


Here's the RenderToTexture class.. (Which I use FrameBuffer Instead)


for class declaration : https://github.com/AntiMoron/aMazing/blob/master/aMazing/FrameBuffer.h
for class defination   : https://github.com/AntiMoron/aMazing/blob/master/aMazing/FrameBuffer.cpp
 
for test Code : https://github.com/AntiMoron/aMazing/blob/master/aMazing/aMazing.cpp

or you can download the whole project to help me check out how could it be !
https://github.com/AntiMoron/aMazing

Share this post


Link to post
Share on other sites
Advertisement

I see that you have already implemented the debug layer in your D3DClass.cpp, can you tell us the output message during runtime?

Share this post


Link to post
Share on other sites

I see that you have already implemented the debug layer in your D3DClass.cpp, can you tell us the output message during runtime?

well...Actually everything seems to work fine.....But Just Nothing Rendered.

 

No error message is printed..

 

I'm so confused..........  8-(

Share this post


Link to post
Share on other sites
Hey, I had a quick look at this tonight, so if you still need to fix it, here you go.
 
Like Migi0027 suggested, the initial error is being reported by the debug layer.  Open the project in VS, switch the build configuration to Debug instead of Release, and start it with the Local Windows Debugger button.  While the app is running go back to the VS window and check the Output tab, make sure it's set to show output from Debug, and you'll see your app is spamming out this every frame:
 

D3D11 WARNING: ID3D11DeviceContext::PSSetShaderResources: Resource being set to PS shader resource slot 0 is still bound on output! Forcing to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]

 
Which is the result of trying to bind the framebuffer.cpp render-to-texture buffer's SRV to the PS, while it's RTV is still bound on the OM.  It's trying to set it to read while it's still bound for writing.  So the runtime is simply ignoring your request to bind it to the PS, meaning basic2D.fx can't sample from it.  That's why your app only displays the cleared color of your backbuffer, it never attempts to read from the render-to-texture.  You can fix this warning by re-ordering your Render() function in aMazing.cpp:
 
...
blur.setRenderTarget(DEVICE, CONTEXT);
blur.clearRenderTarget(DEVICE, CONTEXT);
 
TEXTURE.getTexture(1)->bindPS(DEVICE, CONTEXT, 0);
SHADERS.getPair("Basic3D").bindShader(DEVICE, CONTEXT);
mz->Render(DEVICE, CONTEXT);
 
d3d.setRenderTarget(); //bind the backbuffer RTV to the OM -before- binding the render-to-texture SRV to the PS 
blur.bindPS(DEVICE, CONTEXT,0);
 
d3d.clearDepthStencil();
SHADERS.getPair("Basic2D").bindShader(DEVICE, CONTEXT);
GRAPHICS.RenderRectangle(0, 0, WINWIDTH, WINHEIGHT);
...
That solves the immediate problem of why you don't get anything onscreen.  Run your project again and hold down S to back the camera away, you'll see your boxes appear after a second or two. So it's working now, that's great right?!  However...
 
If you go look at the debug output in VS, it now gives 2 new warnings and 1 ouright error in the VS output window:
 

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 0 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]
D3D11 ERROR: ID3D11DeviceContext::Draw: The Shader Resource View dimension declared in the shader code (TEXTURE2D) does not match the view type bound to slot 0 of the Pixel Shader unit (TEXTURE2DMS).  This mismatch is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #354: DEVICE_DRAW_VIEW_DIMENSION_MISMATCH]

 
Lets deal with the warnings first.  The two warnings happen at the start of the frame, because the render-to-texture SRV from framebuffer.cpp is still bound to the PS from the end of previous frame.  When it tries to bind the RTV of the same resource to the OM it complains in the first warning and then forces the SRV to be unbound from the PS in the second warning.  Unlike the earlier warning these ones don't outright break your rendering, but you should probably fix them.  Once again it can be fixed by re-ordering the calls in your render function:
 
TEXTURE.getTexture(1)->bindPS(DEVICE, CONTEXT, 0); //replace the SRV bound to slot 0 in the PS -before- binding the render-to-texture RTV to the OM
blur.setRenderTarget(DEVICE, CONTEXT);
blur.clearRenderTarget(DEVICE, CONTEXT);
 
SHADERS.getPair("Basic3D").bindShader(DEVICE, CONTEXT);
mz->Render(DEVICE, CONTEXT);
 
d3d.setRenderTarget(); //bind the backbuffer RTV to the OM -before- binding the render-to-texture SRV to the PS 
blur.bindPS(DEVICE, CONTEXT,0);
 
d3d.clearDepthStencil();
SHADERS.getPair("Basic2D").bindShader(DEVICE, CONTEXT);
GRAPHICS.RenderRectangle(0, 0, WINWIDTH, WINHEIGHT);

Attempt to run the project now and only the error message remains.  The error is happening because you've created your render-to-texture resource and it's associated views with multiplesampling enabled (SampleDesc.Count =4 on the resource, and _TEXTURE2DMS on both of the views), while your basic2D.fx shader declares it as a plain TEXTURE2D.  The quickest fix is to go into FrameBuffer.cpp and change your sample counts to 1 instead of 4, and the view descriptions to _TEXTURE2D.  Note you need to do this for the associated depth buffer in FrameBuffer.cpp also.  That's all the per-frame D3D11 runtime warnings/errors corrected.
 
If you did want to render the box geometry with multisampling, then you need resolve the render-to-texture TEXTURE2DMS buffer into a seperate TEXTURE2D buffer and sample from that instead in your shader.  You'd do this by using context->ResolveSubResource().  So basically you'd no longer create the SRV for the render-to-texture buffer, but instead create a second buffer of the same format (you're currently using DXGI_FORMAT_R32G32B32A32_FLOAT which is a bit overkill btw) with a sample count of 1 instead of 4, and create an SRV with a viewdimension of _TEXTURE2D for that new 1-sample buffer.  Then once you'd finished rendering to your multisample buffer, unbind it's RTV from the OM, and call ResolveSubResource with the multisample buffer as the src, and the 1-sample buffer as the dst.  Then bind your 1-sample buffer's SRV to the PS when you render with basic2D.fx.
 
On a seperate note, when you application exits the debug output from the D3D11 runtime is complaining about a lot of resources still alive.  There are a lot of threads here about how to fix those errors (some resources aren't being released).

Good luck!

Share this post


Link to post
Share on other sites

Hey, I had a quick look at this tonight, so if you still need to fix it, here you go.
 
Like Migi0027 suggested, the initial error is being reported by the debug layer.  Open the project in VS, switch the build configuration to Debug instead of Release, and start it with the Local Windows Debugger button.  While the app is running go back to the VS window and check the Output tab, make sure it's set to show output from Debug, and you'll see your app is spamming out this every frame:
 

D3D11 WARNING: ID3D11DeviceContext::PSSetShaderResources: Resource being set to PS shader resource slot 0 is still bound on output! Forcing to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]

 
Which is the result of trying to bind the framebuffer.cpp render-to-texture buffer's SRV to the PS, while it's RTV is still bound on the OM.  It's trying to set it to read while it's still bound for writing.  So the runtime is simply ignoring your request to bind it to the PS, meaning basic2D.fx can't sample from it.  That's why your app only displays the cleared color of your backbuffer, it never attempts to read from the render-to-texture.  You can fix this warning by re-ordering your Render() function in aMazing.cpp:
 
...
blur.setRenderTarget(DEVICE, CONTEXT);
blur.clearRenderTarget(DEVICE, CONTEXT);
 
TEXTURE.getTexture(1)->bindPS(DEVICE, CONTEXT, 0);
SHADERS.getPair("Basic3D").bindShader(DEVICE, CONTEXT);
mz->Render(DEVICE, CONTEXT);
 
d3d.setRenderTarget(); //bind the backbuffer RTV to the OM -before- binding the render-to-texture SRV to the PS 
blur.bindPS(DEVICE, CONTEXT,0);
 
d3d.clearDepthStencil();
SHADERS.getPair("Basic2D").bindShader(DEVICE, CONTEXT);
GRAPHICS.RenderRectangle(0, 0, WINWIDTH, WINHEIGHT);
...
That solves the immediate problem of why you don't get anything onscreen.  Run your project again and hold down S to back the camera away, you'll see your boxes appear after a second or two. So it's working now, that's great right?!  However...
 
If you go look at the debug output in VS, it now gives 2 new warnings and 1 ouright error in the VS output window:
 

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 0 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]
D3D11 ERROR: ID3D11DeviceContext::Draw: The Shader Resource View dimension declared in the shader code (TEXTURE2D) does not match the view type bound to slot 0 of the Pixel Shader unit (TEXTURE2DMS).  This mismatch is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). [ EXECUTION ERROR #354: DEVICE_DRAW_VIEW_DIMENSION_MISMATCH]

 
Lets deal with the warnings first.  The two warnings happen at the start of the frame, because the render-to-texture SRV from framebuffer.cpp is still bound to the PS from the end of previous frame.  When it tries to bind the RTV of the same resource to the OM it complains in the first warning and then forces the SRV to be unbound from the PS in the second warning.  Unlike the earlier warning these ones don't outright break your rendering, but you should probably fix them.  Once again it can be fixed by re-ordering the calls in your render function:
 
TEXTURE.getTexture(1)->bindPS(DEVICE, CONTEXT, 0); //replace the SRV bound to slot 0 in the PS -before- binding the render-to-texture RTV to the OM
blur.setRenderTarget(DEVICE, CONTEXT);
blur.clearRenderTarget(DEVICE, CONTEXT);
 
SHADERS.getPair("Basic3D").bindShader(DEVICE, CONTEXT);
mz->Render(DEVICE, CONTEXT);
 
d3d.setRenderTarget(); //bind the backbuffer RTV to the OM -before- binding the render-to-texture SRV to the PS 
blur.bindPS(DEVICE, CONTEXT,0);
 
d3d.clearDepthStencil();
SHADERS.getPair("Basic2D").bindShader(DEVICE, CONTEXT);
GRAPHICS.RenderRectangle(0, 0, WINWIDTH, WINHEIGHT);
Attempt to run the project now and only the error message remains.  The error is happening because you've created your render-to-texture resource and it's associated views with multiplesampling enabled (SampleDesc.Count =4 on the resource, and _TEXTURE2DMS on both of the views), while your basic2D.fx shader declares it as a plain TEXTURE2D.  The quickest fix is to go into FrameBuffer.cpp and change your sample counts to 1 instead of 4, and the view descriptions to _TEXTURE2D.  Note you need to do this for the associated depth buffer in FrameBuffer.cpp also.  That's all the per-frame D3D11 runtime warnings/errors corrected.
 
If you did want to render the box geometry with multisampling, then you need resolve the render-to-texture TEXTURE2DMS buffer into a seperate TEXTURE2D buffer and sample from that instead in your shader.  You'd do this by using context->ResolveSubResource().  So basically you'd no longer create the SRV for the render-to-texture buffer, but instead create a second buffer of the same format (you're currently using DXGI_FORMAT_R32G32B32A32_FLOAT which is a bit overkill btw) with a sample count of 1 instead of 4, and create an SRV with a viewdimension of _TEXTURE2D for that new 1-sample buffer.  Then once you'd finished rendering to your multisample buffer, unbind it's RTV from the OM, and call ResolveSubResource with the multisample buffer as the src, and the 1-sample buffer as the dst.  Then bind your 1-sample buffer's SRV to the PS when you render with basic2D.fx.
 
On a seperate note, when you application exits the debug output from the D3D11 runtime is complaining about a lot of resources still alive.  There are a lot of threads here about how to fix those errors (some resources aren't being released).

Good luck!

 

Wow,your answer is really terrific!!!!

I appreciate your patience,really.

I learn a lot from you! 

I've read your answer carefully and can draw a conclusion that I really need to care the binding order of SRVs and RTVs.

Maybe I should make a limitation of binding orders with syntax of c++. 

Edited by AntiMoron

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!