• Advertisement
Sign in to follow this  

Direct2D and AMD Firepro GPU

This topic is 829 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

recently i started project that involved some rendering with GDI and Direct2D. Everything went swift until i was forced to change my laptop.

On new GPU (AMD Firepro m4170) drawing with Direct2D causes not redrawing graphics, it looks like underlying DC bitmap is not affected.

I've tested code before on Intel HD 4600, AMD Radeon HD6470m, WARP device and all was fine. DirectX debug layer also didn't yield any warning nor errors. All drivers are up-to-date.

 

Code:

void Init()
{
    if (D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &_d2dFactory) != S_OK)
    {
	throw std::runtime_error("Failed to create D2D1 factory");
    }

    D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
    D2D1_RENDER_TARGET_TYPE_DEFAULT,
	D2D1::PixelFormat(
	DXGI_FORMAT_B8G8R8A8_UNORM,
	D2D1_ALPHA_MODE_IGNORE),
	0,
	0,
	D2D1_RENDER_TARGET_USAGE_NONE,
	D2D1_FEATURE_LEVEL_DEFAULT
	);

    if (_d2dFactory->CreateDCRenderTarget(&props, &_d2dRenderTarget) != S_OK)
    {
	throw std::runtime_error("Failed to DC Render Target");
    }
}

int Draw(CDC* dc)
{
    CRect rectWindow;
    dc->GetWindow()->GetClientRect(&rectWindow);

    RECT ClientRect;
    ClientRect.left = rectWindow.left;
    ClientRect.right = rectWindow.right;
    ClientRect.top = rectWindow.top;
    ClientRect.bottom = rectWindow.bottom;

    auto returnCode = _d2dRenderTarget->BindDC(dc->GetSafeHdc(), &ClientRect);
    if (returnCode != S_OK)
    {
	LOG_ERROR("Failed to BindDC()");
        return 0;
    }
    
    _d2dRenderTarget->BeginDraw();
    _d2dRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
    _d2dRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));

    //...Drawing...
    //...But it can be also empty...

   result = _d2dRenderTarget->EndDraw();
   if (result == D2DERR_RECREATE_TARGET)
   {
	Reinit();
   }
   else if (result != S_OK)
   {
        LOG_ERROR("Failed to EndDraw()");
	return 0;
   }
}

Much thanks for any ideas!

 

Share this post


Link to post
Share on other sites
Advertisement

It looks like weird bug in AMD driver, but i managed to fix this one, change DCRenderTarget to HWNDRenderTarget and get HWND from DC.

Posting code snippet so maybe someone will stumble on similar problem and it will help smile.png

void D2DRenderer::CreateRenderTarget(CDC* dc, RECT rect)
{
	auto hwnd = WindowFromDC(*dc);
	auto props = D2D1::RenderTargetProperties(
		D2D1_RENDER_TARGET_TYPE_HARDWARE,
		D2D1::PixelFormat(
		DXGI_FORMAT_B8G8R8A8_UNORM,
		D2D1_ALPHA_MODE_IGNORE));

	HRESULT hr = _d2dFactory->CreateHwndRenderTarget(
		props,
		D2D1::HwndRenderTargetProperties(
		hwnd,
		D2D1::SizeU(
		rect.right - rect.left,
		rect.bottom - rect.top)
		),
		&_d2dRenderTarget
		);
}

Share this post


Link to post
Share on other sites
Are you sure it's the *RenderTarget change that "fixed" the bug and not the fact that you switched from D2D1_RENDER_TARGET_TYPE_DEFAULT to D2D1_RENDER_TARGET_TYPE_SOFTWARE (which doesn't use your graphics card anymore)?

Share this post


Link to post
Share on other sites

Forgot to change it when i tested software mode rendering speed. A copy/paste error, with Hardware also works correct smile.png

Edited by Armus

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement