Jump to content
  • Advertisement
Sign in to follow this  
schupf

OMSetRenderTargets

This topic is 3906 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, in my DX10 Application im rendering to 5 faces of the box with this code:
techniqueUpdate->GetPassByIndex(0)->Apply(0);
for(int view = 0; view < 5; ++view) {
        float clearColor[4] = { 1.0, 0.0, 0.0, 0.0 };
        d3d10device->ClearRenderTargetView(envMapRTView[view], clearColor);
        d3d10device->ClearDepthStencilView(envMapDepthStencilView,
                                           D3D10_CLEAR_DEPTH, 1.0, 0);
        ID3D10RenderTargetView* RTViews[1] = { envMapRTView[view] };
        d3d10device->OMSetRenderTargets(1, RTViews, envMapDepthStencilView);
			
	d3d10device->Draw(4, 4 * view);
}

So in every loop I set envMapRTView[view] as the current Rendertarget (envMapRTView is an Array of ID3D10RenderTargetView and these 5 views are bound to 5 textures TEX) Later Im trying to render the created faces with this loop (Loop B):
[source="cpp"]
for(int i=0; i < 5; i++) {
   skyBoxFaceTextureSC->SetResource(envMapShaderView);
   techniqueRender->GetPassByIndex(0)->Apply(0);
			
   d3d10device->Draw(4, 4*i);
}

envMapShaderView are ID3D10ShaderResourceViews on the 5 textures TEX. The code works, but I get these warnings if i run the loop B:
Quote:
D3D10: WARNING: ID3D10Device::OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD ] D3D10: WARNING: ID3D10Device::OMSetRenderTargets: Forcing PS shader resource slot 1 to NULL.
I kinda understand the warning. Im trying to use the 5 textures as a shader resource but obviously they are still bound as a render target. Unfortunately I couldnt solve the problem. Neither a ID3D10ShaderResourceView *const pSRV[1] = {NULL}; d3d10device->PSSetShaderResources(0, 1, pSRV); nor a skyBoxFaceTextureSC->SetResource(NULL); helped. Any ideas how I can unbound the resource? Thanks

Share this post


Link to post
Share on other sites
Advertisement
I know almost nothing about D3D10, but in D3D9 the way to solve this was to pass set NULL as the texture or the render target once finished. Perhaps this also works in D3D10?

Share this post


Link to post
Share on other sites
Yes that works for me anw, I had the same problem while trying to implement a HDR pipeline.
Solved it like this though

__DiffuseVariable->SetResource( 0 );
__TechniqueCopy->GetDesc( &techDesc );
__TechniqueCopy->GetPassByIndex( 0 )->Apply(0);

Stefan

Share this post


Link to post
Share on other sites
Hm, if I comment out the first line in my render loop:
for(int i=0; i < 5; i++) {
skyBoxFaceTextureSC->SetResource(envMapShaderView);
techniqueRender->GetPassByIndex(0)->Apply(0);

d3d10device->Draw(4, 4*i);
}
then I dont get the warning. (envMapShaderView is a shader Resource view onto the 5 textures in which I render with RenderTargetViews)

So I tried what you both suggested: Right before the loop I do the following:
skyBoxFaceTextureSC->SetResource(0);
techniqueRender->GetPassByIndex(0)->Apply(0);
Supprisingly it doesnt change anything and I still get the warning!
Any idea why this doesnt help??

Share this post


Link to post
Share on other sites
Could you possibly post more code? The warning indicates that the texture is still bound as input when you try to set the render target, yet you indicate here that you're calling OMSetRenderTargets before SetResource. So it seems to me like there's more going on that you didn't show, like you went back to the first loop again after the second one is run :)

Share this post


Link to post
Share on other sites
Hehe, sure! I always try to post as little code as possible but maybe this time it was a little bit to little;)

First, this are the variables related to the problem:
ID3D10Texture2D* envMap[5]; // the 5 face textures
ID3D10Texture2D* envMapDepthStencil; // Depth stencil

ID3D10RenderTargetView* envMapRTView[5]; // 5 render target views, each view is used for 1 face of the env map
ID3D10DepthStencilView* envMapDepthStencilView; // Depth stencil view for environment map

ID3D10ShaderResourceView* envMapShaderView[5];



Second, this is my init code (I guess its not relevant, but I post it for completeness):


// Depth Stencil
D3D10_TEXTURE2D_DESC dstex;
dstex.Width = ENVMAPSIZE;
dstex.Height = ENVMAPSIZE;
dstex.MipLevels = 1;
dstex.ArraySize = 1;
dstex.SampleDesc.Count = 1;
dstex.SampleDesc.Quality = 0;
dstex.Format = DXGI_FORMAT_D32_FLOAT;
dstex.Usage = D3D10_USAGE_DEFAULT;
dstex.BindFlags = D3D10_BIND_DEPTH_STENCIL;
dstex.CPUAccessFlags = 0;
dstex.MiscFlags = 0;
d3d10device->CreateTexture2D( &dstex, NULL, &envMapDepthStencil );

// Create the depth stencil view
D3D10_DEPTH_STENCIL_VIEW_DESC DescDS;
DescDS.Format = DXGI_FORMAT_D32_FLOAT;
DescDS.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
DescDS.Texture2DArray.FirstArraySlice = 0;
DescDS.Texture2DArray.ArraySize = 1;
DescDS.Texture2DArray.MipSlice = 0;
d3d10device->CreateDepthStencilView( envMapDepthStencil, &DescDS, &envMapDepthStencilView );

// Create the 5 cube map faces
dstex.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
dstex.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
dstex.MiscFlags = 0;
dstex.MipLevels = 1;
for(int i=0; i < 5; i++)
d3d10device->CreateTexture2D( &dstex, NULL, &envMap );

// Create the 5 Render Target Views
D3D10_RENDER_TARGET_VIEW_DESC DescRT;
DescRT.Format = dstex.Format;
DescRT.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
DescRT.Texture2D.MipSlice = 0;
for( int i = 0; i < 5; ++i )
d3d10device->CreateRenderTargetView( envMap, &DescRT, &envMapRTView);

// Create the 5 Shader Resource Views
D3D10_SHADER_RESOURCE_VIEW_DESC desc;
desc.Format = dstex.Format;
desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipLevels = 1;
desc.Texture2D.MostDetailedMip = 0;
for(int i=0; i < 5; i++)
d3d10device->CreateShaderResourceView(envMap, &desc, &envMapShaderView)


Now the update code which renders into the 5 faces:

void update() {
// Save the old RT and DS buffer views
ID3D10RenderTargetView* oldRTViews[1] = { NULL };
ID3D10DepthStencilView* oldDSView = NULL;
d3d10device->OMGetRenderTargets(1, oldRTViews, &oldDSView);

// Save the old viewport
D3D10_VIEWPORT oldViewport;
UINT numViewports = 1;
d3d10device->RSGetViewports(&numViewports, &oldViewport);

// Set a new viewport for rendering to cube map
D3D10_VIEWPORT SMVP;
SMVP.Height = ENVMAPSIZE;
SMVP.Width = ENVMAPSIZE;
SMVP.MinDepth = 0;
SMVP.MaxDepth = 1;
SMVP.TopLeftX = 0;
SMVP.TopLeftY = 0;
d3d10device->RSSetViewports( 1, &SMVP );

UINT stride = sizeof(SkyBoxVertex);
UINT offset = 0;
d3d10device->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

d3d10device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3d10device->IASetInputLayout(vertexLayout);

opticalDepthLUTSC->SetResource(lookupTableView);

d3d10device->RSSetState(rasterizerState);

techniqueUpdate->GetPassByIndex(0)->Apply(0);

for(int view = 0; view < 5; ++view) {
float clearColor[4] = { 1.0, 0.0, 0.0, 0.0 };
d3d10device->ClearRenderTargetView(envMapRTView[view], clearColor);
d3d10device->ClearDepthStencilView(envMapDepthStencilView, D3D10_CLEAR_DEPTH, 1.0, 0);

ID3D10RenderTargetView* RTViews[1] = { envMapRTView[view] };
d3d10device->OMSetRenderTargets(1, RTViews, envMapDepthStencilView);

d3d10device->Draw(4, 4 * view);
}

// Restore old view port
d3d10device->RSSetViewports(1, &oldViewport);

// Restore old RT and DS buffer views
d3d10device->OMSetRenderTargets(1, oldRTViews, oldDSView);

SAFE_RELEASE(oldRTViews[0]);
SAFE_RELEASE(oldDSView);
As you can see first I save the old render target and depth stencil, then I set a new viewport, set some stats and then I enter the loop. Inside the loop I render into envMapRTView, which is a RenderTargetView onto the 5 face textures.
After the loop I restore the old settings and restore the saved RenderTarget (Maybe here is a problem?)

Last my render code:
render() {
UINT stride = sizeof(SkyBoxVertex);
UINT offset = 0;
d3d10device->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

d3d10device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3d10device->IASetInputLayout(vertexLayout);
d3d10device->RSSetState(rasterizerState);

for(int i=0; i < 5; i++) {
skyBoxFaceTextureSC->SetResource(envMapShaderView);
techniqueRender->GetPassByIndex(0)->Apply(0);
d3d10device->Draw(4, 4*i);
}
}

Inside the loop I render the 5 faces. First I set the current face texture and then I render 4 vertices.
If I comment out the first line of the loop (skyBoxFaceTextureSC->SetResource(envMapShaderView);), then I dont get the warning!
My main programm just calls update and then render in a loop:
g_skyBox->update();
g_skyBox->render();

Maybe you have an idea what could be the problem. Thanks for the help!

Share this post


Link to post
Share on other sites
Ah ok, so you're calling the first block of code again after the second. That's what I figured :)

As far as I know, doing SetResource(0) on the shader variable followed by an Apply call on the appropriate pass should unbind the texture from input and circumvent the warning. That's what our engine does, and I haven't noticed any warnings related to this. Make sure you put it before the first loop (in the update() function).

If that doesn't work, then perhaps it's a driver issue? Do you have the latest version for your hardware? You could try posting this in the Microsoft DX10 forum (forums.xna.com) and see if you get a response from one of those guys.

Share this post


Link to post
Share on other sites
These warnings are never driver related as the checks are only done by the debug layer. It is safe to ignore them as long as you know what you are doing. You can even disable it.

The warning is there to protect you from yourself. You may know that it is not uncommon to save the current state of the device in some variables inside the engine and only forwarded changes to the device. As the runtime unbind resources to resolve read write hazards it is possible that the real device state does not longer match the state that the engine has stored. In this case it may not forward a necessary change.

If you don’t use such a system at all you are most times safe. You will only run in problems if you really want to read and write to the same resource during one draw. In these cases the warnings are helpful to find this problem.

Share this post


Link to post
Share on other sites
@Zipster: Yeah, setting the resource to Zero before the update loop solved the problem!
Im gonna make some tests if I unbound the resource to avoid the warning or if I just live with the warning since its not a real error. Since I only care about speed maybe I omit the 2 Statements and just dont care about the warning.
But the most important thing is that I know how to solve such warnings.

Thanks to you and also to all the others!

Share this post


Link to post
Share on other sites
Quote:
Original post by Demirug
These warnings are never driver related as the checks are only done by the debug layer. It is safe to ignore them as long as you know what you are doing. You can even disable it.

Er my bad, I meant the DirectX (debug) runtime, and the latest SDK :)

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!