See the question and my original answer on StackOverflow

Here's a solution that only uses WIC and DirectX 9:

public partial class MainWindow : Window
{
    private readonly D3DImage _d3dImage = new();

    // you can keep the device if you want to use it
    private readonly SharpDX.Direct3D9.Device _device;

    public MainWindow()
    {
        InitializeComponent();
        Loaded += (s, e) => LoadJpegToTexture(@"sample.bmp");

        var hwnd = new WindowInteropHelper(this).EnsureHandle();
        using var context = new SharpDX.Direct3D9.Direct3D();
        _device = new SharpDX.Direct3D9.Device(context,
            0,
            SharpDX.Direct3D9.DeviceType.Hardware,
            hwnd,
            SharpDX.Direct3D9.CreateFlags.HardwareVertexProcessing,
            new SharpDX.Direct3D9.PresentParameters()
            {
                Windowed = true,
                SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard,
                DeviceWindowHandle = hwnd,
                PresentationInterval = SharpDX.Direct3D9.PresentInterval.Immediate,
            });

        img.Source = _d3dImage;
    }

    private void LoadJpegToTexture(string filePath)
    {
        using var imagingFactory = new SharpDX.WIC.ImagingFactory2();
        using var decoder = new SharpDX.WIC.BitmapDecoder(imagingFactory, filePath, SharpDX.WIC.DecodeOptions.CacheOnDemand);
        using var frame = decoder.GetFrame(0);

        // depending on the image's pixel format, you must convert the frame
        // to match DirectX 9 RGBA surface format
        using var converter = new SharpDX.WIC.FormatConverter(imagingFactory);
        converter.Initialize(frame, SharpDX.WIC.PixelFormat.Format32bppBGRA);

        // create a render target surface
        using var surface = SharpDX.Direct3D9.Surface.CreateRenderTarget(_device,
            frame.Size.Width,
            frame.Size.Height,
            SharpDX.Direct3D9.Format.A8R8G8B8,
            SharpDX.Direct3D9.MultisampleType.None,
            0,
            true
            );

        // copy pixels from WIC to surface
        var rc = surface.LockRectangle(SharpDX.Direct3D9.LockFlags.None);
        converter.CopyPixels(rc.Pitch, rc.DataPointer, frame.Size.Height * rc.Pitch);
        surface.UnlockRectangle();

        _d3dImage.Lock();
        _d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface.NativePointer, true);
        _d3dImage.AddDirtyRect(new Int32Rect(0, 0, frame.Size.Width, frame.Size.Height));
        _d3dImage.Unlock();
    }
}