Why is Direct2D so slow?

Started by
7 comments, last by Erik Rufelt 12 years, 9 months ago
Hello! I've found the new Direct2D, and I want to use it for my HUD or the Browser of my engine. For some testing, I created a new window, which gets refreshed via FillRectangle() and draws a white Rectangle on it. When THIS window is open, the FPS of my engine drops from 300 to 59. Can I make it faster? Microsoft always says "Wow! Direct2D is soooo fast!". How to make it soooo fast? :( Here is the whole code:
 
#include "WD2DWindow.h"

WD2DWindow::WD2DWindow(void)
{
	D2DFactory = NULL;
	RT=NULL;
	BlackBrush=NULL;
}

WD2DWindow::~WD2DWindow(void)
{
	Cleanup();
}

void WD2DWindow::Cleanup()
{
	SaveRelease(RT);
	SaveRelease(BlackBrush);
	SaveRelease(WhiteBrush);
	 
	SaveRelease(D2DFactory);
}

HRESULT WD2DWindow::RenderWindow()
{
	HRESULT hr;
	RT->BeginDraw();



	RT->FillRectangle(RectF(
			WindowSize.left,
			WindowSize.top,
			WindowSize.right,
			WindowSize.bottom),
		BlackBrush);

	POINT Mouse;

	GetCursorPos(&Mouse);
	ScreenToClient(MyWindow,&Mouse);

	RT->DrawRectangle(
		RectF(
		Mouse.x-50,
		Mouse.y-50,
		Mouse.x+50,
		Mouse.y+50),
		WhiteBrush);

	V_RETURN(RT->EndDraw());	

	return S_OK;
}

HRESULT WD2DWindow::CreateFactory(HWND hw)
{
	HRESULT hr;
		
	V_RETURN(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &D2DFactory));
	MyWindow=hw;

	
	GetClientRect(hw, &WindowSize);
	V_RETURN(D2DFactory->CreateHwndRenderTarget( RenderTargetProperties(),	HwndRenderTargetProperties(	hw, SizeU( WindowSize.right - WindowSize.left, WindowSize.bottom - WindowSize.top)), &RT));
	
	V_RETURN(RT->CreateSolidColorBrush(	ColorF(ColorF::Black),&BlackBrush)); 
	V_RETURN(RT->CreateSolidColorBrush(	ColorF(ColorF::White),&WhiteBrush)); 

	return S_OK;
}

help! :(
Advertisement
Sounds like a vsync issue...
hm... could be. The Direct3D10 device is created without VSync. Can I disable it for D2D? Anyways, I don't think that VSync is the problem, because when I place many meshes into the world, the FPS goes down to 40. When I close the D2D viewport, the FPS goes up to >100 again. :(
Quote:
because when I place many meshes into the world, the FPS goes down to 40. When I close the D2D viewport, the FPS goes up to >100 again. :(

That doesn't mean it isn't v-sync related, it just means that drawing meshes takes finite time. FPS is a pretty horrible measure of performance anyway, don't give it so much weight.

You haven't really posted enough code for us to help.
Uhm... I don't know, what you need. but here is some important stuff:

DX10 DeviceCreation:
	DXUTInit( true, false, LPS cmdLine  ); // Parse the command line, show msgboxes on error,command line params    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen    //DXUTCreateWindow( L"WTech DX10" );   			DXUTCreateDevice( true, 0, 0 );

It gets created by DXUT, without VSync.


Rendering:
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ){    // Clear render target and the depth stencil         pd3dDevice->ClearRenderTargetView( DXUTGetD3D10RenderTargetView(), (float *)&ClearColor );    pd3dDevice->ClearDepthStencilView( DXUTGetD3D10DepthStencilView(), D3D10_CLEAR_DEPTH , 1.0, 0 );		const DXGI_SURFACE_DESC* pd3dsdBackBuffer = DXUTGetDXGIBackBufferSurfaceDesc();	D3D10_VIEWPORT Viewport;	Viewport.TopLeftX = 0;	Viewport.TopLeftY = 0;	Viewport.Width = pd3dsdBackBuffer->Width;	Viewport.Height = pd3dsdBackBuffer->Height;	Viewport.MinDepth = 0.0f;	Viewport.MaxDepth = 1.0f;	DXUTGetD3D10Device()->RSSetViewports( 1, &Viewport );	//TestMesh.RenderMe(); pd3dDevice->RSSetState(g_pRasterStateSolid);  		TheScene.RenderScene();		BrowserView.RenderBase();	TestD2D.RenderWindow();}


hm... And what else?
How are you creating your D2D render target? Do you create it once and hold on to it or do you recreate it every frame?
-Mike
You can see the device creation in my first post under the "HRESULT WD2DWindow::CreateFactory(HWND hw)"-function. It gets created at the start of my program.
Each time you see stable framerate close to 60 fps, consider vsync issue first (try changing display refresh rate in video settings to check).

It looks like you have created render target with presentOptions == D2D1_PRESENT_OPTIONS_NONE. In this mode EndDraw() function waits (sleeps) for VSync.

If you dont want this, you should set presentOptions to D2D1_PRESENT_OPTIONS_IMMEDIATELY.




I see you use CreateHwndRenderTarget in the code from your original post. If you want to use D2D together with D3D10 you can use CreateDxgiRenderTarget instead to render to your D3D back-buffer. When you create a HWND render target I guess D2D either creates a new D3D10 device and a new swapchain (which might use vsync), or draws in software mode instead..

This topic is closed to new replies.

Advertisement