D3D11: Implement zcomploc for hardware supporting D3D 11.0.
This commit is contained in:
parent
805009abca
commit
eed36cbf78
|
@ -805,6 +805,7 @@ union PE_CONTROL
|
||||||
u32 unused : 17;
|
u32 unused : 17;
|
||||||
u32 rid : 8;
|
u32 rid : 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 hex;
|
u32 hex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1005,6 +1006,9 @@ struct BPMemory
|
||||||
TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd
|
TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd
|
||||||
u32 bpMask; //0xFE
|
u32 bpMask; //0xFE
|
||||||
u32 unknown18; //ff
|
u32 unknown18; //ff
|
||||||
|
|
||||||
|
bool UseEarlyDepthTest() const { return zcontrol.early_ztest && zmode.testenable; }
|
||||||
|
bool UseLateDepthTest() const { return !zcontrol.early_ztest && zmode.testenable; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
@ -258,8 +258,8 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
|
||||||
unsigned int numStages = bpmem.genMode.numtevstages + 1;
|
unsigned int numStages = bpmem.genMode.numtevstages + 1;
|
||||||
unsigned int numTexgen = bpmem.genMode.numtexgens;
|
unsigned int numTexgen = bpmem.genMode.numtexgens;
|
||||||
|
|
||||||
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.zcontrol.early_ztest && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
||||||
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) || (!g_ActiveConfig.bFastDepthCalc && !forced_early_z);
|
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && !forced_early_z);
|
||||||
|
|
||||||
out.Write("//Pixel Shader for TEV stages\n");
|
out.Write("//Pixel Shader for TEV stages\n");
|
||||||
out.Write("//%i TEV stages, %i texgens, %i IND stages\n",
|
out.Write("//%i TEV stages, %i texgens, %i IND stages\n",
|
||||||
|
@ -372,11 +372,30 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
|
||||||
// It just allows it, but it seems that all drivers do.
|
// It just allows it, but it seems that all drivers do.
|
||||||
out.Write("layout(early_fragment_tests) in;\n");
|
out.Write("layout(early_fragment_tests) in;\n");
|
||||||
}
|
}
|
||||||
|
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
|
||||||
|
{
|
||||||
|
static bool warn_once = true;
|
||||||
|
if (warn_once)
|
||||||
|
WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required).");
|
||||||
|
warn_once = false;
|
||||||
|
}
|
||||||
|
|
||||||
out.Write("void main()\n{\n");
|
out.Write("void main()\n{\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (forced_early_z)
|
||||||
|
{
|
||||||
|
out.Write("[earlydepthstencil]\n");
|
||||||
|
}
|
||||||
|
else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
|
||||||
|
{
|
||||||
|
static bool warn_once = true;
|
||||||
|
if (warn_once)
|
||||||
|
WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current configuration. Make sure to use the D3D11 or OpenGL backend and enable fast depth calculations. If this message still shows up your hardware isn't able to emulate the feature properly (a GPU which supports D3D 11.0 / OGL 4.2 is required).");
|
||||||
|
warn_once = false;
|
||||||
|
}
|
||||||
|
|
||||||
out.Write("void main(\n");
|
out.Write("void main(\n");
|
||||||
if(ApiType != API_D3D11)
|
if(ApiType != API_D3D11)
|
||||||
{
|
{
|
||||||
|
@ -630,11 +649,11 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
|
||||||
uid_data.per_pixel_depth = per_pixel_depth;
|
uid_data.per_pixel_depth = per_pixel_depth;
|
||||||
uid_data.forced_early_z = forced_early_z;
|
uid_data.forced_early_z = forced_early_z;
|
||||||
uid_data.fast_depth_calc = g_ActiveConfig.bFastDepthCalc;
|
uid_data.fast_depth_calc = g_ActiveConfig.bFastDepthCalc;
|
||||||
uid_data.early_ztest = bpmem.zcontrol.early_ztest;
|
uid_data.early_ztest = bpmem.UseEarlyDepthTest();
|
||||||
uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel;
|
uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel;
|
||||||
|
|
||||||
// Note: z-textures are not written to depth buffer if early depth test is used
|
// Note: z-textures are not written to depth buffer if early depth test is used
|
||||||
if (per_pixel_depth && bpmem.zcontrol.early_ztest)
|
if (per_pixel_depth && bpmem.UseEarlyDepthTest())
|
||||||
out.Write("depth = zCoord;\n");
|
out.Write("depth = zCoord;\n");
|
||||||
|
|
||||||
// Note: depth texture output is only written to depth buffer if late depth test is used
|
// Note: depth texture output is only written to depth buffer if late depth test is used
|
||||||
|
@ -652,7 +671,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
|
||||||
out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n");
|
out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (per_pixel_depth && !bpmem.zcontrol.early_ztest)
|
if (per_pixel_depth && bpmem.UseLateDepthTest())
|
||||||
out.Write("depth = zCoord;\n");
|
out.Write("depth = zCoord;\n");
|
||||||
|
|
||||||
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
|
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
|
||||||
|
@ -1189,7 +1208,7 @@ static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE Api
|
||||||
// OpenGL 4.2 has a flag which allows the driver to still update the depth buffer
|
// OpenGL 4.2 has a flag which allows the driver to still update the depth buffer
|
||||||
// if alpha test fails. The driver doesn't have to, but I assume they all do because
|
// if alpha test fails. The driver doesn't have to, but I assume they all do because
|
||||||
// it's the much faster code path for the GPU.
|
// it's the much faster code path for the GPU.
|
||||||
uid_data.alpha_test_use_zcomploc_hack = bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable && !g_ActiveConfig.backend_info.bSupportsEarlyZ;
|
uid_data.alpha_test_use_zcomploc_hack = bpmem.UseEarlyDepthTest() && bpmem.zmode.updateenable && !g_ActiveConfig.backend_info.bSupportsEarlyZ;
|
||||||
if (!uid_data.alpha_test_use_zcomploc_hack)
|
if (!uid_data.alpha_test_use_zcomploc_hack)
|
||||||
{
|
{
|
||||||
out.Write("\t\tdiscard;\n");
|
out.Write("\t\tdiscard;\n");
|
||||||
|
|
|
@ -245,6 +245,13 @@ std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter)
|
||||||
return aa_modes;
|
return aa_modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter)
|
||||||
|
{
|
||||||
|
D3D_FEATURE_LEVEL feat_level = D3D_FEATURE_LEVEL_9_1;
|
||||||
|
PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, NULL, &feat_level, NULL);
|
||||||
|
return feat_level;
|
||||||
|
}
|
||||||
|
|
||||||
DXGI_SAMPLE_DESC GetAAMode(int index)
|
DXGI_SAMPLE_DESC GetAAMode(int index)
|
||||||
{
|
{
|
||||||
return aa_modes[index];
|
return aa_modes[index];
|
||||||
|
|
|
@ -31,6 +31,7 @@ void UnloadD3D();
|
||||||
void UnloadD3DX();
|
void UnloadD3DX();
|
||||||
void UnloadD3DCompiler();
|
void UnloadD3DCompiler();
|
||||||
|
|
||||||
|
D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter);
|
||||||
std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter);
|
std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter);
|
||||||
DXGI_SAMPLE_DESC GetAAMode(int index);
|
DXGI_SAMPLE_DESC GetAAMode(int index);
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,6 @@ void InitBackendInfo()
|
||||||
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
g_Config.backend_info.bSupportsFormatReinterpretation = true;
|
||||||
g_Config.backend_info.bSupportsPixelLighting = true;
|
g_Config.backend_info.bSupportsPixelLighting = true;
|
||||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||||
g_Config.backend_info.bSupportsEarlyZ = false;
|
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* ad;
|
IDXGIAdapter* ad;
|
||||||
|
@ -103,11 +102,13 @@ void InitBackendInfo()
|
||||||
g_Config.backend_info.AAModes.clear();
|
g_Config.backend_info.AAModes.clear();
|
||||||
while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND)
|
while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND)
|
||||||
{
|
{
|
||||||
|
const size_t adapter_index = g_Config.backend_info.Adapters.size();
|
||||||
|
|
||||||
DXGI_ADAPTER_DESC desc;
|
DXGI_ADAPTER_DESC desc;
|
||||||
ad->GetDesc(&desc);
|
ad->GetDesc(&desc);
|
||||||
|
|
||||||
// TODO: These don't get updated on adapter change, yet
|
// TODO: These don't get updated on adapter change, yet
|
||||||
if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter)
|
if (adapter_index == g_Config.iAdapter)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
std::vector<DXGI_SAMPLE_DESC> modes;
|
std::vector<DXGI_SAMPLE_DESC> modes;
|
||||||
|
@ -119,6 +120,9 @@ void InitBackendInfo()
|
||||||
else sprintf_s(buf, 32, _trans("%d samples"), modes[i].Count);
|
else sprintf_s(buf, 32, _trans("%d samples"), modes[i].Count);
|
||||||
g_Config.backend_info.AAModes.push_back(buf);
|
g_Config.backend_info.AAModes.push_back(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Requires the earlydepthstencil attribute (only available in shader model 5)
|
||||||
|
g_Config.backend_info.bSupportsEarlyZ = (DX11::D3D::GetFeatureLevel(ad) == D3D_FEATURE_LEVEL_11_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description));
|
g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description));
|
||||||
|
|
|
@ -135,7 +135,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi)
|
||||||
if (z < 0 || z > 0x00ffffff)
|
if (z < 0 || z > 0x00ffffff)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bpmem.zcontrol.early_ztest && bpmem.zmode.testenable && g_SWVideoConfig.bZComploc)
|
if (bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc)
|
||||||
{
|
{
|
||||||
// TODO: Test if perf regs are incremented even if test is disabled
|
// TODO: Test if perf regs are incremented even if test is disabled
|
||||||
SWPixelEngine::pereg.IncZInputQuadCount(true);
|
SWPixelEngine::pereg.IncZInputQuadCount(true);
|
||||||
|
|
Loading…
Reference in New Issue