doitsujin / dxvk

Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine
zlib License
12.85k stars 830 forks source link

[D3D11] Microsoft Flight Simulator Game of the Year Edition (1250410): Visual artifacting between production logos. #4276

Open redmcg opened 3 days ago

redmcg commented 3 days ago

Software information

Microsoft Flight Simulator (1250410)

System information

Apitrace file(s)

link (may expire, I can refresh)

Log files

steam-1250410.log

When first starting up Microsoft Flight Simulator on the Steam Deck OLED, there is a garbled screen displayed prior to the first frame of the first video (which is the XBOX logo).

I have isolated this to a shared texture that is created with MiscFlags = D3D11_RESOURCE_MISC_SHARED. Below is an extract from the linked apitrace:

16576 ID3D11Device5::CreateTexture2D(this = 0x53ed498, pDesc = &{Width = 3840, Height = 2160, MipLevels = 1, ArraySize = 1, Format = DXGI_FORMAT_B8G8R8A8_UNORM, SampleDesc = {Count = 1, Quality = 0}, Usage = D3D11_USAGE_DEFAULT, BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, CPUAccessFlags = 0x0, MiscFlags = D3D11_RESOURCE_MISC_SHARED}, pInitialData = NULL, ppTexture2D = &0x5394ac0) = S_OK
16577 ID3D11Texture2D1::QueryInterface(this = 0x5394ac0, riid = IID_IDXGIResource, ppvObj = &0x5394be0) = S_OK
16578 IDXGIResource1::GetSharedHandle(this = 0x5394be0, pSharedHandle = &0x40000002) = S_OK

The texture does not appear to be initialized and the garbled screen is the result of displaying the memory's previous content. I'm able to resolve this with the attached patch (which writes all zeros to a shared texture on creation): msfs_hacky_fix.txt

Note that this only appears to happen with AMD GPUs. I have not dug into why that is (but presumably NVIDIA clears the texture first).

doitsujin commented 3 days ago

DXVK already zero-initializes all newly created resources, I don't understand why the patch would change anything. Are we sure the problem isn't with whatever is importing the shared texture?

Would appreciate if you could try to figure out why this is not working, I don't really have the patience to deal with this 200GB monstrosity that takes several days to download due to terrible content servers and a terrible installer again.

doitsujin commented 3 days ago

On second thought, if there is a user of the shared texture then there's a chance our initialization does not get submitted before the texture is used.

Does adding something like

if (desc.MiscFlags == D3D11_RESOURCE_MISC_SHARED)
  m_initializer->Flush();

fix the problem as well?

redmcg commented 2 days ago

It does. And that makes sense. I think one thread writes the contents of the video (once its ready), and the other displays it. But I guess the commands to clear the texture were pending the first video write? And the flush now causes it to happen immediately?

Anyway, thank-you for the quick turnaround.

doitsujin commented 2 days ago

Thanks for confirming, currently trying to debug a nasty crash but I'll do a proper fix here once I have the time.