Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReShade bugs with DirectX version detection #873

Closed
3 of 4 tasks
zany130 opened this issue Jul 30, 2023 · 34 comments · Fixed by #881
Closed
3 of 4 tasks

ReShade bugs with DirectX version detection #873

zany130 opened this issue Jul 30, 2023 · 34 comments · Fixed by #881
Labels
bug Something isn't working

Comments

@zany130
Copy link
Collaborator

zany130 commented Jul 30, 2023

System Information

  • SteamTinkerLaunch version: steamtinkerlaunch-v14.0.20230729-1
  • Distribution: Garuda Linux
  • Installation Method: Aur

Issue Description

The logic for determining the direct version of the game is broken. It always installs both the d3d9.dll and dxgi.dll, which can sometimes cause the game to crash, such as in Tales of Arise.

Also, the installation function needs to be reworked. Currently, it is always reinstalling the ReShade files on boot.

Also, I feel having a check box for installing might be confusing. I think there should only be an enable, update, override version, and use with a custom command box.

Right now, the update box actually depends on the install box also being checked.

If the DirectX version can't be reliably acquired, one idea is to add a drop-down menu where you can specify the API (this might actually be useful anyway for overriding what the .dll is installed as ex: dx11 can actually be installed as dxgi.dll or d3d11.dll in case you have a mod installed to dxgi.dll

Logs

steamtinkerlaunch.log


TODO List

@zany130 zany130 added the bug Something isn't working label Jul 30, 2023
@sonic2kk
Copy link
Owner

sonic2kk commented Jul 30, 2023

Possibly related: #852.

The logic for determining the direct version of the game is broken. It always installs both the d3d9.dll and dxgi.dll, which can sometimes cause the game to crash, such as in Tales of Arise.

I think the STL logic is working as intended but it sounds like this is breaking games, so the logic has to be specifically altered. I took a quick look and I don't think STL does any checks for which DLLs to copy, I think it deliberately copies them all.

Also, the installation function needs to be reworked. Currently, it is always reinstalling the ReShade files on boot.

Could you explain this a little bit more? I'm not too intimately familiar with the ReShade stuff. Is it always trying to copy files on each game launch? This is probably not desired, but I'm also wondering if it's causing any problems?

Also, I feel having a check box for installing might be confusing. I think there should only be an enable, update, override version, and use with a custom command box. Right now, the update box actually depends on the install box also being checked.

I think we may have briefly discussed this before, I'm very much in agreement. I think other similar options such as Auto-Bump GE only have the one checkbox - Similar as in, they both conditionally download files, and the GE checkbox doesn't have a higher level "enable" option. Removing this higher level checkbox is probably safe and relatively straightforward.

I don't think it makes much sense to have a checkbox to enable ReShade, and then a separate checkbox to install it. I don't use ReShade but if I did, I would expect enabling ReShade to also install it, and disabling ReShade to uninstall it.

If the DirectX version can't be reliably acquired, one idea is to add a drop-down menu where you can specify the API (this might actually be useful anyway for overriding what the .dll is installed as ex: dx11 can actually be installed as dxgi.dll or d3d11.dll in case you have a mod installed to dxgi.dll

Yes, I'm unsure if there's a "universal" way to actually get the DirectX version. An override option is probably a good idea. In terms of the last point, mods can also be installed to d3d11.dll so the vice versa probably also works and would be useful :-)


So for the points in this issue to be resolved, we need to do the following:

  1. Simplify the ReShade checkboxes to remove the "install" checkbox
    • If I'm not mistaken, "Enable ReShade" downloads it, and "Install ReShade" actually puts it into the game directory, so we want to combine these options.
  2. Either detect the DirectX version used by a game and copy the relevant ReShade DLLs over, or add an option to specify the DirectX version
    • For the override case, the default would be the existing behaviour of copying all the DLLs
    • The user can optionally specify an override for the DirectX version, which should prompt an uninstall of any existing ReShade DLLs and then re-install the relevant DLLs for the chosen DirectX version (such as d3d9.dll)

Please correct me if I got anything wrong :-)

I am not clear in my mind on the specifics of implementing this, but it should be possible. The UI change should hopefully be trivial.

Thanks for staying on top of the ReShade-related stuff. I'll try my best to look into these when I can :-)

@zany130
Copy link
Collaborator Author

zany130 commented Jul 30, 2023

Nah, I think #852 is, as you said, an upstream issue. I commented some more over there with my thoughts.

Could you explain this a little bit more? I'm not too intimately familiar with the ReShade stuff. Is it always trying to copy files on each game launch? This is probably not desired, but I'm also wondering if it's causing any problems?

Exactly. This in itself shouldn't really be too big of an issue. The files are really small (a few kb I believe), so copying them on each launch isn't really time-consuming or anything, where a bigger issue is when you want to name dxgi.dll to d3d11.dll (for compatibility reasons, maybe a mod uses dxgi.dll) it will keep installing a dxgi.dll and a d3d9.dll on each launch.

So for the points in this issue to be resolved, we need to do the following:
Simplify the ReShade checkboxes to remove the "install" checkbox
If I'm not mistaken, "Enable ReShade" downloads it, and "Install ReShade" actually puts it into the game directory, so we want to combine these options.
Either detect the DirectX version used by a game and copy the relevant ReShade DLLs over, or add an option to specify the DirectX version
For the override case, the default would be the existing behaviour of copying all the DLLs
The user can optionally specify an override for the DirectX version, which should prompt an uninstall of any existing ReShade DLLs and then re-install the relevant DLLs for the chosen DirectX version (such as d3d9.dll)
Please correct me if I got anything wrong :-)

Exactly correct. I was calling it a "Bug" because I thought I remember there being logic in the ReShade functions for checking what API the game uses and copying the relevant files (I think the way the check worked is if the game is 32-bit use d3d9.dll and if the game is 64-bit use dxgi.dll)

I vaguely remember someone once posted an issue about this very same problem, and Frostworx implemented a fix, and when I did the refactor adding the version override, I tweaked it further because it wasn't working for me or something.

I actually knew about this issue for a while now but have been very lazy/busy 😅 (new job) and kept forgetting to post a bug report. Also never really was to big of a problem (never caused crashes or issues) until now with Tales.

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 6, 2023

I did a bit more digging, I'll try break this down a little bit.


It turns out you were right, there is an architecture check for ReShade, in installReshade. It will also intentionally create both d3d9.dll and dxgi.dll files, the architecture check just controls whether it uses the 32bit or 64bit ReShade DLLs to do this. Take a look at these lines:

if [ -d "$INSTDESTDIR" ]; then
    #32bit:
    if [ "$(getArch "$CHARCH")" == "32" ]; then
        writelog "INFO" "${FUNCNAME[0]} - Installing 32bit ${RESH} as '$CHARCH' is 32bit" 
        #d3d47
        installd3d47dll "$D3D47_32" "$INSTDESTDIR"
        #dxgi:
        installRSdll "$RS_DX_DEST" "0" "$RS_32"
        #d3d9:
        installRSdll "$RS_D9_DEST" "$NOD3D9" "$RS_32"

    # 64bit:
    elif [ "$(getArch "$CHARCH")" == "64" ]; then
        writelog "INFO" "${FUNCNAME[0]} - Installing 64bit ${RESH} as '$CHARCH' is 64bit" 
        #d3d47
        installd3d47dll "$D3D47_64" "$INSTDESTDIR"
        #dxgi:
        installRSdll "$RS_DX_DEST" "0" "$RS_64"
        #d3d9:
        installRSdll "$RS_D9_DEST" "$NOD3D9" "$RS_64"
    else
        writelog "SKIP" "${FUNCNAME[0]} - ERROR in ${RESH} installation - no file information detected for '$CHARCH' or any 'neighbor file' - setting USERESHADE=0 for this session"
        export USERESHADE=0
    fi
else
    writelog "SKIP" "${FUNCNAME[0]} - INSTDESTDIR '$INSTDESTDIR' not found" 
fi

The getArch function is used throughout STL, and in my experience it works, so I'll assume for now that it is correctly detecting the architecture.

From what I can tell by glancing at the code here, it looks like it moves some DLLs called ReShade32.dll or ReShade64.dll (the RS_32 and RS_64 respectively) from the SteamTinkerLaunch download folder ($RESHADESRCDIR/$RSVERS/$3, where $3 is the ReShade DLL names) to the destination game directory with the relevant D3D DLL names. The relevant line in installRSdll is here:

cp "$RESHADESRCDIR/$RSVERS/$3" "$INSTDESTDIR/$1" >/dev/null 2>/dev/null

Basically the line copies either the 32bit of 64bit ReShade DLL and copies it to the game EXE directory (where ReShade DLLs are meant to go afaik). It copies this DLL twice, identical files but with one copy called d3d9.dll and another called dxgi.dll.


So the above code is what copies the relevant 32bit or 64bit ReShade DLL. And as you said, it creates both d3d9.dll and dxgi.dll. However note this line:

installRSdll "$RS_D9_DEST" "$NOD3D9" "$RS_64"

The NOD3D9 option refers to the Game Menu checkbox that controls PROTON_NO_D3D9. If this is enabled, then STL won't create a d3d9.dll and will only create dxgi.dll. Or at least it should, I have not tested.


My understanding now is that while the code is explicitly creating both of these DLLs, this is not desirable behaviour. Therefore I'd like to ask a couple of things:

  • Which DLL should be created in the game folder, in your case for Tales of Arise? Is creating just dxgi.dll the fix, or in other words is it d3d9.dll causing the problem?
  • For the point about d3d11.dll and dxgi.dll, would a dropdown to select the name of the ReShade DLL work, with a default to dxgi.dll?
  • To the above point, would copying only one of the DLLs work? Is there ever a case where dxgi.dll and d3d9.dll are needed? If not, then to the above point, we could simply only copy the ReShade DLL once and let the user choose a name, with three default values: d3d9.dll, d3d11.dll, and dxgi.dll (ofc with sanity checks for blank values etc).
    • Since it's copying the same DLL twice I imagine this is for cases where a game may require one or the other. Perhaps it's not clear when a game would require which DLL, so maybe having this as a separate checkbox to enable this custom DLL name for ReShade "power users" would be a better approach.

Hopefully my investigation on what's going on here makes sense. Sorry it took me so long to get around to this, I realise this is a bit of a blocker for some games. I'm not very well-versed in ReShade, I am just going by what the STL logic does, so please correct me if I'm talking nonsense :-)

@zany130
Copy link
Collaborator Author

zany130 commented Aug 6, 2023

Yup, you are correct, except you only need one .dll. That's what I was trying to get it to do .

the architecture checks servers two purposes (at least, that is how I was trying to use it when I was doing the rewrite)

the first purpose was to determine if we need the 32-bit or 64 bit reshade

the second purpose was if the game is 32bit, it is usually d3d9 or older, so use d3d9.dll (older versions of DirectX are not supported on newer versions of reshade so you would need something to wrap it to something newer like DXVK, and if the game is 64bit, it usually is d3d10 or newer. ( btw If I remember correctly from the reshade windows installer, it does NOT automatically detect what d3d version to use it however, I think it does mention the above guidance that if its a newer 64-bit game use dxgi.dll and if its an older 32-bit game use d3d9.dll )

Normally it shouldn't really be a problem if you have multiple versions as normally the game will only load one d3dver.dll and then loads the reshade.dll

But in the case of my game, having d3d9.dll causes the game to crash for some reason

I think it may be easier to just have a dropdown with different names to use for the .dll the options being

1.d3d9.dll
2.d3d11.dll
3.dxgi.dll

sorry, I haven't had much time to look at this

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 7, 2023

But in the case of my game, having d3d9.dll causes the game to crash for some reason

Out of curiosity, does enabling the "No D3D9" option in the Game Menu fix this for you? Since it shouldn't copy the D3D9 DLL if this option is disabled.

@Borrachoburro

This comment was marked as off-topic.

@sonic2kk

This comment was marked as off-topic.

@Borrachoburro

This comment was marked as off-topic.

@zany130
Copy link
Collaborator Author

zany130 commented Aug 10, 2023

But in the case of my game, having d3d9.dll causes the game to crash for some reason

Out of curiosity, does enabling the "No D3D9" option in the Game Menu fix this for you? Since it shouldn't copy the D3D9 DLL if this option is disabled.

Sorry for the delay. I Didin't know there was a "NoD3D9" option. Where in the game menu can I find it ? I only see "NoD3D10" and "NoD3D11"

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 10, 2023

Huh, it looks like you're right. STL does track NOD3D9. There is also no setting for it in the game config file, but from looking at the code, setting NOD3D9 looks like it should stop the d3d9.dll ReShade DLL from being moved into the game folder.

There is code that can also try to export this if NOD3D9 is undefined and if there is a ReShade conflict. But in your case where it is STL that moves both DLLs, it seems like there is never a conflict.

EDIT: Relevant code block is here, in installReshade: https://github.com/sonic2kk/steamtinkerlaunch/blob/master/steamtinkerlaunch#L8591-L8608

Proton also no longer seems to have a PROTON_NO_D3D9 option, it looks like it was removed some time ago.


Sorry about that, but perhaps manually setting NOD3D9 in the game config would resolve this.

It is also probably not worth exposing this on the UI if the go-forward approach will be to let the user choose the name of the ReShade DLL, or to at least have an option to specify a name to override the current behavior.

@sonic2kk
Copy link
Owner

So I've been thinking about this (and a couple of other things I want to approach in STL loosely related to this) and essentially the changes needed for this issue to be closed are:

  • "Consolidate" the ReShade enable and install option into one. I'll have to look deeper at the code but I can foresee some logic needed tweaked for this, more than originally expected (such as the downloading logic)
  • Don't constantly move ReShade the DLLs if they're already in the game folder, only move the DLLs once
    • The question is how do we know if STL installed ReShade? Maybe there are other files telling that ReShade is installed (I recall some JSON files?) but if not we can create an empty stl_reshade file in the same folder as the DLLs
  • Only move one DLL instead of always using two of the same ReShade DLLs but with different names - Please correct me if this is the wrong assumption
    • I'm not sure if the current behaviour should be kept as the default or as a separate option behind a checkbox. Is there ever a case when two DLLs would be needed? Maybe if a game had a DX9 and DX11 renderer option, then having both DLLs would mean a game could load it for both DX versions without the user having to change the DLL name.
  • Let the user pick the name for the ReShade DLL with a sensible default, such as dxgi.dll
    • Not sure how to handle cases where this DLL already exists by the game/mods, or how the current code even accommodates this.
    • Similarly, consideration is needed on how to handle ReShade updates, we'd need to know when ReShade has been installed by STL

I think this is a good base summary, hopefully :-) Fixing the DLL issue might be the most straightforward to start with. I'd be very interested in hearing your thoughts on how best to approach it, I see two options:

  1. Default to having a drop-down with a DLL name, priorising some name. I'm currently thinking of having dxgi.dll as the default, it should be getting moved already too
    • My concern is how to handle it if the DLL already exists. It's unlikely that both say d3d9.dll and dxgi.dll would exist in a game folder, so the current behaviour is probably for those cases. Using only one DLL may turn out to be problematic depending on how the existing code handles DLLs that already exist.
  2. Keeping the current functionality as-is but having a checkbox to enable a custom DLL name, and doing so would implement the above. So the default behaviour would be kept. If it is preferred to have the current behaviour and/or if having only one DLL would not work, this is probably the best option.

I'll hack around when I have some time and motivation. No ETA but even though there hasn't been any code changes, I have been giving implementation on this a good bit of thought :-)

@zany130
Copy link
Collaborator Author

zany130 commented Aug 13, 2023

Personally, I would go with option 1, have a dropdown with dxgi.dll as the default option ( this is actually how reshade works on Windows), and all reshade does automatically is figures out for the user what architecture to use
maybe we can have a tooltip or something telling the user there responsible for checking how they should name the reshade .dll for there specific game and to check https://www.pcgamingwiki.com/wiki/ReShade#Compatibility_list

As for when the .dll already exists, I actually never tested that (thinking about it, I probably should of 😅 ), but I am pretty sure it just overwrites the current .dll right now (The correct way in my opinion, is to rename dll to dllname.bak so dxgi.bak for example and maybe have an option in a drop-down or something for controlling this behavior (overwrite, backup, do nothing)

As for wanting to have the option to have multiple dlls (such as having d3d9 and dxgi), Could we not make the dropdown menu for the .dll name editable and possible to pass more than one name separated by a comma or something (personally I don't see this issue to valuable, but I don't think it would be difficult to implement)

As for checking if reshade is installed, STL creates a ReShade.txt with the name of the .dlls to track. ( you will notice that it also tracks d3dcompiler_47.dll that's needed for reshade if I remember correctly and comes from another function in STL)

EDIT: Thinking further, I think the dropdown for the DLL names should have API names and not dll names (so Direct3D 9, Direct3D 10+, and OpenGL(I never tested if this works as I couldn't find an OpenGL game)). The reason being a user not immediately understand what to name the DLL from the linked wiki but they will see API name.

And then ReShade in the background does

Direct3D 9 --> d3d9.dll

Direct3D 10+ (meaning Direct3D 10 or higher) --> dxgi.dll

OpenGL --> openglARCHITECTURE.dll

custom name --> customName.dll

@sonic2kk
Copy link
Owner

Going to take a look at proofing this out soon I think, it's taken a while to make some time for this, apologies!

Personally, I would go with option 1, have a dropdown with dxgi.dll as the default option

I like this approach as well, especially if this is how it behaves on Windows.

As for when the .dll already exists, I actually never tested that (thinking about it, I probably should of 😅 ), but I am pretty sure it just overwrites the current .dll right now (The correct way in my opinion, is to rename dll to dllname.bak so dxgi.bak for example and maybe have an option in a drop-down or something for controlling this behavior (overwrite, backup, do nothing)

I agree with you that the correct way is to create a backup at least by default. When ReShade is then disabled, the backup should be restored. Though this has implications for checking the DLLs in the game directory after ReShade has been disabled. Since STL already tracks when ReShade DLLs are installed as you mentioned later on, maybe this will be more straightforward than I'm thinking! I hope... I'll cross that bridge later I think. Having the option to control this also makes sense.

Could we not make the dropdown menu for the .dll name editable and possible to pass more than one name separated by a comma or something (personally I don't see this issue to valuable, but I don't think it would be difficult to implement)

Yes, this should be possible I think. We could probably create an array by splitting the DLL names on a comma (DLL names probably can't contain commas, right? 😅) and then use loop to copy the ReShade DLLs that way.

As for checking if reshade is installed, STL creates a ReShade.txt with the name of the .dlls to track. ( you will notice that it also tracks d3dcompiler_47.dll that's needed for reshade if I remember correctly and comes from another function in STL).

I wonder if STL has logic to remove this when ReShade is no longer in use. If so, that would be very handy. If we can check when ReShade is installed, then it should be straightforward to stop moving the DLLs on each boot.

I can foresee a scenario (which would also occur on Windows, in fairness), something like this:

  1. User installs ReShade with dxgi.dll, and ReShade is working - Hooray!
  2. User installs a mod which uses dxgi.dll and ReShade stops working - Not hooray!
    • If a user can select multiple DLL names, such as dxgi.dll and d3d11.dll, maybe this is less of an issue
  3. User tries to reinstall ReShade, and then ReShade is working but their mods are not - Once again, not hooray!

The solution to this scenario is probably to further document a scenario like this on the ReShade wiki, and to let users know that selecting the ReShade DLL name is useful to avoid a scenario like this. But as noted this could happen on Windows too when mods which use DLL injection have a name that conflicts with the ReShade DLL.

Though if we back up an existing DLL and then a mod is using that DLL, and then a user uninstalls ReShade... hmm, I think I am overcomplicating scenarios now. I think users should be somewhat responsible for managing DLL name conflicts, since they would have to do this on Windows too if they manually renamed a DLL, then installed a mod which used that DLL, then tried to restore the renamed DLL which would then override the mod DLL.

Thinking further, I think the dropdown for the DLL names should have API names and not dll names

Mapping this might be a little tricky, but I will keep it in mind. We could also note some general guidance on the tooltip for which DLL name to choose, as well as noting on our wiki which names to choose. I do like the idea of having the API names which we then map them to the respective API names. For a minimal proof of concept I will work with the DLL names but will see if STL does this kind of mapping elsewhere (the GameScope menu might have some mapping, I did some whacky caffeine-fueled madness when I was refactoring that menu).


as I couldn't find an OpenGL game

They are few and far between in my experience, the only games I know of which use OpenGL are games using idTech 4 (i.e. DOOM 3/DOOM 3: BFG Edition), and there is an OpenGL backend for DOOM 2016 I believe as well. I own these games so I can try to test in future if ReShade OpenGL works with them :-)

@sonic2kk
Copy link
Owner

I am working on this on a branch now (reshade-dll-custom-name), I have the dropdown appearing but no actual ReShade DLL moving at the time of writing.

It should hopefully be straightforward enough to implement this.


I am not sure if we need to be concerned too much about existing ReShade installs? If a user is using d3d9 and dxgi DLLs, but a mod they installed overwrote the dxgi DLL, then now we're forcing ReShade to use dxgi by default, two things will happen:

  • the dxgi DLL that is actually a mod loader will be overwritten (more concerning)
  • they will have a stray d3d9.dll (less concerning, as this should only be a few megabytes)

I guess we can just tell users to check the changelog before updating? It will be noted there anyway, but I am moreso thinking for users on git packages like Pacstall or the AUR. Maybe changes like this should be considered "par for the course".

If we fix/change the behaviour of STL copying the ReShade DLLs on each boot, though, maybe this wouldn't be a problem to begin with.

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 20, 2023

Success! With commit 07140be, the selected ReShade DLL is copied into the game folder. There was even a little menu that appeared telling me that ReShade was installed and it asked me to go through a tutorial. I have no idea if shaders work, but the actual DLL appears to have been picked up by the game.

I only tested with dxgi.dll but I assume the behaviour should be equivalent to Windows now.

There are still a few outstanding todos:

  • If the user changes the selected DLL, such as switching from dxgi to d3d9, the previous ReShade DLL (i.e. dxgi) is not removed. We can probably manage removing this by checking ReShade.txt if it exists, and skipping the d3dcompiler_47. We can get every other DLL in this file (should only be 1 other in most cases, the last ReShade DLL that was in use), and then remove that before putting the new DLL in.
    • This is useful if the user switches to a DLL that does not work, it will be easy to switch back, but it is risky if this is a DLL a game needs (though verifying integrity of game files should restore the DLLs).
    • Existing behaviour seems to be that when ReShade is disabled, the DLLs in ReShade.txt (as well as this text file itself) are renamed with the suffix _off. Maybe we can just leave it up to the user to remove invalid ReShade DLLs themselves? Though I would like to remove these by parsing the ReShade text file. But I am not sure how this would work for existing ReShade installs, if a user is relying on d3d9.dll but dxgi.dll is the default, d3d9.dll will be removed. Maybe once again we should just direct users to the wiki.
  • We need to handle when the user passes multiple DLL names
  • Test to see if the ReShade DLLs are still being copied on each boot -- In my tests, it looks like this is no longer the case? The last updated time for the DLLs is not changing, so this will need further testing to see if this is resolved
    • It seems the DLLs are overwritten if the ReShade override option is enabled
  • Investigate adding a dropdown to "back up" any existing ReShade DLLs

I was able to verify that this new option worked even with the ReShade Override version (STL defaulted to 5.4.something, but I was able to force ReShade 5.9.1 and it worked great!)


EDIT: I tested over DLL names as well as a custom DLL name, and they worked. So basically right now, for the "happy path" to work (as in, brand new user who has never used ReShade before, and sets the correct DLL name), we just need to support comma-separated DLL names.

After that, we need to account for some problem cases:

  • User changes DLL name - Probably should remove any existing DLLs in ReShade.txt if the selected name(s) are not in that file (may be more challenging if the user inputs multiple ReShade DLL names)
  • Add option on how to handle existing DLLs, probably defaulting to "overwrite" for simplicity - Since we already have logic that can set ReShade DLLs to end with _off, it should be straightforward to do this but rename them to .bak (then when ReShade is disabled, rename any files with .bak to remove that suffix)
  • Testing around how to handle "existing" ReShade installs, which have two ReShade DLLs. Only one will probably ever be selected but the game may be using the d3d9 DLL instead of dxgi without the user even knowing - If this is removed, ReShade will stop working!
    • In this case as well, the user may end up with a "useless" DLL, since if the game is using dxgi, the d3d9.dll won't be in use
  • Testing with OpenGL games

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 20, 2023

Tested "DOOM 3: BFG Edition" with the opengl32.dll selected. This worked no issues, or at least up to the point of showing the little ReShade menu. It did need a manual DLL override which I set using Winecfg (launched from the One-Time Run menu, one of my favourite options I added to this menu 😄). Winecfg did warn me when doing this, but I guess ReShade is intelligent enough to hook into the "real" OpenGL DLL, so the game launched and played as expected under Proton.

20230820175438_1

I am not sure if we should set this override by default when OpenGL is selected. I think it may be a good idea but I am not sure if it could have any negative impacts... It is probably safe to simply do a little export for an override. I will test that now. If we do go the route of automatically setting a DLL override, we should note this on the wiki too in case it fails, or if the user wants to set a custom DLL override.

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 20, 2023

Turns out we already had code to set the D3D DLL overrides for ReShade, so I was able to append the opengl32=n,b override into this code as well. Easy! This is now available with commit caf3977. This should also make managing multiple DLLs even easier, if we just set the DLL overrides ourselves.

I am not sure how custom DLL names should work and if we should set this to n,b ourselves, but since it is a custom DLL it may be fine to leave it up to the exe to find this itself. We also have an STL option for passing DLL overrides. If this is a problem, we can deal with it when a user reports it.

So now we should handle multiple comma-separated DLL names, then consider how best to handle problem cases like existing ReShade installs and existing DLLs. I am not sure the more I think about it, how much of a priority this is to handle since the existing code doesn't, but we can think about that later :-)

@sonic2kk
Copy link
Owner

Okay, comma-seperated DLLs have now been implemented in commit b6bc166! I also tested to ensure that the standard behaviour of only having one DLL selected still works without issue.

So now the main thing left for implementation is handling some extra cases:

  • Changing the name of our custom DLLs - This works, but won't remove the old DLL. Do we want to manually remove any previous DLLs? This may involve re-creating ReShade.txt, since this tracks all ReShade DLLs we select, so if we rename a DLL the text file will store both DLLs
    • I am thinking it may be more convenient if we are able to implement this, for users on something like Steam Deck Game Mode or Linux Desktops using a GameScope Steam session at login (i.e. gamescope-session-git on Arch and equivalent on ChimeraOS).
    • This becomes problematic too if a game/mod is actually using a DLL that we try to remove!
  • How to handle existing ReShade installs, with and without the above. With the above implemented an existing install, using d3d9.dll and dxgi.dll, may get the DLL the game is actually using removed, and so ReShade will stop working.
  • Managing already existing DLLs when we move our DLLs into the game folder. Renaming them to .bak as discussed could work, and having a dropdown to define the behaviour may also work well with this too.

My thinking is that, because of the complexities around trying to manage this ourselves, we just leave it up to the user to remove any stray DLLs themselves. For managing overwriting DLLs, I'd be curious to know how ReShade handles this on Windows.

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 20, 2023

PR is up to implement this, pending more testing and so on (#881). It implements the main functionality of this issue, which is to rename DLLs to resolve the core issue that the game "Tales of Arise" crashes because it tries to read one of the ReShade DLLs. Now we only copy one, and let the user decide the name.

The UX portion of this issue will be tackled separately. In testing I have really come to appreciate how cumbersome this behaviour is, and I would like to change it :-)


If anyone is free to test the PR, including how it impacts existing ReShade installs, please do test and report back. This should work at least for Dirct3D 9/10/11 games, OpenGL games should hopefully work too. Vulkan may not work due to how ReShade uses the Vulkan layering system and this probably doesn't play nice/probably isn't even read by the Linux system Vulkan (maybe an LD_PRELOAD could fix this?)

@zany130
Copy link
Collaborator Author

zany130 commented Aug 20, 2023

Awesome work! Sorry, I wasn't able to get back sooner. As for

With the above implemented an existing install, using d3d9.dll and dxgi.dll, may get the DLL the game is actually using removed, and so ReShade will stop working

I don't think there is much that can be done other than warning users in the release notes and wiki.

Managing already existing DLLs when we move our DLLs into the game folder. Renaming them to .bak as discussed could work, and having a dropdown to define the behaviour may also work well with this too.

same for this. Most we can do is rename existing files to .bak or something and maybe have an option for controlling the behavior (no overwrite, overwrite, overwrite and backup (default) ) I don't know how useful that last option would be do and maybe it is just adding extra complexity for no reason.

We should warn users in the wiki and maybe in tooltips as well that this will override any existing .dll with the name chosen (opengl32 64, d3d9, dxgi d3d11` , etc .dll)

Vulkan may not work due to how ReShade uses the Vulkan layering system and this probably doesn't play nice/probably isn't even read by the Linux system Vulkan (maybe an LD_PRELOAD could fix this?)

AFAIK no one has really tried and succeded getting the vulkan layer working (and I think even if it did it wouldn't work on linux games, it would still need to be through wine and I don't think you can run games in wine with vulkan)

So I wouldn't worry about this use case, plus vkbasalt is recommend for this use case ( though its support of reshade features is not complete, mainly it lacks depth buffer access which is needed for most cool looking shaders)

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 22, 2023

I don't think there is much that can be done other than warning users in the release notes and wiki.

I'm ok with this approach 👍

Most we can do is rename existing files to .bak or something

Yeah, it might be extra complexity trying to manage renaming the files back. I'll look into dealing with existing DLLs before merging #881. Though having said that:

We should warn users in the wiki and maybe in tooltips as well that this will override any existing .dll with the name chosen (opengl32 64, d3d9, dxgi d3d11 , etc .dll)

This might be the simplest approach 😄

AFAIK no one has really tried and succeded getting the vulkan layer working (and I think even if it did it wouldn't work on linux games, it would still need to be through wine and I don't think you can run games in wine with vulkan)

It's very possible that ReShade Vulkan may not work, though Vulkan does actually work with games running through Wine 😄 Wine can point games to use the system OpenGL or Vulkan - at least afaik it's Wine that does it and not DXVK, Wine does have a winevulkan module which I think exists to facilitate this. I'm not a Wine developer though (sadly, maybe one day!). A couple notable Wine games you can use with system Vulkan are DOOM 2016 (and DOOM Eternal, or any game with a recent idTech engine), Hades, and Baldur's Gate 3.

ReShade would still not work with native Linux games though, because as far as I know, ReShade uses a Vulkan layer to try and inject the ReShade DLL into a game. For Proton games this might work depending on whether it's the system driver (i.e. mesa) responsible for handling the Vulkan layer. If that's the case it might get confused when it tries to read the ReShade DLL, but if it's read by the game (running via Proton) it may work. I am not sure to be honest, this is all out of my depth 😅 That's just my armchair understanding as of now.

If there was a way to get ReShade Vulkan to work I'm sure someone closer to it than me would've figured it out by now, but I'll still mess around and see if there's a way to get the game to read the Vulkan layer, as it probably wouldn't pick this up by default.


So to get #881 merged, I think I'll update the tooltip to note about how this will override any existing DLLs with the chosen name, look into perhaps making backups of those DLLs or having an option to (not sure, maybe I'll just default to backing them up, that might be much more straightforward), and then after that I'll prepare the updates to the wiki to note these changes to ReShade and the expected behaviour.

Feel free to test the PR when you have some time, or if not I'll just merge it as-is and if I'm horribly broken something I'm sure I'll hear about it 😄

@sonic2kk
Copy link
Owner

Okay, I did some more work on this tonight in #881. Here's a quick breakdown!

When we have an existing DLL, I went with this approach:

  • ReShade install, NO update:
    • if (DLL file with our chosen name exists in the game folder) and (we are NOT tracking this as an installed ReShade DLL in ReShade.txt) then
      • Mark the existing DLL as dll_name.dll.bak
      • Move our ReShade DLL into the game folder
      • Add this ReShade DLL to ReShade.txt so we are tracking it, this ensures we won't incorrectly flag this DLL as a duplicate
    • else
      • Copy the ReShade files over as normal
    • done
  • ReShade install, WITH update check
    • if (currently selected ReShade version in DLL matches selected version) then
      • Do nothing, DLL is up-to-date
    • else if (DLL file with our chosen name exists already in game folder) and (we are NOT tracking this as an installed ReShade DLL) then
      • Mark existing DLL as dll_name.bak
      • Move our ReShade DLL into the game folder (if an existing untracked ReShade file exists that doesn't equal the currently selected ReShade version, this acts as a backup+update logic since it will force in a ReShade DLL with the current ReShade version)
      • Add this ReShade DLL to ReShade.txt
      • Copy ReShade DLL to game folder as normal
    • else (in this scenario, the ReShade version in the DLL either does not match or returned no version information (i.e. not a ReShade DLL), AND the DLL is a tracked ReShade DLL already (already in ReShade.txt) so there isn't a conflicting DLL)
      • Update the existing, already tracked ReShade DLL with our new one which has a different version
    • done
  • done

I hope that breakdown made sense, it seems to work in my tests of doing fresh installs, removing the chosen DLL name(s) from the ReShade.txt folder, and messing around with the .bak files. On that, if the .bak file already exists, we just warn and overwrite it. I don't think it's worth it to make multiple backups.

There is no notifier for any of this but plenty of logging. I am not sure if it's worth it to add this in a notifier to be honest, it might be too noisy (and we're already a bit noisy with the notifier).

There is no dropdown to select this behaviour, I think just backing up existing DLLs is enough. We should never have a case where we back up an existing, STL-managed ReShade DLL, so if the game/a mod is using the chosen DLL name, the user should be able to go to the game files and rename the game/mod DLL that got backed up, back to the original name to restore functionality.

This behaviour will be documented on the wiki too. I think this is as far as I'll go for managing existing DLLs, so the warnings we discussed will be added to the wiki.


I updated the tooltip to be a bit more descriptive and helpful. I also added a quality of life feature to append .dll to any DLL names which don't have a file extension. Finally, I also added dxgi.dll,d3d9.dll to the dropdown for the ReShade DLL names, to make it a bit easier for users to "select" the old behaviour.

On the subject of the legacy behaviour, I think simply documenting on the wiki and changelog that this behaviour has changed and that only ony DLL is copied, is good enough. I am also not going to do any work with "removing" superfluous DLLs, hopefully having that approximately 4mb eaten up is acceptable to most users :-)


So with that, the following is currently implemented in #881:

  • Only one ReShade DLL is copied now, and the default name for this is dxgi,.dll - This should fix the issue with Tales of Arise
  • Added a dropdown to enter a ReShade DLL name, which you can either select a list of names from, or enter your own
    • If the name is missing a file extension, .dll will b appended automatically
    • This field can also take a list of comma-separated values for multiple DLL names
    • If the field is left blank, dxgi.dll is chosen as a fallback
    • If a custom name is chosen, a DLL override may need to be set manually by the user (STL has an option to set DLL override exports)
  • Gracefully handle cases when the ReShade DLL already exists in the game folder but is not tracked by STL as a ReShade DLL (back up the existing DLL so it is not lost, in case it is in use by the game/a mod)
  • Added ReShade support for OpenGL games by correctly setting the Wine override for opengl32.dll (we already do this for dxgi, etc)
  • Refactor installRSdll to be a bit cleaner and more robust when adding the ReShade DLL names to our list of tracked DLLs (and also refactor installd3d47dll to be more robust when adding itself to ReShade.txt as well)

I have tested the following games with these changes to ensure they launch and show the ReShade menu. I have not knowingly tested any DX10 games.

  • NieR:Automata (Direct3D 11)
  • Sonic Mania (Direct3D 9)
  • Let's zig zag (Direct3D 11)
  • DOOM 3: BFG Edition (OpenGL)

So with all that, and excluding the ReShade UX updates to reduce the number of checkboxes, all that's left for #881 is:

  • Test actual shaders, to ensure ReShade still works (it shows the ReShade menu for me in a number of games, but I have not tested any shaders as I am not even too sure how to use ReShade in general, not specific to STL)
  • Test to make sure this fixes the actual issue, which it should (once the d3d9 DLL is removed)
  • Update the wiki to document all of these changes to ReShade behaviour and functionality, as well as to link to various useful resources like the PCGamingWiki page for which API games use, so users can pick the right DLL

Once those three items are complete, #881 can be merged and the bulk of this issue will be resolved! I'll move onto tackling the ReShade checkboxes after it is merged, and maybe after #870 as well (just to clean up all loose ongoing threads of work first).

If you have any time please feel free to test these. In the meantime I'll try to work on updating the wiki page, which may take a while depending on my motivation, so there is no hurry on this. We all have lives and jobs, and anyone else reading this is free to test and see if anything has broken with my hacking around with STL's ReShade implementation.


Fingers crossed this will be all good and ready to merge soon!

@sonic2kk sonic2kk reopened this Aug 26, 2023
@sonic2kk
Copy link
Owner

PR was closed by mistake when merging #881, sorry about that.

There is some remaining work to be done from this issue:

  1. Consolidate ReShade installation checkboxes, as enable and install ReShade seem to be a bit much and confusing. Having only one should be more user-friendly.
  2. Investigate ReShade DLLs being overwritten on each boot when they don't need to be. They should only be overwritten when there is a version mismatch.

The first point will require a bit of a refactor, but I will look into it. The second point should be much more straightforward... hopefully... 😅

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 27, 2023

Taking a look at migrating the USERESHADE and INSTALL_RESHADE options now. It may be a bit of a delicate operation, so if anyone is able to test once this feature goes up on a branch and is ready for testing, be aware that your configuration files may get overwritten a little bit. I will do my own testing before putting it out there to make sure it doesn't cause any explosions.

@sonic2kk
Copy link
Owner

sonic2kk commented Aug 27, 2023

I noticed an issue after #881 where the ReShade DLL name ends up getting duplicated in the dropdown list, I'll investigate this too. It seems difficult to reproduce though.

@sonic2kk
Copy link
Owner

#888 is up to implement the ReShade checkbox consolidation. In my tests it seems to work, but please do take care while testing in case any STL ReShade checkbox options get mangled :-)

@sonic2kk
Copy link
Owner

Decided to live on the edge and merge #888. This change is now in master. We can revert if there are any glaring issues.

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 1, 2023

I have done some more testing since merging, I haven't been able to reproduce the issue of the duplicated DLL names in the DLL name box again, and the USERESHADE and INSTALL_RESHADE merging seems to be working fine in my tests. I am not very close to ReShade usage though so there could be other oddities

I haven't had much time to look into the ReShade DLLs getting overwritten on each boot since before where I couldn't re-create that behaviour, but if it's still a problem I can look into fixing it again.

Aside from that, this issue can be closed once those two outstanding points are resolved 🥳 (recreating the DLLs on each boot, and additional testing on the features implemented as part of this issue)

@zany130
Copy link
Collaborator Author

zany130 commented Sep 1, 2023

Sorry, I didn't respond earlier, got sick with covid.

Anyway, I have been playing Tales of Arise here and there since then, and I think the USERSHADE and INSTALL_RESHADE merging went fine. My settings seem to have migrated fine, and everything is working as expected

as for the DLLs being recreated on each boot it seems it is still happening as every launch of the game seems to modify the dxgi.dll file

you can see from the following line in the log it is saying the DLL is being updated

installRSdll - Destfile '/home/zany130/.local/share/Steam/steamapps/common/Tales of Arise/Arise/Binaries/Win64/dxgi.dll' already exists, but has a different version or is not a ReShade DLL - updating

740130.log

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 2, 2023

That's no fun, hope you get over it soon :-)

Thanks for attaching a log, it seems like based on that and the line you pointed out, the ReShade version check is not working. The logic in STL right now checks the version of ReShade by parsing the DLL. It does this specifically:

grep -q "$RSVERS" <<< "$(strings "$INSTDESTDIR/$1" | grep "^Initializing")"

If you navigate to the game directory with the ReShade DLL and run strings "dxgi.dll" | grep "^Initializing", you should see a line along the lines of Initializing crosire's ReShade version '5.9.1.1755' (32-bit) loaded from (it gets cut off because of how strings outputs the "stringified" DLL). Version and architecture will vary of course :-)

It seems that for some reason, trying to grep the selected ReShade version from the DLL string is failing. I have not tried with ReShade 5.9.2 yet, but I noticed in the log that you're using 5.9.2_Addon. In the example above, we can still grep the ReShade version, even though it's 5.9.1.1755. It isn't looking for an exact word match. However, I am not sure what ReShade Addon DLLs return. I am going to check and see if it returns the version differently, perhaps this is why the version check is failing.

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 2, 2023

Ah, so I think I figured it out. It isn't that the Addon DLL is returning the wrong version (it isn't, strings dxgi.dll | grep "^Initializing" returns Initializing crosire's ReShade version '5.9.2.1761' (32-bit) loaded from), but that RSVERS is actually 5.9.2_Addon -- WITH the _Addon suffix. So the STL grep statement actually looks like this:

grep -q "5.9.2_Addon" <<< "$(strings "$INSTDESTDIR/$1" | grep "^Initializing")"

And of course, the version in the ReShade DLL does not include _Addon. So the check fails, and STL thinks that it needs to update. You could test this yourself, if you go to the game config file the RSOVRVERS will be suffixed with _Addon (or in the global config I think you can do this too). Then you could run this command from terminal in the game directory with the ReShade DLL:

if grep -q "5.9.2_Addon" <<< "$( strings dxgi.dll | grep "^Initializing" )"; then echo "reshade up to date"; else echo "reshade needs updating"; fi

It will return reshade needs updating each time, because it's trying to grep for a version string that includes _Addon.


The solution to this will probably be to create a "clean" ReShade version to check against, probably by using parameter expansion as the cleanest method as it should hopefully mean we don't have to create a temporary variable to store this. This is a lot simpler than trying to change how we store RSOVRVERS (there is a potential solution of storing an indicator to mark when we want to use ReShade Addon but that's messy and I don't want to go that road; I like the way you have implemented it more, with appending _Addon to use the ReShade Addon version).

Should hopefully be an easy fix, and one I will be doing without any Dr Pepper or coffee as it is 2am, so here goes! 😅

sonic2kk added a commit that referenced this issue Sep 2, 2023
@sonic2kk
Copy link
Owner

sonic2kk commented Sep 2, 2023

Pushed this one directly to master for giggles, 57cfc4e should hopefully resolve this version issue. I used ${RSVERS%%_*} to strip the ReShade version of the _Addon suffix, making it so 5.9.2_Addon -> 5.9.2. This should, with some luck, allow the version check to function correctly.

@zany130
Copy link
Collaborator Author

zany130 commented Sep 5, 2023

Never thought about the issue being the _Addon suffix, but you were totally correct. And it makes sense now because I was appending it to the version (so that it could grab the right dll from upstream since the addon dll is always RSVERS_Addon

Nice find and yeah your solution works perfectly it ignores the suffix because we don't care about that for our purposes here .

I think this issue is ready for closing now ?

@sonic2kk
Copy link
Owner

sonic2kk commented Sep 5, 2023

Woohoo, this issue can be closed I think! Sorry it took over a month for me to get around to actually fixing everything outlined here, and thanks for all your input with it :-) I hope this makes the ReShade experience a bit easier!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants