sharpdx / SharpDX

SharpDX GitHub Repository
http://sharpdx.org
MIT License
1.7k stars 639 forks source link

[SharpDX.Direct2D1 v2.6.3] CustomEffectBase PropertyBinding: performance issue due to internal exceptions #529

Open morpheusxx opened 9 years ago

morpheusxx commented 9 years ago

I'm using SharpDX 2.6.3 to develop a WinForms based application the uses Direct2D (DX11_1 target). While all inbuilt Effects are working well, the example "RippleEffect" (and my own shader effects) causes huge performance drops when Properties are accessed (see https://github.com/sharpdx/SharpDX-Samples/blob/master/WindowsAppStore81/D2DCustomPixelShaderEffect/EffectRenderer.cs#L80-L97).

To illustrate the effect see following screenshots: when accessing properties in each Render call, the performance drops to ~9 fps, while when not accessing properties the result is at ~500 fps.

Calling SetValue(...): custom_effect_01_perframe_update

Not calling SetValue(...): custom_effect_02_no_update

A performance profile shows internal NullReferenceExceptions when accessing NativeGetInt (no idea why, all my properties are float and similar). profile

A downgrade to 2.6.2 didn't change the behavior.

Is there a fix (or workaround) for this issue? It's currently a show stopper for finishing the migration of a DX9 application to DX11/D2D1.

morpheusxx commented 9 years ago

I have investigated this issue more in detail:

It only happens when running the application inside VS debugger (vshost). If you are running the program standalone it works correctly! Even attaching debugger later works then.

So the problem seems to be only related to VS debugging environment, but a fix would be very appreciated though.

xoofx commented 9 years ago

Thanks for the report. This could be a bug in the binding process. Unfortunately, I don't have enough spare time currently to dig into this. Let me know if you can investigate this by compiling the source tagged 2.6.3 and debug from there.

morpheusxx commented 9 years ago

I was finally able to build a custom sharpdx version and debugged this problem.

Inside Utilities.Write the destination pointer is 0. This happens for every call, so I think that probably none of my variables read the shader.

Unfortunately the stacktrace has one "external code", so I can't follow where the dataPointer gets 0.

sharpdx_nre

The step before the [external code] and the local varibles: sharpdx_nre_caller2

My calling code: sharpdx_nre_caller

Can you check this problem? If you can give me a hint, I could try some code modifications.

morpheusxx commented 9 years ago

FYI: adding a sanity check for null pointers does solve my problems:

        public static void Write<T>(IntPtr destination, ref T data) where T : struct
        {
            unsafe
            {
                // Sanity check for null pointers. TODO: Calling code should be checked!
                if (destination == IntPtr.Zero)
                    return;
                Interop.CopyInline((void*)destination, ref data);
            }
        }

Every 2nd call to this methods fails in my case. Could this be an indication for another issue in calling code?

This check also improves performance, as costly NREs are avoided now.

morpheusxx commented 9 years ago

@xoofx do you think that the above fix is enough? I would supply a pull request then.

But if this is only an indicator for a deeper issue, it would be good if you could check it more in detail.