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

prevent missing polygons with AMD GPU #1865

Merged
merged 3 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/core/hle/D3D8/Direct3D9/CxbxVertexShaderTemplate.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,16 @@ float4 c(int register_number)
// Map Xbox [-96, 95] to Host [0, 191]
// Account for Xbox's negative constant indexes
register_number += X_D3DSCM_CORRECTION;
if (register_number < 0)
return 0;


// Like Xbox, out-of-range indices are guaranteed to be zero in HLSL
// so no need to bounds check negative numbers
// if (register_number < 0)
// return 0;

// If the index is too large, set it to -1 so 0 is returned
// Note: returning 0 directly requires many more instructions
Comment on lines +52 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely optimization, thanks for the idea @NZJenkins!

if (register_number >= X_D3DVS_CONSTREG_COUNT) // X_D3DVS_CONSTREG_COUNT
return 0;
register_number = -1;

return C[register_number];
}
Expand Down
11 changes: 11 additions & 0 deletions src/core/hle/D3D8/Direct3D9/Direct3D9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,17 @@ VOID EmuD3DInit()
std::cout << "Host D3DCaps : " << g_D3DCaps << "\n";
std::cout << "----------------------------------------\n";
}

// AMD compatibility workaround since VS model 3.0 doesn't work as intended with Direct3D9.
{
D3DADAPTER_IDENTIFIER9 adapter_info;
HRESULT status = g_pDirect3D->GetAdapterIdentifier(g_EmuCDPD.Adapter, 0, &adapter_info);
// 1002 and 1022 are vendor ids of AMD gpus
if (status == D3D_OK && (adapter_info.VendorId == 0x1002 || adapter_info.VendorId == 0x1022)) {
g_vs_model = vs_model_2_a;
EmuLogInit(LOG_LEVEL::WARNING, "AMD GPU Detected, falling back to shader model 2.X to prevent missing polygons");
}
}
}

// cleanup Direct3D
Expand Down
11 changes: 6 additions & 5 deletions src/core/hle/D3D8/Direct3D9/VertexShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <sstream>

extern const char* g_vs_model = vs_model_3_0;

// HLSL generation
void OutputHlsl(std::stringstream& hlsl, VSH_IMD_OUTPUT& dest)
{
Expand Down Expand Up @@ -247,9 +249,8 @@ extern HRESULT EmuCompileShader
EmuLog(LOG_LEVEL::DEBUG, DebugPrependLineNumbers(hlsl_str).c_str());
EmuLog(LOG_LEVEL::DEBUG, "-----------------------");

// Level 0 for fastest runtime compilation
// TODO Can we recompile an optimized shader in the background?
UINT flags1 = D3DCOMPILE_OPTIMIZATION_LEVEL0;

UINT flags1 = D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_AVOID_FLOW_CONTROL;

hRet = D3DCompile(
hlsl_str.c_str(),
Expand All @@ -258,7 +259,7 @@ extern HRESULT EmuCompileShader
nullptr, // pDefines
nullptr, // pInclude // TODO precompile x_* HLSL functions?
"main", // shader entry poiint
"vs_3_0", // shader profile
g_vs_model, // shader profile
flags1, // flags1
0, // flags2
ppHostShader, // out
Expand All @@ -275,7 +276,7 @@ extern HRESULT EmuCompileShader
nullptr, // pDefines
nullptr, // pInclude // TODO precompile x_* HLSL functions?
"main", // shader entry poiint
"vs_3_0", // shader profile
g_vs_model, // shader profile
flags1, // flags1
0, // flags2
ppHostShader, // out
Expand Down
4 changes: 4 additions & 0 deletions src/core/hle/D3D8/Direct3D9/VertexShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ enum class ShaderType {
Unsupported,
};

static const char* vs_model_2_a = "vs_2_a";
static const char* vs_model_3_0 = "vs_3_0";
extern const char* g_vs_model;

extern ShaderType EmuGetShaderInfo(IntermediateVertexShader* pIntermediateShader);

extern HRESULT EmuCompileShader
Expand Down