Search code examples
directx-11directcompute

D3DCSX 11 Problems hooking up and running FFT function


as per title I have problems setting up and running DirectX11 GPU-based FFTs using D3DCSX 11 (System: Win10 Pro + MS Visual Studio community 2022 (ver: 17.8.3), Windows kit 10 (ver: 10.0.22621.0) )

My includes and linked files:

#include <d3dcsx.h> 

#pragma comment(lib, "d3dcsx.lib") 

This should suffice as per MS reference guide. However, if I start my application and call D3DX11CreateFFT(..) for example, I get an error window stating d3dcsx.dll cannot be found. I worked around by copying d3dcsx_47.dll from the kit 10 bin directory into my executable directory and renaming it to d3dcsx.dll. While the error message vanished, now I get an E_OUTOFMEMORY error on calling functions like D3DX11CreateFFT(..) no matter what parameters I provide.

I guess something is wrong with the windows kit 10 installation but its all new installed on a new system. It seems the internal reference from d3dcsx.lib to the actual d3dcsx_47.dll is broken, but I have no idea how to fix this. Thanks a lot in advance for any help.


Solution

  • The short answer here is that implicit linking with D3DXCS.LIB / D3DCSX_47.DLL is broken. The import library doesn't reference the correct DLL name. While renaming the DLL for your local deployment works, it means that it can't find the PDB files on the Microsoft Symbol Server.

    Therefore, you should really use explicit linking if you are going to make use of D3DXCS11.

        auto hmod = LoadLibraryW(D3DCSX_DLL_W);
        if (!hmod)
            return 1;
    
        using PFN_D3DX11CreateFFT2DReal = HRESULT (WINAPI *)(
            ID3D11DeviceContext * pDeviceContext,
            UINT X,
            UINT Y,
            UINT Flags,
            _Out_ D3DX11_FFT_BUFFER_INFO * pBufferInfo,
            _Out_ ID3DX11FFT * *ppFFT
        );
    
        auto createFFT2DReal = reinterpret_cast<PFN_D3DX11CreateFFT2DReal>(static_cast<void*>(GetProcAddress(hmod, "D3DX11CreateFFT2DReal")));
        if (!createFFT2DReal)
            return 1;
        
        D3DX11_FFT_BUFFER_INFO  fftbufferinfo = {};
        CComPtr<ID3DX11FFT> pFFT = 0;
        HRESULT hr = createFFT2DReal(pContext, 16, 16, 0, &fftbufferinfo, &pFFT);
        if (FAILED(hr))
            return 1;
    

    And you need to copy the DLL file to your local build directory:

    copy "C:\Program Files (x86)\Windows Kits\10\Redist\D3D\x64\d3dcsx_47.dll" $(OutDir)
    

    The other problem is that the D3DXCS11 library will return E_OUTOFMEMORY for all kinds of errors, so it's not particular informative.