Updating RendDx9 to use LAA D3DX9
Posted: 2021-03-15 21:23
BF2 has been compiled using the Large Address Aware (LAA) flag. That allows the process to use up to 4gb of memory. However RendDx9 does not use Direct3D in LAA mode, so using more than 2gb memory might cause crashes coming from Direct3D. This tutorial shows how to edit the shaders and Renddx9.dll in order to use LAA mode for Direct3D and use full 4gb of memory.
1. Shader preparation
To use the LAA flag we need to link RendDx9 to a newer d3dx9.dll. However those no longer support the shadermodel 1.3 and 1.4 that is used across the BF2 shaders. As such the first step is to prepare the shaders to use more modern shadermodel 2.0. For PR we went with shadermodel 2.0a. (Note: In theory SM3.0 could be possible, but it does not support enough input registers when used with DirectX 9).
1.1 Cleaning shaders
Before starting to convert shaders to the newer shadermodel, you should clean up a bit to cut down on the amount of code to adjust.
1.2 Update existing HLSL shadermodel
Next you should change all existing HLSL shaders to use the newer shadermodel. This is mostly a find-replace job. Just as with the DICE datatype, I suggest to get rid of all the existing shadermodel definitions (e.g. PSMODEL or PS2_EXT) and instead use the default ps_2_0, ps_2_a, ps_2_b and vs_2_0, vs_2_a, vs_2_b instead. Again this makes things easier to read and share with people outside of BF2 world.
You also need to replace all the passes that use the name "point" to something like "point_". Point is a predefined control word in newer DirectX.
1.3 Updating inline ASM code
DICE used a lot of inline ASM code to reduce the amount of instructions in some shaders. This code is mostly written in shadermodel 1.3 or 1.4, so no longer supported for the newer DirectX. Updating this is the hardest part of the shader preparation. You have 2 options:
Helpful resources: 2. Updating RendDx9.dll
To use DirectX with LAA addresses, you need to create the effects with the D3DXFX_LARGEADDRESSAWARE flag. Here we edited the ShaderManager to add this flag in the constructor.
Since with LAA enabled you can no longer use names to address resources inside an effect and DICE uses this in some places. So these are the other things that need changing. Then there are some minor things that need fixing like taking screenshots in a different D3DFORMAT.
For PR we already did all this and you are free to use this as long as you credit us or in case it causes crashes, blame us
Explanation of the format:
The code snippets in comments reference loaded addresses, not file offsets.
After this just need to replace d3dx9_25.dll with d3dx9_43.dll (latest DirectX 9). BF2 also loads d3dx9_24.dll dynamically to fix some obscure bug. This should still get used. Using the d3dx9_43.dll here causes crashes and the d3dx9_24.dll does not seem to cause any further issues regarding high memory.
3. Updating TextureAtlasBuilder.dll and bf2.exe
These 2 are optional, but recommended. In TextureAtlasBuilder.dll you just need to change d3dx9_25.dll to d3dx9_43.dll. It wont change much, but reduces the amount of different d3dx9 getting loaded.
For bf2.exe I recommend to also apply this fix for loading minimap icons that have an address above the 2gb memory space.
4. Issues to be aware off
These changes are all part of current PR and thus have been tested by quite some people on different system. As such for the most part these can be considered stable. However one big issue are players using graphics mods like Reshade or overlays like Overwolf. These might no longer work with the updated shaders/d3dx9 and can cause crashes.
1. Shader preparation
To use the LAA flag we need to link RendDx9 to a newer d3dx9.dll. However those no longer support the shadermodel 1.3 and 1.4 that is used across the BF2 shaders. As such the first step is to prepare the shaders to use more modern shadermodel 2.0. For PR we went with shadermodel 2.0a. (Note: In theory SM3.0 could be possible, but it does not support enough input registers when used with DirectX 9).
1.1 Cleaning shaders
Before starting to convert shaders to the newer shadermodel, you should clean up a bit to cut down on the amount of code to adjust.
- Remove all the unneeded effect files
- Remove all the unreachable code inside of _FORCE_1_3_, _FORCE_1_4_ and #if 0 brachnes
- Remove all the commented out shader code. Those are often things to reproduce bugs we have no clue about any more.
1.2 Update existing HLSL shadermodel
Next you should change all existing HLSL shaders to use the newer shadermodel. This is mostly a find-replace job. Just as with the DICE datatype, I suggest to get rid of all the existing shadermodel definitions (e.g. PSMODEL or PS2_EXT) and instead use the default ps_2_0, ps_2_a, ps_2_b and vs_2_0, vs_2_a, vs_2_b instead. Again this makes things easier to read and share with people outside of BF2 world.
You also need to replace all the passes that use the name "point" to something like "point_". Point is a predefined control word in newer DirectX.
1.3 Updating inline ASM code
DICE used a lot of inline ASM code to reduce the amount of instructions in some shaders. This code is mostly written in shadermodel 1.3 or 1.4, so no longer supported for the newer DirectX. Updating this is the hardest part of the shader preparation. You have 2 options:
- Update the ASM to your chosen shadermodel
- Rewrite the ASM in HLSL and compile it with your chosen shadermodel
Helpful resources: 2. Updating RendDx9.dll
To use DirectX with LAA addresses, you need to create the effects with the D3DXFX_LARGEADDRESSAWARE flag. Here we edited the ShaderManager to add this flag in the constructor.
Since with LAA enabled you can no longer use names to address resources inside an effect and DICE uses this in some places. So these are the other things that need changing. Then there are some minor things that need fixing like taking screenshots in a different D3DFORMAT.
For PR we already did all this and you are free to use this as long as you credit us or in case it causes crashes, blame us

Explanation of the format:
Code: Select all
[...] defines the file to edit
A: file offset of the bytes to change
O: Original bytes
N: New bytes
#: Comments
Spoiler for RendDx9.dll:
3. Updating TextureAtlasBuilder.dll and bf2.exe
These 2 are optional, but recommended. In TextureAtlasBuilder.dll you just need to change d3dx9_25.dll to d3dx9_43.dll. It wont change much, but reduces the amount of different d3dx9 getting loaded.
For bf2.exe I recommend to also apply this fix for loading minimap icons that have an address above the 2gb memory space.
Spoiler for bf2.exe:
4. Issues to be aware off
These changes are all part of current PR and thus have been tested by quite some people on different system. As such for the most part these can be considered stable. However one big issue are players using graphics mods like Reshade or overlays like Overwolf. These might no longer work with the updated shaders/d3dx9 and can cause crashes.