Issue with DUI / Texture Replacements

I have included a full set of resources to re-produce this issue here: https://we.tl/t-HlJbF46XIy

Drop each resource in your resources folder, start in this order → test_objects, test_dui, test_usage

test_dui and test_usage should be started after connecting since it triggers on resource start.

Alternative / simpler download: GitHub - mikeemoo/fivem-texture-bug

Coords for test location: x=“269.76640000” y="-320.84060000" z=“46.33287000”

To put the issue simply, when you want to create multiple DUI objects with multiple texture replaces and multiple texture dictionaries / names, you get a weird bug where some of them don’t render. Its inconsistent behavior is very consistent in that some may show, and some may not.

Here are some example screenshots of what happens when you run the above resources:

Blank canvas: https://i.imgur.com/tg3FNVZ.jpg

First run: https://i.imgur.com/GtX89mO.jpeg

Second run: https://i.imgur.com/8IhDHJh.png

As you can see above, what is supposed to happen is each texture is replaced with its corresponding number in order. So each individual square would have 1 through 8 on it. What actually happens is some do not render whatsoever. On occasion, you can get lucky, and they will all render. Other times, none of them will render.

Additionally, unrelated, there seems to be a hard limit on DUI objects of 128. If you exceed this, your game will freeze up (not crash, freeze, and have to be stopped via task manager.)

1 Like

Update:

Another tester I gave the resource too was able to make this work 100% of the time. The only difference is they are 1080p and I use a 1440p monitor; unsure why that would matter. I did set my resolution to 1080p as well to test, still didn’t work.

We also tested default game build and 2060, no difference.

We also tested a totally clean server, no difference.

Here it is working on default game build 1080p clean server: https://streamable.com/u03b9b

Even when I have the same setup, I get the same issues as previous.

Here’s a JS script with commands to re-create instead of restarting the resources:

let duis = [];

RegisterCommand(
  "gothere",
  async (_source) => {
    const ped = PlayerPedId();
    SetEntityCoords(ped, 269.7664, -320.8406, 46.33287, true, false, false, false);
  }, false
);

RegisterCommand(
  "replace",
  async (_source) => {
    
    [...Array(10)].forEach(async (_, i) => {

      const dictionaryName = `testobjecttxd0${i}`;
      const textureName = `testobjecttx0${i}`;
  
      let dui = CreateDui(`https://via.placeholder.com/1024.png?text=0${i}`, 1024, 1024);
        
      duis.push(dui);

      while (!IsDuiAvailable(dui)) {
        await new Promise((res) => setTimeout(res, 100));
      }
  
      const replacementDictionaryName = `${dictionaryName}_replaced`;
      const replacementTextureName = `${textureName}_replaced`;
  
      const tdx = CreateRuntimeTxd(replacementDictionaryName);
      CreateRuntimeTextureFromDuiHandle(tdx, replacementTextureName, GetDuiHandle(dui));
  
  
      AddReplaceTexture(dictionaryName, textureName, replacementDictionaryName, replacementTextureName);
  
    })

  }, false
);

RegisterCommand(
  "destroy",
  async (_source) => {
    [...Array(10)].map((_, i) => {
      duis.forEach((dui) => {
        if (dui) {
          return;
        }
      });
      console.log(`testobjecttxd0${i}`, `testobjecttx0${i}`, `testobjecttxd0${i}`, `testobjecttx0${i}`);
      AddReplaceTexture(`testobjecttxd0${i}_replaced`, `testobjecttx0${i}_replaced`, `testobjecttxd0${i}`, `testobjecttx0${i}`);
    })

  }, false
);

Further update:

After giving this resource to multiple people with 1080p and 2060 fresh server, it seems to work for them every time.

For me, on 1080p with 1440p native resolution, clean 2060 server, it is very inconsistent.

Not sure if its a resolution issue or something else; will continue to investigate.

After thorough testing with multiple 1080p and 1440p users, it appears to be random and not resolution based. Though the success rate on 1080p was much higher.

Hi,

I’ve updated the repository a bit and added a README to show the steps to recreate.

From the testing I’ve done, it seems to work fine for about 70% of users and it’s broken for about 30%. I’ve not been able to find any patterns.

1 Like

And update to this -

We’ve worked out that the cause seems to be the “Enable NUI in-process GPU” option.

With it enabled, DUIs in textures are very intermittent.

Yes, this is likely expected, and even more so if an end user is using any D3D proxies/overlays/… (‘ReShade’, ‘ENBSeries’, etc.). Chromium is not designed for in-process GPU, but currently Windows is preventing us from having proper GPU priority with out-of-process GPU.

Sadly, Microsoft is a massive brick wall in this regard.

However, there may be some other slight design fluke with how in-process GPU is handled currently - this may indeed lead to reliability issues when creating new cross-device textures.

2 Likes

Thanks for the update.

Can confirm that none of the test subjects had any external add-ons, and used clean servers / clients.

Is there any other information we can provide or something we can look in to ourselves to see if its a fluke, or its Windows?

Thanks for the reply.

Is there a possibility to run NUI with the flag, and DUI without the flag? or is that too much of an overhaul?

Currently it’s making DUIs difficult to justify using because you can’t programatically turn the option off (as far as I can tell), and you can’t detect if the user is using it - unless I’m missing a trick?

That’d require factoring out the main Chromium browser process as well, which is a bit counterproductive as the Windows bug only gets fixed with Chromium GPU running in-process.

However, a testing fix may get pushed on FiveM’s canary channel within the next hour that may mitigate this.

Awesome - will keep a look out for it.

On a side note, there seems to be a hard limit on how many DUIs can be created, but destroying a DUI doesn’t reduce the tally. Is that a bug or is it by design?

(For example, if you created / destroyed a single DUI over and over again, it’d still crash the game once the limit has been reached)

Change is live and it seems to work as expected for this issue.

If it crashes it’s probably a bug, as a crash would never be by design. Are you able to provide a crash log file of such?

I’m struggling to get a file from the /crashes/ folder because the client just seems to freeze completely and doesn’t generate anything (I have to then manually kill the process).

The lines from the application log are:

[     65531] [   ROSLauncher]                16404/ SC JS message: SetGameLaunchState -> {"launchState":"running","message":"","titleName":"gta5"}
[     84906] [    GTAProcess]             MainThrd/ 
[    101968] [    GTAProcess]             MainThrd/ InvokeNative: execution failed: Error executing native 0x0000000023eaf899 at address 0x1412f3e1d.
[    102000] [    GTAProcess]             MainThrd/ ^1SCRIPT ERROR in promise (unhandled): Error: Execution of native 0000000023eaf899 in script host failed: Error executing native 0x0000000023eaf899 at address 0x1412f3e1d.^7
[    102000] [    GTAProcess]             MainThrd/ ^3> Object.callback^7 (^5@fivem-texture-bug/client.js^7:15)
[    102000] [    GTAProcess]             MainThrd/ ^3> Object.callback^7 (^5@fivem-texture-bug/client.js^7:31)
[    102000] [    GTAProcess]             MainThrd/ 
[    365531] [   ROSLauncher]                16404/ SC JS message: SetTitleInfo -> {"batchEnd":true,"branches":[{"branchName":13,"friendlyName":"default","isDefault":true}],"currentBranch":13,"currentBranchFriendlyName":"default","currentVersion":"1.0.1604.0","externalInstall":[],"friendlyName":"Grand Theft Auto V","parentApp":null,"shortcuts":{"desktop":true,"startMenu":false},"status":{"entitlement":true,"install":true,"installLocation":"C:\\Program Files\\Rockstar Games\\Games\\Grand Theft Auto V","lastUsed":"2021-04-15T17:58:33+00:00","preparing":false,"queuePosition":-1,"releaseState":"available","totalBytes":72484280,"updateBytes":0,"updateProgress":0,"updateState":"notUpdating","updateTotal":0},"titleName":"gta5"}

I’ll post a crash log here if I’m able to get it to generate one.

It never generates a crash log and always freezes the game, resulting in the need to kill the client from the task manager. (I noted this in my first post).

The hard limit is 128 before it freezes up.

I haven’t confirmed myself but apparently the following is true:

made and destroyed 800 duis with useSharedResources on false and didnt crash

Works great. Thank you for such a quick response.

1 Like

Create dump file is an option in Task Manager.

Does this mode even work? I assumed it was for NY only.

Can confirm the fix on canary solves the issue, even in 1440p. Runs buttery smooth now, thanks a lot!

As for the game freezing, when generating a dump file to upload, I notice FiveM had generated quite a lot of chromium subprocesses - is it created one per dui resource? I can see this getting quite heavy, though I am not an expert.

When I created the .DMP file it generated an 11gb file which I don’t really have anywhere to upload, but seems excessive.

Yes, unlike normal stuff which ‘hackily’ layers a lot of iframes, there’s no other way to get separated views for multiple DUI assets.

Compression should lower it to around 10% of said size, alternately procdump.exe from MS’ site should be able to make ~400 MB dumps.