protonscr

Master Arena: Poor performance with light shafts

dxvkopen nvidia proprietaryperformanced3d9amd proprietary
doitsujin/dxvk#1697 · opened 2020-07-22 by jeremyPGE · updated 2025-10-10 · 9 comments · github
JjeremyPGE 2020-07-22 github

Hello everyone,

I've been developing a game for a few years on Unreal Engine 3 and I'm testing DXVK. I want to tell you that I was pleasantly surprised with the performance. It's really a good job.

Well, I'm here to report two issues:

  • Low performance with high resolutions (on 2K when using ultra quality settings, on 4K with any quality settings).
  • Very low performance when light shafts are enable in any screen resolution.

Light shafts cost when using legacy DX9, but with DXVK the cost is insane.

I have recorded some benchmarks to compare performances, a playlist is available here:
https://www.youtube.com/playlist?list=PLV913EkEcIFC51j-UsW9Pu39A9ekbauL6

There are two cases tested: 1080p and 4K from low textures quality to ultra.
If you take a look at the videos "1080p DirectX9 vs Vulkan (dxvk) XXXX", you will observe good performances with dxvk.
But if you check "4K DirectX9 vs Vulkan (dxvk) XXXX" you will observe that DirectX9 is running better than dxvk in any case
(sorry, the fps counter is tiny).

I have to precise: On the game, when we select a new quality preset, it reduce textures quality only. There is no static mesh LOD yet. So there is exactly the same number of triangle to draw and draw primitives call in any game graphic quality. The only thing changing is textures resolution.
Draw call primitives are bigger than other games on this type (Arena FPS) because we decided to work with the most modular assets possible. As the level editor is included, players can create what they want with our modular assets library (5000+).

As I've done several tests, I'm ready to run other tests and provide needed files but in this wiki:
https://github.com/Joshua-Ashton/d9vk/wiki/Making-a-Trace
the link to download prebuilt apitrace files is dead ( https://people.freedesktop.org/~jrfonseca/apitrace/apitrace-msvc-latest.7z )
If you want to test it, the game is available on steam: Master Arena Demo :)

### System information

  • GPU: Nvidia GTX1080
  • Driver: 451.67
  • OS: Windows 10
  • DXVK version: dxvk-1.7

Best regards,
Jérémy

Mmirh 2020-08-13 github

I'm also seeing something similar in Mass Effect with an amd card (even though nothing this big).
I wonder if it isn't related to #1675, #1717 and #1721?

KK0bin maintainer 2020-08-14 github

The problem of #1717 is already fixed and the user just opened an identical issue to ask for a build.

#1721 seems to be just a stupid game that spams API calls (not even draw calls) like there's no tomorrow.

Ddoitsujin maintainer 2020-08-14 github

@Joshua-Ashton can you take a look at some point?

Mmirh 2020-08-14 github

I did test #1717 and from 145 fps (was 184 before with d3d9) performance tanked even more to 104.
I assumed that was just some half-assed hotfix to be ironed out in the future.

#1721 didn't really provide real performance figures but similarly it's faring worse.

Ddoitsujin maintainer 2020-08-14 github

@mirh please don't hijack other people's issues. If you have anything specific to report and can provide us something to work with, please open a separate issue.

KK0bin maintainer 2022-08-31 github

Is this still an issue?

Your game is Master Arena, right?
https://store.steampowered.com/app/704020/Master_Arena/

Jjeremweb 2022-09-05 github

Yes it's still an issue. And yes, https://store.steampowered.com/app/704020/Master_Arena/ is my game.

KK0bin maintainer 2025-10-09 github

@jeremweb I finally took a look at the game and I gotta say: what the actual fuck is that light shaft implementation.

To create this:
Image

You could just render a single triangle with a gradient and blending (or maybe some more triangles). The light shafts in the game don't do something fancy like casting shadows (something that other games do).

Instead the game somehow renders a line:
Image

And then runs a fullscreen pass to render the light shaft.
That fullscreen pass runs a loop with 32 iterations and each iteration does 2 texture samples.
The texture it sample from is also a R16G16B16A16_UNORM texture to make sure it wastes as much bandwidth as possible.
This is also needlessly executed for the entire screen, even though 80% of pixels are completely black.
No viewport, stencil, discard or anything like that used.

defi i0, 32, 0, 0, 0
rep i0
      mov r4.zw, r4.xyxw
      mul r5.xy, r4.zwzw, r4.zwzw
      mul r5.zw, r5.xyxy, c2.w
      mad r5.xy, r5, c2.w, -r4.zwzw
      cmp r4.xy, r5, r4.zwzw, r5.zwzw
      max r5, r3, c8.xyxy
      min r6, c8.zwzw, r5
      texld r5, r6, s0
      mad r5, r5, r4.xxxz, r2
      texld r6, r6.zwzw, s0
      mad r2, r6, r4.yyyw, r5
      add r4.xw, r4.zyzw, c3.x
      mad r3, r1, c2.y, r3
    endrep

On top of that the renderer copies that texture from one texture to another dozens of times both before and after those light shafts are generated.

Image

There's 4 different textures like that:

Image

Some even do frequent clears in between to make it waste even more bandwidth on desktop GPUs.

It's not exactly clear why any of this is done. Most of the fullscreen draws in that list before EID 10025 (the one that generates the light shafts) are completely black.

I think each volumetric light does 4 of those fullscreen passes and one of the fullscreen passes for each light is the one with that 32 iteration loop. I counted at least 5 lights and I didnt go over all draws. (the mars map)

You really should do some culling instead of processing every single light like that even when they don't contribute to the final image at all because they aren't on screen.

To be perfectly honest, all of this is terrible and I have no idea how this isn't super slow on the Nvidia D3D9 driver.
I don't see anything we're doing wrong here or any opportunity to optimize this.
As far as I can tell, it's not possible to move the texture samples outside of the loop because each iteration impacts the texture coords used for the next one.

It's possible that the Nvidia compiler struggles to optimize our specialization constant based texture sampling when it's in a loop like that.

BTW I also really don't see why the game needs 6200 different shaders.

BBlisto91 2025-10-10 github

Some spot test results made with a RTX 4080 and 7900 XTX. Driver versions are 581.42 and 25.9.1 respectively and dxvk version is current master (1c25c0a).
Testing was done in a specific spot in the map DM-MARS where i noticed in your lights shafts comparison video that dxvk differs a bunch from native.

Settings used:
Note that my monitor is natively 1080p but i am running the game itself at 4K.

Settings page

Image

FPS (top left) screenshots:
In both cases the native d3d9 implementation and driver out performs dxvk + Vulkan by a decent margin.

Nvidia Windows

Ignore that the gun looks different on the d3d9 screenshot. I had alt-tabbed just before taking it and the lighting on it hadn't updated properly, but this did not affect the performance noticeably.

Native d3d9: 219fps

Image

dxvk Vulkan: 163fps

Image

AMD Windows

Native d3d9: 151fps

Image

dxvk Vulkan: 115fps

Image

A interesting counter example is the Linux AMD Vulkan driver RADV which admirably outperforms the native AMD d3d9 driver.

AMD Linux (RADV)

dxvk Vulkan: 176fps

Image

Nothing extracted yet.