Poor performance of ID2D1RenderTarget

Started by
1 comment, last by who_say_pawno 1 year, 1 month ago

Hi. I need to draw text into a D3D11 texture, but I have encountered very poor performance and don't know how to fix it. I use DirectWrite and D2D1 to render text. It suits me very well because it allows me to create the effects I need and can work with unicode characters (emoticons, etc.).

I do the following:

  1. Create a D3D11 texture (ID3D11Device::CreateTexture2D)
  2. Create a DXGI render target via D2D1 (ID2D1Factory7::CreateDxgiSurfaceRenderTarget)
  3. Render text inside ID2D1RenderTarget::BeginDraw and ID2D1RenderTarget::EndDraw

And so. Several textures with text can be created per frame in the game (2-5). After creating a texture (or taking it from the pool), the following code is executed:

ID2D1RenderTarget::BeginDraw();
// render text, etc...
ID2D1RenderTarget::EndDraw();

But the game started to freeze a lot. I measured the code execution time, and noticed that the EndDraw call takes a very long time. From 1 to 5 ms (I have a good hardware and this is VERY much for it). I commented out the text rendering code and left ONLY the ID2D1RenderTarget::BeginDraw and ID2D1RenderTarget::EndDraw calls. I got exactly the same results.

It's not about DirectWrite, etc. It's just that calling BeginDraw and EndDraw for a DXGI surface takes a very long time. But what other way can I get D2D1 to draw what I need into a D3D11 texture in runtime?

Microsoft writes here https://learn.microsoft.com/en-us/windows/win32/direct2d/improving-direct2d-performance​ it:

When rendering to a DXGI surface, Direct2D saves the state of the Direct3D devices while rendering and restores it when rendering is completed. Every time that a batch of Direct2D rendering is completed, the cost of this save and restore and the cost of flushing all the 2D operations are paid, and yet, the Direct3D device is not flushed. Therefore, to increase performance, limit the number of rendering switches between Direct2D and Direct3D.

But LOL, even if I combine everything into one texture and call BeginDraw and EndDraw once per frame - ~5 ms is a LOT.

For clarity:

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

Advertisement

I can't reproduce these freezes in an empty project yet, apparently because D3D11 is not loaded with anything. I'll provide the code if I can.

I'll have two number 9s, a number 9 large, a number 6 with extra dip, a number 7, two number 45s, one with cheese, and a large soda.

This topic is closed to new replies.

Advertisement