directx11 – How to correctly initialize Direct2D with DirectX 11

I have a problem with creating Direct2D with DirectX11 .I have tried two methods to initialize Direct2D.

In the first attempt, I’ve create the surface pointer to the back buffer in DX11 and passed it to CreateDxgiSurfaceRenderTarget. I get an error from the function stating The parameter is incorrect.

In the second attempt, I did the same but more complicated. I used DXGI and I need to use a new interface Direct2D 1.1 instead of using ID2D1RenderTarget. I need to use ID2D1DeviceContex but in here i get a error from the function direct2d.factory1->CreateDevice() and the error is the same, the parameter is incorrect.

struct Direct2D {

    ID2D1Device *device = NULL;
    ID2D1DeviceContext *device_context = NULL;
    ID2D1Factory *factory = NULL;
    ID2D1Factory1 *factory1 = NULL;
    ID2D1RenderTarget *render_target = NULL;
    ID2D1SolidColorBrush *gray_brush = NULL;
    ID2D1SolidColorBrush *blue_brush = NULL;

    void init();
    void draw();
};

struct Direct3D {

    Direct2D direct2d;
    ID3D11Device *device = NULL;
    ID3D11DeviceContext *device_context = NULL;
    IDXGISwapChain *swap_chain = NULL;
    
    ID3D11RenderTargetView *render_target_view = NULL;
    ID3D11DepthStencilView *depth_stencil_view = NULL;
    ID3D11Texture2D *depth_stencil_buffer = NULL;
    ID3D11Texture2D* back_buffer = NULL;
    IDXGISurface* back_buffer2 = NULL;
    
    UINT quality_levels;

    Matrix4 perspective_matrix;

    void init(const Win32_State *win32);
    void shutdown();
    void resize(const Win32_State *win32);
};

void Direct2D::init()
{

    HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory1));
    HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory));

    float dpi_x;
    float dpi_y;
    factory->GetDesktopDpi(&dpi_x, &dpi_y);

    D2D1_RENDER_TARGET_PROPERTIES rtDesc = D2D1::RenderTargetProperties(
        D2D1_RENDER_TARGET_TYPE_HARDWARE,
        D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), dpi_x, dpi_y
    );

    IDXGISurface *surface = NULL;
    HR(direct3d.swap_chain->GetBuffer(0, IID_PPV_ARGS(&surface)));

    //HR(factory->CreateDxgiSurfaceRenderTarget(surface, &rtDesc, &render_target));
    
    //HR(render_target->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::LightSlateGray),&gray_brush));
    //HR(render_target->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CornflowerBlue),&blue_brush));
}

void Direct3D::init(const Win32_State *win32) 
{

    D3D_FEATURE_LEVEL feature_level;
    HRESULT hr = D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, create_device_flag, 0, 0, D3D11_SDK_VERSION,&device, &feature_level, &device_context);

    if (FAILED(hr)) {
        MessageBox(0, "D3D11CreateDevice Failed.", 0, 0);
        return;
    }

    if (feature_level != D3D_FEATURE_LEVEL_11_0) {
        MessageBox(0, "Direct3D Feature Level 11 unsupported.", 0, 0);
        return;
    }


    HR(device->CheckMultisampleQualityLevels(
        DXGI_FORMAT_R8G8B8A8_UNORM, 4, &quality_levels));
    //assert(m4xMsaaQuality > 0);

    DXGI_SWAP_CHAIN_DESC sd;
    sd.BufferDesc.Width = win32->window_width;
    sd.BufferDesc.Height = win32->window_height;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    
    if (true) {
        sd.SampleDesc.Count = 4;
        sd.SampleDesc.Quality = quality_levels - 1;
    } else {
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
    }

    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.BufferCount = 1;
    sd.OutputWindow = win32->window;
    sd.Windowed = true;
    sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    sd.Flags = 0;

    IDXGIDevice* dxgi_device = 0;
    HR(device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgi_device));

    IDXGIAdapter* dxgi_adapter = 0;
    HR(dxgi_device->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgi_adapter));

    IDXGIFactory* dxgi_factory = 0;
    HR(dxgi_adapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgi_factory));

    HR(dxgi_factory->CreateSwapChain(device, &sd, &swap_chain));
    

    // Init directx 2d
    HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &direct2d.factory));
    HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &direct2d.factory1));
    
    HR(direct2d.factory1->CreateDevice(dxgi_device, &direct2d.device));
    HR(direct2d.device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &direct2d.device_context));
    
    IDXGISurface *surface = NULL;
    HR(swap_chain->GetBuffer(0, __uuidof(IDXGISurface), (void **)surface));

    auto props = BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE));

    ID2D1Bitmap1 *bitmap = NULL;
    HR(direct2d.device_context->CreateBitmapFromDxgiSurface(surface, props, &bitmap));

    direct2d.device_context->SetTarget(bitmap);

    float32 dpi_x;
    float32 dpi_y;
    direct2d.factory->GetDesktopDpi(&dpi_x, &dpi_y);

    direct2d.device_context->SetDpi(dpi_x, dpi_y);


    RELEASE_COM(dxgi_device);
    RELEASE_COM(dxgi_adapter);
    RELEASE_COM(dxgi_factory);

    resize(win32);
}

void Direct3D::resize(const Win32_State *win32)
{
    assert(device);
    assert(device_context);
    assert(swap_chain);


    RELEASE_COM(render_target_view);
    RELEASE_COM(depth_stencil_view);
    RELEASE_COM(depth_stencil_buffer);


    // Resize the swap chain and recreate the render target view.

    HR(swap_chain->ResizeBuffers(1, win32->window_width, win32->window_height, DXGI_FORMAT_R8G8B8A8_UNORM, 0));

    ID3D11Texture2D* back_buffer = NULL;
    HR(swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&back_buffer)));
    HR(device->CreateRenderTargetView(back_buffer, 0, &render_target_view));
    RELEASE_COM(back_buffer);

    // Create the depth/stencil buffer and view.

    D3D11_TEXTURE2D_DESC depth_stencil_desc;

    depth_stencil_desc.Width = win32->window_width;
    depth_stencil_desc.Height = win32->window_height;
    depth_stencil_desc.MipLevels = 1;
    depth_stencil_desc.ArraySize = 1;
    depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;

    // Use 4X MSAA? --must match swap chain MSAA values.
    if (true) {
        depth_stencil_desc.SampleDesc.Count = 4;
        depth_stencil_desc.SampleDesc.Quality = quality_levels - 1;
    } else {
        depth_stencil_desc.SampleDesc.Count = 1;
        depth_stencil_desc.SampleDesc.Quality = 0;
    }

    depth_stencil_desc.Usage = D3D11_USAGE_DEFAULT;
    depth_stencil_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depth_stencil_desc.CPUAccessFlags = 0;
    depth_stencil_desc.MiscFlags = 0;

    HR(device->CreateTexture2D(&depth_stencil_desc, 0, &depth_stencil_buffer));
    HR(device->CreateDepthStencilView(depth_stencil_buffer, 0, &depth_stencil_view));


    // Bind the render target view and depth/stencil view to the pipeline.

    device_context->OMSetRenderTargets(1, &render_target_view, depth_stencil_view);


    // Set the viewport transform.

    D3D11_VIEWPORT mScreenViewport;
    mScreenViewport.TopLeftX = 0;
    mScreenViewport.TopLeftY = 0;
    mScreenViewport.Width = static_cast<float>(win32->window_width);
    mScreenViewport.Height = static_cast<float>(win32->window_height);
    mScreenViewport.MinDepth = 0.0f;
    mScreenViewport.MaxDepth = 1.0f;

    device_context->RSSetViewports(1, &mScreenViewport);

    perspective_matrix = get_perspective_matrix(win32->window_width, win32->window_height, 1.0f, 1000.0f);
}