Jump to content
  • Advertisement
Sign in to follow this  
rjbishop

setRenderTarget broken (SlimDX, DirectX9)

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

All,

I have been re-writing my Software Defined Receiver application to take better advantage of knowledge learned in my DirectX adventures. This is essentially a 2D application, but lends itself well to the power of DirectX3d.

I was finishing up my spectrum renderer, and decided to upgrade my NVidia driver to the latest (Windows 7 64bit). To my dismay, one VERY simple aspect of my code is now broken, and I'm baffled- this was all working great on multiple machines prior to upgrading my NVidia drivers.

Basically, I initially create a render surface to draw my rather "static" features of the spectrum- background gradient, dbM grid, labels, and frequency strip (much like a tape measure). This is saved away and re-used each call to render. When it comes time to render, I copy my static surface to the backbuffer using StretchRect, then draw my frequency spectrum into the backbuffer with my Transforms. The problem is, it seems my "static" surface is getting overwritten by the spectrum draw routines- the next render, It appears I am copying not only my static surface into the backbuffer, but also all the primitives that were drawn into the backbuffer the prevous render. This happens over and over, until my window is a mess. What is wierd, is if I change my transforms (zoom and translate) several times as part of normal operation, eventually DirectX will "Catch" and start drawing normally (i.e. keeping my static surface intact and not corrupt it with primitive drawing to the backbuffer. It takes quite a bit of redrawing with different transforms for this "catch" to occur. Once it does, all is well.

Let me show the appropriate tidbits of code:

Here's a snippet from my OnResourceLoad():


// Get our waterfall rendering surface
SlimDX.Direct3D9.SurfaceDescription desc; // Declare a SurfaceDescription
Context9.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,spectrumColor,1f,0);
origTarget_ = Context9.Device.GetRenderTarget(0); // Get the current DirectX render surface
desc = origTarget_.Description; // ..and load it's Description





Here is where I create my "static" surface, and draw to it. This is only done when I need to change my transforms or scale.


surface_ = Surface.CreateRenderTarget(Context9.Device, // Create a new render surface
WindowWidth, // ..using current Width
WindowHeight, // ..using current Height
Format.X8R8G8B8, // ..using our format
MultisampleType.None,
//desc.MultisampleType, // ..using existing MS Type
desc.MultisampleQuality, // ..using existing MS Quality
false); // This surface doesn't need to be lockable
Context9.Device.SetRenderTarget(0, surface_); // Set our new surface as render target
Context9.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, spectrumColor, 1.0f, 0); // Clear the target
//Context9.Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.WhiteSmoke, 1.0f, 0); // Clear the target
Context9.Device.BeginScene(); // Begin drawing
if (!(drawWaterfall))
{
DrawBackgroundGradient();
DrawSpectrumGrid(); // Draw the Spectrum Grid
}
DrawMarkerGrid(); // Draw the db Marker text
DrawFreqMarkers(); // Draw the frequency marker text
Context9.Device.EndScene(); // End drawing
Context9.Device.SetRenderTarget(0, origTarget_); // Set the rendertarget back to the original target






And here is where I do my actual Rendering on every render call



// The first thing we need to do is copy our previously drawn Grid surface to the current backbuffer.
// This data was previously drawn during the OnResourceLoad routines.
Surface backbuf = null; // Declare a surface
Context9.Device.SetRenderTarget(0, origTarget_);
Context9.Device.Clear( // Clear the backbuffer
ClearFlags.Target | ClearFlags.ZBuffer, // our flags
waterfallLow, // using our fill color
1.0f, // ZDepth
0); // No stencil
rect = new Rectangle(0, 0, WindowWidth, WindowHeight); // Define stretch Rectangle
backbuf = Context9.Device.GetBackBuffer(0, 0); // Get the current backbuffer
Context9.Device.StretchRectangle(surface_, // Copy from grid surface to current backbuffewr
rect, // Source rectangle
backbuf, // Destination surface
rect, // Destination rectangle
TextureFilter.None); // Texture filter to use
Context9.Device.BeginScene(); // Now that we have done this, prepare for normal rendering
DrawSpectrum();
DrawFilterVisuals();
DrawMouseCursor();
// All done
Context9.Device.EndScene();
Context9.Device.Present();




Is it really concievable that this worked fine before on my Desktop (Windows 7 64bit) as well as my Laptop (XP SP3, HP with el-cheapo video), but is now broken after simply upgrading my NVidia driver for Windows 7? It seems like such a simple thing, and I can't believe this driver would be released with a bug like this. I think it's more my code, but what am I doing wrong?

Thanks!

-Reid-
W0CNN
CNNSDR Development

Share this post


Link to post
Share on other sites
Advertisement
Have you enabled to the debug runtimes and checked for any messages? Also, have you tried debugging in PIX? You can go through a frame call-by-call and see the results. You can also switch to the reference device, which can help finding out if you've encountered a driver bug.

Share this post


Link to post
Share on other sites
Matt,

Good thought on checking Debug, PIX, and the reference driver.

Debug only shows "normal" warnings such as "ignoring redundant SetRenderState", "ignoring redundant SetTextureStageState", etc.

PIX- This puts out a LOT of info, and I just tried it tonight. So far, nothing that I can see that is out of the ordinary- but more to go here.

Reference Device- BINGO. The Reference device is working perfectly, per my code. None of the problems that I found with NVidia.

I am absolutely amazed about this. So far, I have not found the NVidia misbehaving on my machine with these new drivers, other than my own code. It just seems so simple a thing to use a temporary surface as a "cache", and have that cache intermingled with the backbuffer improperly. You would think this would show up SOMEWHERE else, wouldn't you? These drivers were put out by NVidia on June 15th, so maybe there just hasn't been enough feedback.

Thanks for the suggestions. Either way, if anybody has any thoughts on my rather simple technique above, that would be great.

-Reid-
W0CNN
CNNSDR Development

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!