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

Fix vsync, oPos register and RenderState #108

Merged
merged 2 commits into from
Feb 3, 2020
Merged

Conversation

elishacloud
Copy link
Contributor

@elishacloud elishacloud commented Feb 3, 2020

This pull request fixes #49
This pull request fixes #63
This pull request fixes #86
This pull request fixes #103
This pull also fixes AquaNox, which never worked before with d3d8to9.

There are three main updates in this pull:

  1. Fixes present parameters to match the documentation.

This will properly set the vsync based on whether the game is usin windowed or fullscreen. This also removes the code that forced D3DMULTISAMPLE_NONE, as this broke some AA functions.

  1. Fixes oPos register swizzles in VertexShader

AquaNox uses almost 100 VirtexShaders. Several of them would set only on the x and y components of the pPos register, which is not allowed in DirectX9. See sample below.

Before fix (see error):

> Dumping translated shader assembly:

    vs_1_1
    dcl_position v0
    dcl_blendweight v1
    dcl_blendindices v2
    dcl_normal v3
    dcl_psize v4
    mov r0, c0 /* initialize register r0 */
    mov oT1, c0 /* initialize output register oT1 */
    mov oT0, c0 /* initialize output register oT0 */
    mul r0.xy, v3, c23
    add oPos.xy, r0, c22      //  <--  Error is here
    mov oT0.xy, v3
    mul r0.xy, v3, c25
    add oT1.xy, r0, c24

// approximately 5 instruction slots used

> Failed to reassemble shader:

d:\games\aquanox\memory(17,1): error X5350: Vertex shader must minimally write all four components (xyzw) of oPos output register.  Missing components(*): x/0 y/1 *z/2 *w/3

After fix:

> Dumping translated shader assembly:

    vs_1_1
    dcl_position v0
    dcl_blendweight v1
    dcl_blendindices v2
    dcl_normal v3
    dcl_psize v4
    mov r0, c0 /* initialize register r0 */
    mov oT1, c0 /* initialize output register oT1 */
    mov oT0, c0 /* initialize output register oT0 */
    mul r0.xy, v3, c23
    add oPos, r0, c22 /* removed oPos swizzles */
    mov oT0.xy, v3
    mul r0.xy, v3, c25
    add oT1.xy, r0, c24

// approximately 5 instruction slots used
  1. Changes how SetRenderState/GetRenderState works with the following States: D3DRS_LINEPATTERN, D3DRS_EDGEANTIALIAS and D3DRS_PATCHSEGMENTS

These states were removed in DirectX9. For D3DRS_LINEPATTERN and D3DRS_PATCHSEGMENTS this changes from returning D3DERR_INVALIDCALL to returning D3D_OK. It also changes D3DRS_EDGEANTIALIAS to use D3DRS_ANTIALIASEDLINEENABLE instead.

These changes are required for AquaNox because AquaNox would monitor the return call and fail out if anything other than D3D_OK is returned.

Some games, like Command and Conquer Generals and Silent Hill 2 require system memory.  Other games like Forsaken World require scratch memory and will fail if system memory is used.  Trying system memory first and then scratch memory seems to work for all games.
- Fixes present parameters to match the documentation
- Fixes oPos register swizzles in VertexShader
- Changes how RenderState works with the follwoing States: 'D3DRS_LINEPATTERN', 'D3DRS_EDGEANTIALIAS' and 'D3DRS_PATCHSEGMENTS'
@crosire
Copy link
Owner

crosire commented Feb 3, 2020

Awesome work!

@crosire crosire merged commit 708ca24 into crosire:master Feb 3, 2020
@CookiePLMonster
Copy link
Contributor

CookiePLMonster commented May 13, 2024

This makes GTA III and Vice City not use vsync when running in windowed mode (forced by another mod), even though games should request vsync. Is this intended?

EDIT:
I should have checked the code before asking:
// Windowed mode should always present immediately

That doesn't match my experience though, PRESENT_ONE always worked fine in windowed. Where is this change coming from?

EDIT2:
OK I see that it's just DX8's behaviour... That is not optimal to be fair, but I can understand the reasoning. It makes using windowed mode in GTA quite annoying though.

@elishacloud
Copy link
Contributor Author

@CookiePLMonster, this may be the behavior of Windows when using Direct3D9. Native Direct3D8 it uses "Composed: Copy with GPU GDI", but with d3d8to9 it uses "Hardware Composed: Independent Flip". These modes handle vsync (and GDI) differently. I found out if you call Direct3D9SetSwapEffectUpgradeShim(0) it will switch the Direct3D9 mode back.

See this thread for more details.

@CookiePLMonster
Copy link
Contributor

I found out if you call Direct3D9SetSwapEffectUpgradeShim(0) it will switch the Direct3D9 mode back.

Would that be worth doing for d3d8to9 then, or is forced-no-vsync the behaviour you desire in this scenario?

@elishacloud
Copy link
Contributor Author

I found out if you call Direct3D9SetSwapEffectUpgradeShim(0) it will switch the Direct3D9 mode back.

Would that be worth doing for d3d8to9 then, or is forced-no-vsync the behaviour you desire in this scenario?

See comments here to answer that question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants