diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index 5a371396d2..22782cc41c 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -81,7 +81,6 @@ void InitBackendInfo() g_Config.backend_info.bSupportsOversizedViewports = false; g_Config.backend_info.bSupportsStereoscopy = true; g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsGSInstancing = false; IDXGIFactory* factory; IDXGIAdapter* ad; @@ -115,11 +114,17 @@ void InitBackendInfo() g_Config.backend_info.AAModes.push_back(samples); } + bool shader_model_5_supported = (DX11::D3D::GetFeatureLevel(ad) >= D3D_FEATURE_LEVEL_11_0); + // Requires the earlydepthstencil attribute (only available in shader model 5) g_Config.backend_info.bSupportsEarlyZ = shader_model_5_supported; + // Requires full UAV functionality (only available in shader model 5) g_Config.backend_info.bSupportsBBox = shader_model_5_supported; + + // Requires the instance attribute (only available in shader model 5) + g_Config.backend_info.bSupportsGSInstancing = shader_model_5_supported; } g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description)); ad->Release(); diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 3ebea24585..b75eddd87a 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -64,8 +64,16 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy } else // D3D { - out.Write("[maxvertexcount(6)]\n"); - out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + { + out.Write("[maxvertexcount(3)]\n[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output, in uint InstanceID : SV_GSInstanceID)\n{\n"); + } + else + { + out.Write("[maxvertexcount(6)]\n"); + out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); + } out.Write("\tGS_OUTPUT gs;\n"); } @@ -75,13 +83,19 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy // If the GPU supports invocation we don't need a for loop and can simply use the // invocation identifier to determine which layer we're rendering. if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\tint l = gl_InvocationID;\n"); + { + if (ApiType == API_OPENGL) + out.Write("\tint l = gl_InvocationID;\n"); + else + out.Write("\tint l = InstanceID;\n"); + } else out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); - out.Write("\t\tgs.layer = l;\n"); + // Select the output layer + out.Write("\t\tgs.layer = l;\n"); if (ApiType == API_OPENGL) out.Write("\t\tgl_Layer = l;\n"); @@ -118,7 +132,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (ApiType == API_OPENGL) out.Write("\tEndPrimitive();\n"); else - out.Write("\t\tOutput.RestartStrip();\n"); + out.Write("\tOutput.RestartStrip();\n"); if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n");