Skip to content

Commit

Permalink
Fix V-Sync plus some render states and code generation for oPos regis…
Browse files Browse the repository at this point in the history
…ter (#108)
  • Loading branch information
elishacloud authored Feb 3, 2020
1 parent 6e64089 commit 708ca24
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
27 changes: 22 additions & 5 deletions source/d3d8to9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,13 +787,14 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::SetRenderState(D3DRENDERSTATETYPE Sta

switch (static_cast<DWORD>(State))
{
case D3DRS_LINEPATTERN:
case D3DRS_ZVISIBLE:
case D3DRS_EDGEANTIALIAS:
case D3DRS_PATCHSEGMENTS:
return D3DERR_INVALIDCALL;
case D3DRS_PATCHSEGMENTS:
case D3DRS_LINEPATTERN:
case D3DRS_SOFTWAREVERTEXPROCESSING:
return D3D_OK;
case D3DRS_EDGEANTIALIAS:
return ProxyInterface->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, Value);
case D3DRS_CLIPPLANEENABLE:
hr = ProxyInterface->SetRenderState(State, Value);
if (SUCCEEDED(hr))
Expand Down Expand Up @@ -821,10 +822,13 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::GetRenderState(D3DRENDERSTATETYPE Sta

switch (static_cast<DWORD>(State))
{
case D3DRS_LINEPATTERN:
case D3DRS_ZVISIBLE:
case D3DRS_EDGEANTIALIAS:
return D3DERR_INVALIDCALL;
case D3DRS_LINEPATTERN:
*pValue = 0;
return D3D_OK;
case D3DRS_EDGEANTIALIAS:
return ProxyInterface->GetRenderState(D3DRS_ANTIALIASEDLINEENABLE, pValue);
case D3DRS_ZBIAS:
hr = ProxyInterface->GetRenderState(D3DRS_DEPTHBIAS, pValue);
*pValue = static_cast<DWORD>(*reinterpret_cast<const FLOAT *>(pValue) * -500000.0f);
Expand Down Expand Up @@ -1463,6 +1467,19 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::CreateVertexShader(const DWORD *pDecl
}
}

// Vertex shader must minimally write all four components (xyzw) of oPos output register. (fix error X5350)
if (std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.")) && !std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos,")))
{
bool xReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[y|z|w]*x"));
bool yReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|z|w]*y"));
bool zReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|y|w]*z"));
bool wReg = std::regex_search(SourceCode, std::regex(" ([a-z2-4]*) oPos\\.[x|y|z]*w"));
if (!xReg || !yReg || !zReg || !wReg)
{
SourceCode = std::regex_replace(SourceCode, std::regex(" ([a-z2-4]*) (oPos\\.[x|y|z|w]*,) ([^\\n]*)\\n"), " $1 oPos, $3 /* removed oPos swizzles */\n");
}
}

#ifndef D3D8TO9NOLOG
LOG << "> Dumping translated shader assembly:" << std::endl << std::endl << SourceCode << std::endl;
#endif
Expand Down
26 changes: 13 additions & 13 deletions source/d3d8types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ static UINT CalcTextureSize(UINT Width, UINT Height, UINT Depth, D3DFORMAT Forma
return ((Width + 3) >> 2) * ((Height + 3) >> 2) * 16;
}
}

void ConvertCaps(D3DCAPS9 &Input, D3DCAPS8 &Output)
{
CopyMemory(&Output, &Input, sizeof(Output));
Expand All @@ -82,7 +81,6 @@ void ConvertCaps(D3DCAPS9 &Input, D3DCAPS8 &Output)
// D3D8 can only handle up to 256 for MaxVertexShaderConst
Output.MaxVertexShaderConst = min(256, Input.MaxVertexShaderConst);
}

void ConvertVolumeDesc(D3DVOLUME_DESC &Input, D3DVOLUME_DESC8 &Output)
{
Output.Format = Input.Format;
Expand All @@ -104,14 +102,7 @@ void ConvertSurfaceDesc(D3DSURFACE_DESC &Input, D3DSURFACE_DESC8 &Output)
Output.MultiSampleType = Input.MultiSampleType;
Output.Width = Input.Width;
Output.Height = Input.Height;

// Check for D3DMULTISAMPLE_NONMASKABLE and change it to D3DMULTISAMPLE_NONE for best D3D8 compatibility.
if (Output.MultiSampleType == D3DMULTISAMPLE_NONMASKABLE)
{
Output.MultiSampleType = D3DMULTISAMPLE_NONE;
}
}

void ConvertPresentParameters(D3DPRESENT_PARAMETERS8 &Input, D3DPRESENT_PARAMETERS &Output)
{
Output.BackBufferWidth = Input.BackBufferWidth;
Expand All @@ -136,22 +127,31 @@ void ConvertPresentParameters(D3DPRESENT_PARAMETERS8 &Input, D3DPRESENT_PARAMETE
}

// D3DPRESENT_RATE_UNLIMITED is no longer supported in D3D9
if (Output.PresentationInterval == D3DPRESENT_RATE_UNLIMITED)
if (Output.FullScreen_RefreshRateInHz == D3DPRESENT_RATE_UNLIMITED)
{
Output.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
}

// Windowed mode should always present immediately
if (Output.Windowed)
{
Output.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}

// D3DPRESENT_INTERVAL_DEFAULT is defined as zero and is equivalent to D3DPRESENT_INTERVAL_ONE in D3D9
if (Output.PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT)
// Fulscreen mode defaults to D3DPRESENT_INTERVAL_ONE
if (!Output.Windowed && Output.PresentationInterval == D3DPRESENT_INTERVAL_DEFAULT)
{
Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
}

// D3DSWAPEFFECT_COPY_VSYNC is no longer supported in D3D9
if (Output.SwapEffect == D3DSWAPEFFECT_COPY_VSYNC)
{
Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
Output.SwapEffect = D3DSWAPEFFECT_COPY;
if (!Output.Windowed && Output.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE)
{
Output.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
}
}
}
void ConvertAdapterIdentifier(D3DADAPTER_IDENTIFIER9 &Input, D3DADAPTER_IDENTIFIER8 &Output)
Expand Down

0 comments on commit 708ca24

Please sign in to comment.