JDK-8096374 : Low texture update performance with D3D9Ex enabled
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 8u20
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-04-25
  • Updated: 2015-06-12
  • Resolved: 2014-04-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u20Fixed
Related Reports
Relates :  
Relates :  
Description
This is basically duplicate of RT-27508: 8.0-h96-b68: 68% regression in SpiralText in hw pipeline caused by enabling DirectX 9Ex.
The performance regression in SpiralText with D3D9Ex enabled is cause by the huge number of small texture updates per frame (~1400).
Comments
Changeset: d7370ecfa1f3 Author: vadim Date: 2014-04-29 14:15 +0400 URL: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/d7370ecfa1f3
29-04-2014

Thanks for the explanation. +1
28-04-2014

Right now MR doesn't key off of the "true size" of the VRAM pool, but just picks a default out of thin air, or what the user specifies on the command line. If we ever try to figure out how much VRAM there is, we would end up asking the D3D pipeline and it should probably take this (and the framebuffer) into account in its answer.
28-04-2014

Chien, the system memory pool doesn't count toward runtime memory (if you are talking about JVM memory), it uses some internal d3d memory allocations I believe, here is the quote from the msdn: "This memory allocation consumes system RAM but does not reduce pageable RAM." So given that this overallocation can only occur in extreme cases of huge updates of huge textures of many different texture formats, I think it's not worth trying to do something here. Most of the time it will be like 30x30 grayscale texture for glyphs.
28-04-2014

This actually seems fine to me based on Vadim's explanation.
28-04-2014

Hi Vadim, Regarding the cached texture size, it will have the bad side effect of tied up runtime memory like what we have with temp. memory for point and vector objects. I believe we have JIRA filed against such caching approach. The problem with such grow and never shrink scheme is that it tied up memory and application has no way to trigger a release. It will be great if we can find a better alternative.
28-04-2014

This cache will be at most one maximum texture size texture per format, so the overhead is not that big. These textures are not in the video memory, but in system memory only, so vram pool is not applicable here.
28-04-2014

Thanks for the explanation. So it intentionally creates a texture as large as the largest that is needed. This is fine unless we run out of memory. One question (for Jim as much as for you) -- it seems that the ManagedResource pool will not track this overallocation of texture memory. What problems, if any, might this cause?
28-04-2014

That's exactly what is needed for the cache texture. Suppose we need to upload 10x15 texture, we will create 10x15 cache texture, upload pixels and update surface. Then we need to upload 15x10 texture, without this logic we will create new 15x10 texture and drop old texture, with this logic though we will create 15x15 texture. And then we need to upload 10x15 texture again. Without this logic, we will create new texture 10x15 and so on, but with this we will skip the creation and return our 15x15 cache. So on the first frame the cache will grow to be able to receive any texture uploaded, and hopefully on subsequent frames there will be no need to recreate it.
28-04-2014

Good catch, Kevin. It does seem odd to need that logic.
28-04-2014

Looks fine to me (once Chien's comments are addressed). I have a question about the need for the following code, though: + if (w < width) + w = width; + if (h < height) + h = height; This will cause a new texture to always be at least as big as the previous texture, right? Is this needed?
28-04-2014

The proposed fix looks good to me. I did see a 20% boost on SpiralText running on my Intel HD laptop. I just have a few minor comment on code style: 1) Please make the "if" statement a one liner or add {} block to it. IDirect3DTexture9 *D3DContext::TextureUpdateCache::getTexture( .... if (w < width) w = width; if (h < height) h = height; 2) Please add spacing between variables and operator. int D3DContext::release() { ... for (int i=0; i!=NUM_TEXTURE_CACHE; i++) {
28-04-2014

No, the only pool where texture locking is possible in D3D9Ex is system memory, and it can't be used for rendering, only for uploading data to the textures in the default pool. Managed pool which is used in D3D9 for uploading textures is not available in D3D9Ex. Also these two issues are orthogonal - texture upload from system memory like in glyph rendering and volatile render targets in case of Canvas.
26-04-2014

A quick question - is there a way to have D3D9non-ex style textures when working with D3D9ex such that we don't care if their contents are volatile. That would help with some textures where we can reconstruct them in the rare case that they are flushed. It's only things like Canvas that need the protection so it would be nice if we could restrict the "performance issues" only to those textures that need it...
25-04-2014

Chien, Kevin, Please review this fix: http://cr.openjdk.java.net/~vadim/RT-36836/webrev.00/ This is texture update part of the first version of the fix for RT-36571. I've introduced native texture cache for the update operations. Results of this fix are (with prism.text=t2k) : d3d9 reference - 35 fps d3d9ex w/o cache - 18 fps (-48%) d3d9ex with cache - 24 fps (-30%)
25-04-2014