I have a WPF application that uses an HwndHost to display DirectX 9 content. I'm trying to use the PIX for Windows graphics profiler (which comes bundled with the DirectX SDK) to see render states and debug shaders in this DirectX window.
The problem I'm running into is that when I try to do a single-frame capture by pressing F12 in PIX, I sometimes don't get all the draw information for an entire frame. Also, when I try clicking on a DrawPrimitive call in PIX I get an error message saying "A call that previously succeeded failed during playback."
I think the reason for these problems is that WPF also uses DirectX to render all the WPF widgets. It does this on the WPF render thread which is hidden from the user in WPF. It looks like PIX uses calls to IDirect3DDevice9::Present to determine when a frame has ended. The WPF render thread is making calls to IDirect3DDevice9::Present in the middle of a frame of my render, causing PIX to get confused and truncate that frame (and errors when I try to look at DrawPrimitive calls).
Here's a little more information about how my application is set up: I have a WPF application with an HwndHost inside the main window that I use to show some 3D content. In the HwndHost::BuildWindowCore function, I create a window using CreateWindowEx which gives me an hwnd. I then initialize the DirectX 9 device using this hwnd. I then return the hwnd to the HwndHost. I hook up to the CompositionTarget.Render event which calls my unmanaged render function to draw everything in the scene.
I've tried getting this working using the D3DImage control to display my DirectX surface, but I run into the same problem.
It seems to me like the only way to solve this problem is to make sure that the WPF render thread has completely finished before doing a frame capture in PIX. That way, PIX won't be thrown off by any WPF DirectX calls. However, I don't see that there is any way to determine that WPF has finished rendering everything. There is a good post here that explains how to use the Dispatcher.Invoke function to determine when a single WPF element has completed rendering, but I need to know when everything has finished rendering.
I'm wondering if anybody has successfully set up a WPF application with their own DirectX window and was able to get PIX to work properly. Any help would be appreciated.
Related
In Silverlight there was an abillity to visualize GPU rendering.
eg: elements that was rendered on GPU would highlight in Magenta while everything else was normal colored.
Is there a similar feature for WPF ?
To make sure that what I'm trying to optimize is actually doing what i want it to ..
edit:
I found the function in Silvelright, it's called EnableCacheVisualization and apparantly this doesn't apply to WPF because WPF is running directly on GPU...
I wonder if there is a repaint / redraw visualizer instead like in browsers, which helps me find problems...
I am hoping this makes sense.
I am developing an application which will be a plugin inside of an existing application. The application has DirectX output that is placed in a WPF container/window.
I would like to get a "handle" on that DirectX output such that I can change basic properties of that Output such as switching to a stereoscopic 3d display, switching said output to full screen, etc.
I am not trying to manipulate the objects/information/etc. of that output, just how it is presented.
Any direction I can head in?
Thank you.
I've done some searching, but I can't find an exact answer on this. In my C# WPF app, I get the HWND pointer and pass it to a C dll. That C dll then attempts to use GDI calls to render an overlay of sorts on my window. There are no errors, but nothing appears. If I switch to a Windows Form, the dll can render over it fine. If I host a WindowsFormHost control and use the hwnd from there I have the same effect. I've seen information on the HwndHost control but it doesn't really look like what I want. Perhaps someone with more knowledge of that control can tell me differently. I read somewhere that an hwnd used for DirectX rendering (like WPF) can't also use GDI. Does this make my scenario impossible? I could fake it by overlaying a borderless form over the WPF window, but obviously that wouldn't be too pretty. Any thoughts or ideas?
You can't have WPF and GDI rendering to the same hwnd but you can easily have a child hwnd inside of your WPF app and let GDI render into it. Take a look at HwndHost for doing that. The section "Hosting a Microsoft Win32 Window in WPF" in this article has a little more details. It also talks about the various issues you'll run into (like airspace) when doing this type of interop.
I'm writing a Video application utilizing D3DImage. Frames are from memory and rendered as textures in native code with DirectX9, finally exposed by D3DImage to the WPF GUI. I have some Overlays on top, created with WPF's painting framework (Text, shapes etc.). Up to this point, it works like a charm.
Now, I would like encode the composited image from my underlying native C++ code. Video is 640x480 BGR, 25 FPS and has to be rendered and encoded in parallel, also on older Hardware with Windows versions down to XP/SP3.
Problem is, I cannot find any documentation describing the composition process between WPF and D3DImage. They 'blend' in some sense, but what is the meaning of this? And is it possible to get a handle to the WPF's part of the drawing or even the composited image in my native C++ code?
p.s: I'm also open to managed solutions, but didn't found much performant up to now.
There is global static method called "CompositionTarget.Rendering". Add an event to that and every time WPF renders that method will be called before WPF presents(the FPS can vary though). So just updated your renderTarget accordingly.
There might be a better way, but i'm not aware of it.
NOTE:: Also for D3DImage on WindowsXP you use a D3D9 device with a lockable renderTarget while on Vista/7 you use a D3D9Ex device with a non-lockable renderTarget. Just a note.
I'm looking for a way to overlay the graphical output of a third-party application with some lines, arcs etc. The applications accepts a handle of a window in which it will then display its output.
Using VC++ I put together a Windows Forms app in Visual Studio that draws (non-static) stuff in the onPaint-method of a form. Passing this form's handle to the other app, of course, overwrites my graphics stuff every time the other app redraws.
Can I somehow hook into this redrawing process to add my graphics after the other app redraws? Overlaying the form with a transparent panel onto which I draw could be an alternative. But real transparency for controls seem to be a problem of its own in Windows ...
You can't do this easily without getting notifications from the app. Which, if it doesn't provide them, would require setting a global hook with SetWindowsHookEx() so you can see the WM_ERASEBKGND and WM_PAINT messages. That's hard to get right, you cannot write such a hook in managed code. Since it requires injecting a DLL into the target process.
The only other option is that you put a transparent overlay on top of your form. Another form that has its TransparencyKey property set. The basic code you need to get that right is available in my answer in this thread. You just need to tweak it so it is permanent.