OMSetRenderTargets

Started by
8 comments, last by Zipster 16 years, 3 months ago
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
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?
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
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??
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 :)
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 texturesID3D10Texture2D*  envMapDepthStencil; // Depth stencil 	ID3D10RenderTargetView*  envMapRTView[5]; // 5 render target views, each view is used for 1 face of the env mapID3D10DepthStencilView* envMapDepthStencilView; // Depth stencil view for environment mapID3D10ShaderResourceView* envMapShaderView[5];


Second, this is my init code (I guess its not relevant, but I post it for completeness):
// Depth StencilD3D10_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 viewD3D10_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 facesdstex.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 ViewsD3D10_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 ViewsD3D10_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!
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.
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.
@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!
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 :)

This topic is closed to new replies.

Advertisement