DirectX in .Net as COM interop. RRS feed

  • General discussion

  • Hello. I'm want to discuss question about "how to debug COM interop" in the DirectX interop scenarios. I'm have pure C# DXGI component wrapper on codeplex. Here it is MDXGI. There are not a problem to write interop for all DirectX component. But the main problem is that some funtions doesn't work and i don't know why. I try use many of possible signatures but problem still exist. Is there are some mechanism to check what actualy does in interop code. And why there are no any pure .Net interop. All working interop code for DirectX use CLI C++.
    Tuesday, October 19, 2010 1:24 PM

All replies

  • Is there a specific call i could look at? a small snippet of code that would crash and burn would be nice.
    Tuesday, October 19, 2010 7:22 PM
  • Problem code:

    var factory = DXGIMethods.CreateFactory1();
    IDXGIAdapter1 adapter;
    factory.EnumAdapters1(0, out adapter);
    ID3D10Device device;
    D3D10Methods.CreateDevice(adapter, D3D10_DRIVER_TYPE.Hardware, D3D10_CREATE_DEVICE_FLAG.Zero, out device);
    var desc = new DXGI_SWAP_CHAIN_DESC();
    desc.BufferCount = 1;
    desc.BufferDesc.Width = 640;
    desc.BufferDesc.Height = 480;
    desc.BufferDesc.Format = DXGI_FORMAT.R8G8B8A8_UNORM;
    desc.BufferDesc.RefreshRate.Numerator = 60;
    desc.BufferDesc.RefreshRate.Denominator = 1;
    desc.BufferUsage = DXGI_USAGE.RenderTargetOutput;
    desc.OutputWindow = panel1.Handle;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Windowed = true;
    IDXGISwapChain swapChain;
    factory.CreateSwapChain(device, desc, out swapChain);
    IUnknown res;
    var hr = swapChain.GetBuffer(1, typeof(ID3D10Texture2D).GUID, out res);
    if (res == null) throw new Exception("NULL"); // HERE!!!
    var TexRt = (ID3D10Texture2D)res;

    Original declaration:

      IDXGISwapChain : public IDXGIDeviceSubObject
        virtual HRESULT STDMETHODCALLTYPE Present( 
          /* [in] */ UINT SyncInterval,
          /* [in] */ UINT Flags) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetBuffer( 
          /* [in] */ UINT Buffer,
          /* [annotation][in] */ 
          __in REFIID riid,
          /* [annotation][out][in] */ 
          __out void **ppSurface) = 0;
        virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( 
          /* [in] */ BOOL Fullscreen,
          /* [annotation][in] */ 
          __in_opt IDXGIOutput *pTarget) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( 
          /* [annotation][out] */ 
          __out BOOL *pFullscreen,
          /* [annotation][out] */ 
          __out IDXGIOutput **ppTarget) = 0;
          /* [annotation][out] */ 
          __out DXGI_SWAP_CHAIN_DESC *pDesc) = 0;
        virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( 
          /* [in] */ UINT BufferCount,
          /* [in] */ UINT Width,
          /* [in] */ UINT Height,
          /* [in] */ DXGI_FORMAT NewFormat,
          /* [in] */ UINT SwapChainFlags) = 0;
        virtual HRESULT STDMETHODCALLTYPE ResizeTarget( 
          /* [annotation][in] */ 
          __in const DXGI_MODE_DESC *pNewTargetParameters) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetContainingOutput( 
          /* [annotation][out] */ 
          __out IDXGIOutput **ppOutput) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( 
          /* [annotation][out] */ 
          __out DXGI_FRAME_STATISTICS *pStats) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( 
          /* [annotation][out] */ 
          __out UINT *pLastPresentCount) = 0;

    My declaration:

    [ComImport, Guid("310d36a0-d2e7-4c0a-aa04-6a9d23b8886a")/*, SuppressUnmanagedCodeSecurity*/]
    public interface IDXGISwapChain : IDXGIDeviceSubObject
        HResult Present(UInt32 syncInterval, DXGI_PRESENT flags);
        HResult GetBuffer(UInt32 buffer, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IUnknown surface);
        HResult SetFullscreenState(Boolean fullscreen, IDXGIOutput target);
        HResult GetFullscreenState(out Boolean fullscreen, out IDXGIOutput target);
        HResult GetDesc(out DXGI_SWAP_CHAIN_DESC desc);
        HResult ResizeBuffers(UInt32 bufferCount, UInt32 width, UInt32 height, DXGI_FORMAT newFormat, DXGI_SWAP_CHAIN_FLAG swapChainFlags);
        HResult ResizeTarget(DXGI_MODE_DESC newTargetParameters);
        HResult GetContainingOutput(out IDXGIOutput output);
        HResult GetFrameStatistics(out DXGI_FRAME_STATISTICS pStats);
        HResult GetLastPresentCount(out UInt32 lastPresentCount);

    I try many other combination as IntPtr and so on, but it always return 0 as HResult and null as buffer.


    Wednesday, October 20, 2010 9:56 AM
  • Downloaded the latest copy of your code from codeplex, DXGIMethods is not in there, neither are any of the D3D10 enums, can you post a more recent snapshot so i can easily run the problemenatic code ?
    Thursday, October 21, 2010 11:15 PM
  • Yes, codeplex copy has legasy code. But publish new code is real problem because many dependencies. Actualy problem in method IDXGISwapChain::GetBuffer which declared:

    HRESULT GetBuffer(
     [in]    UINT Buffer,
     [in]    REFIID riid,
     [in, out] void **ppSurface

    It looks that it has in and out attribute for ppSurface. I don't sure how it can be in, but typical usage from C++ like this:

    ID3D10Texture2D *p_RT;
    pSwapChain->GetBuffer(0, __uuidof(p_RT), reinterpret_cast<void**>(&p_RT));
    In general I must interop it like: out IntPtr but howlater I can convert it to interface?
    Saturday, October 23, 2010 10:29 AM