How to use D2D with D3D11?

Started by
57 comments, last by Magmatwister 12 years, 8 months ago
Quote:DieterVW: The SDK contains the headers, but the runtime is shipped in the OS.


DieterVW,

DirectX9 had a number of versions. I suspect that the DX9 effects library was the main difference between versions, but nevertheless it could be considered as a vehicle to fix outstanding problems, which is why I (and GPUShader) asked. However, I appreciate that D3D11 applications are not expected to query the version of D3D11 that is installed, so you are limited in what you can fix.

That leaves me with a number of concerns. I appreciate that we are now outside the scope of this topic, but since you are involved with the DX team (and since I have no other contacts), please advise where I should take these problems:

1) D3DX11CreateEffectFromMemory appears to be absent from "d3dx11_42.dll". A version exists in "[Program Files]\Microsoft DirectX SDK (August 2009)\Utilities\Source\Effects11" but it has bugs, is not in the form of a dll (and so can only be used with C/C++), and might not be redeployable.

2) The fxc compiler with the Aug 2009 SDK is taking 7 minutes to compile a pixel shader that took only around 45 seconds with the previous SDK [Edit Oct 12th : Times estimates replaced with actual values after tests were carried out with various SDKs]. Cutting the shader down, there appears to be no single cause: it just compiles the whole lot slowly. 7 minutes (or 10 minutes for that group of shaders) is too long to iterate the very complex numerical maths that this shader performs (we are doing real time anatomical simulation, mesh generation and deformation on the GPU). Where can I report and discuss fxc issues?

Regarding your point about looking forward:

A problem with the D3D11 "shared texture" approach is that it doesn't work well with existing software architectures. For example, when upgrading our D3D9 graphics library with a D3D10.1 device I could change routines that used to draw 2D objects by creating 3D primitives to call D2D1 instead. However with the D3D11 shared surface method this is more difficult. Firstly I have to worry whether calling AcquireSync on the mutex hundreds or thousands of times per frame is a good idea in terms of good GPU/CPU usage. Secondly, the results are different. With the D3D10.1 approach, the 2D interleaves correctly with non-depth buffered 3D. This is important in some of our applications. With the D3D11 "single shared texture" approach, the 2D is put on top of all other 3D.

JB.

---

PS: I suspect that we have hit the limit of D2D1 performance, so I don't want to draw this out unnecessarily. However, for your information:

Profiling my application shows that the time appears to be spent mostly in the CPU, not GPU. Approx 3/4 of time is spent in DrawText calls, and most of the remainder in EndDraw. D2D1 is presented as a "high performance" way of drawing text, but from my results this is not the case in terms of speed - and indeed why should it be much faster than GDI, because GDI was not deliberatly inefficient. D2D1 is probably faster than GDI+. Why D3DXFont was so fast is a mystery, though they may have cached each letter of the alphabet, which may not be possible with D2D1/DirectWrite given its support for underlining etc. However the documentation should make this clear.

Quotes like "In fact, with the exception of a few specific operations such as per-primitive anti-aliasing, you'd be hard pressed to outperform Direct2D with Direct3D" (Kenny Kerr) are misleading. For 2D line/shape drawing D2D1 is about the same speed as any other not-particularly-optimized D3D approach.

[Edit: I've done some more thorough tests now. In my tests, non-filled rectangles were slow - about 1/10th the speed of the D3D "line list" equivalents. Filled rectangles were fast, and achieved 81% of the expected pixel rate of the graphics card.]

Caching text layers is not a great performance winner for us because most of the text does indeed change every frame. Using multithreading is an interesting idea, but we already have two threads that are effectively real time (graphics (40 ms/frame) and force feedback (3 ms frame max)) and that would limit us to using quad (or more) cores/processors.

For the sake of progress for Direct3D, please ensure that all my concerns in this discussion are filed as developer feedback for D3D11/D2D1 (or alternatively tell me how/where to file them).

Sincerely,

JB.

[Edited by - JB2009 on October 12, 2009 8:03:18 AM]
Advertisement
I didn't mean to cause confusion, when I say that the SDK is final I mean that the D3D/D2D API is final. The D3DX libraries and Effects are independent, they are provided in their entirety as SDK components and not part of the OS. Therefore we are free to update those in future SDK releases.

Bugs can be filed on the compiler and Effects issues you found. I will pm about getting more info.

For small text, are you animating clear type? or, have you tried using rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED) when rendering very small text?

[Edited by - DieterVW on October 2, 2009 1:20:07 PM]
Quote:Bugs can be filed on the compiler and Effects issues you found. I will pm about getting more info.


Many thanks DieterDW.

Quote:Have you tried using rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED)


It's the text version of that method that affects the text antialiasing, i.e. rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED). It does reduce the "fuzziness" of very small text, but introduces very erratic (i.e. unacceptable) character spacing. Small GDI text (and D3DXFont text in D3D9) is very much better.

Text problems with small text with D2D1

Note the large gap between the "m" and "e" of camera in the third (aliased) text.

BenCon in your second link above says "The vision going forward is that D2D is *the* 2D API [i.e. to replace GDI]. We are very interested in any feedback that could tell us what is blocking this going forward.".

This is such a reason. I'll try and find time to register with the MSDN blog site and log the problem. But time is something I am very short of...!

JB.
Have you tried changing the measuring mode and the snap to pixel boundaries options in DrawText?
Erik,

Thanks for that info. Using a combination of:

a) rt->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_ALIASED)
b) DWRITE_MEASURING_MODE_GDI_CLASSIC with DrawText (fixes irregular character spacing)

the results are both much clearer and better spaced - though with "MS Sans Serif" they still do not rival traditional GDI. Verdana is more successful, though it needs to be larger than GDI to achieve the same readability.

JB.
I've been benchmarking various techniques, and here are my findings.

1) First I noted the overhead per frame without actually rendering anything.

Framebuffer size: 1024x768

D3D10.1 device (feature level 10.0) => 0.43 ms/frame
D3D11 device (feature level 10.0) => 0.7 ms/frame

This result is strange enough on its own - presumably it's due to an unoptimized driver path (which is odd since I am using NVIDIA's 190.62 WHQL'd driver).

2) I then added in some very simple text rendering of a string that changes each frame.

D3D10.1 device for 3D and D2D content => 0.63ms/frame
D3D11 device for 3D content, D3D10.1 device for D2D content, shared texture + mutex => 1.64ms/frame

Subtracting the constant D3D11 device overhead of 0.27 ms/frame, there seems to be approximately 0.74 ms of overhead added onto each frame. Can anything be done to remedy this (other than not updating the d2d texture each frame)?
Here's a couple of implementation references for D2D over D3D11

http://will-sherif.appspot.com/html/d3d11+DirectWrite.html
http://braynzarsoft.mezoka.com/index.php?p=D3D11FONT

Here's a couple of implementation references for D2D over D3D11

http://will-sherif.a...irectWrite.html
http://braynzarsoft....php?p=D3D11FONT


Thanks dude. Now, when will Microsoft allow us to use D3D 11 and D2D w/o doing all that?
I for one have seen this thread many, many times. I think I first found it almost a year ago, when I first wanted to render text, albeit when I was much worse coder. Regardless, even though now I'm alot more experienced with directx11 and c++ in general, programmers still shouldn't have to go through all this to render some text. I'd like to see microsoft put some effort into having a fast, robust, not to the point of every format in existence, but with basic antialising, etc, ship with every version of directx. Sure, ID3DXFont was slow, really slow, but it got the job done, with little or no headache. Ever since I found out that this interop would have to be done, I can't seem to force myself to do it, even know, comparatively speaking to even my smaller files, there isn't that much code involved. I think...If I was to do this interop, It would either have to be an easy straight copy and paste, or else I'd really, genuinely rather write my own font renderer. Maybe.... one day I'll render some text in Directx11 :) For now, anyway, I'll procrastinate as long as possible.

EDIT: I just remembered, all the DirectX11 samples I've seen, are really just using ID3DXFont. Says it all, really. For fast prototyping, you don't want to have all this overhead code, even if you only have to write it once.
Currently trying to make a planet renderer. After many hours of work, somehow I know It'll never be complete.
Also, If I help you, please give me an ++

This topic is closed to new replies.

Advertisement