diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index d4d98e35b8..1f219fa2e2 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -407,7 +407,7 @@ ID3D11RasterizerState* StateCache::Get(RasterizerState state) if (it != m_raster.end()) return it->second; - D3D11_RASTERIZER_DESC rastdc = CD3D11_RASTERIZER_DESC(state.wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID, + D3D11_RASTERIZER_DESC rastdc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, state.cull_mode, false, 0, 0.f, 0, true, true, false, false); diff --git a/Source/Core/VideoBackends/D3D/D3DState.h b/Source/Core/VideoBackends/D3D/D3DState.h index 2910eb9358..a2bb4e61c9 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.h +++ b/Source/Core/VideoBackends/D3D/D3DState.h @@ -22,7 +22,6 @@ namespace DX11 union RasterizerState { BitField<0, 2, D3D11_CULL_MODE> cull_mode; - BitField<2, 1, u32> wireframe; u32 packed; }; diff --git a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp index 9a9da67b63..59b0e3ff65 100644 --- a/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp @@ -211,7 +211,7 @@ bool GeometryShaderCache::SetShader(u32 primitive_type) last_uid = uid; // Check if the shader is a pass-through shader - if (IsPassthroughGeometryShader(uid)) + if (uid.GetUidData()->IsPassthrough()) { // Return the default pass-through shader last_entry = &pass_entry; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 95fa5e1e57..9609fbf722 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -255,7 +255,6 @@ Renderer::Renderer(void *&window_handle) gx_state.zmode.func = ZMode::NEVER; gx_state.raster.cull_mode = D3D11_CULL_NONE; - gx_state.raster.wireframe = false; // Clear EFB textures float ClearColor[4] = { 0.f, 0.f, 0.f, 1.f }; @@ -1084,10 +1083,7 @@ void Renderer::ApplyState(bool bUseDstAlpha) { gx_state.blend.use_dst_alpha = bUseDstAlpha; D3D::stateman->PushBlendState(gx_state_cache.Get(gx_state.blend)); - D3D::stateman->PushDepthState(gx_state_cache.Get(gx_state.zmode)); - - gx_state.raster.wireframe = g_ActiveConfig.bWireFrame; D3D::stateman->PushRasterizerState(gx_state_cache.Get(gx_state.raster)); for (unsigned int stage = 0; stage < 8; stage++) diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 14f5f94c82..01c1d43035 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -211,7 +211,7 @@ SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components ShaderCode gcode; GenerateVertexShaderCode(vcode, components, API_OPENGL); GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); - if (g_ActiveConfig.backend_info.bSupportsGeometryShaders && !IsPassthroughGeometryShader(uid.guid)) + if (g_ActiveConfig.backend_info.bSupportsGeometryShaders && !uid.guid.GetUidData()->IsPassthrough()) GenerateGeometryShaderCode(gcode, primitive_type, API_OPENGL); if (g_ActiveConfig.bEnableShaderDebugging) diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 42af2521d9..aa5275b3f9 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1790,9 +1790,6 @@ void Renderer::RestoreAPIState() SetLogicOpMode(); SetViewport(); - if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) - glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL); - VertexManager *vm = (OGL::VertexManager*)g_vertex_manager; glBindBuffer(GL_ARRAY_BUFFER, vm->m_vertex_buffers); if (vm->m_last_vao) diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index f2b102038e..7e8fa080e2 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -7,7 +7,6 @@ #include "VideoCommon/BPMemory.h" #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" -#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VideoConfig.h" @@ -27,7 +26,8 @@ static const char* primitives_d3d[] = "triangle" }; -template static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType); +template static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex = false); +template static inline void EndPrimitive(T& out, API_TYPE ApiType); template static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) @@ -46,7 +46,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A uid_data->primitive_type = primitive_type; const unsigned int vertex_in = primitive_type + 1; - const unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; + unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; + + uid_data->wireframe = g_ActiveConfig.bWireFrame; + if (g_ActiveConfig.bWireFrame) + vertex_out++; uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) @@ -55,12 +59,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("layout(%s, invocations = %d) in;\n", primitives_ogl[primitive_type], g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("layout(triangle_strip, max_vertices = %d) out;\n", vertex_out); + out.Write("layout(%s_strip, max_vertices = %d) out;\n", g_ActiveConfig.bWireFrame ? "line" : "triangle", vertex_out); } else { out.Write("layout(%s) in;\n", primitives_ogl[primitive_type]); - out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); + out.Write("layout(%s_strip, max_vertices = %d) out;\n", g_ActiveConfig.bWireFrame ? "line" : "triangle", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); } } @@ -114,12 +118,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("[maxvertexcount(%d)]\n[instance(%d)]\n", vertex_out, g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in, g_ActiveConfig.bWireFrame ? "Line" : "Triangle"); } else { out.Write("[maxvertexcount(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream output)\n{\n", primitives_d3d[primitive_type], vertex_in, g_ActiveConfig.bWireFrame ? "Line" : "Triangle"); } out.Write("\tVertexData ps;\n"); @@ -178,6 +182,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tfor (int eye = 0; eye < 2; ++eye) {\n"); } + if (g_ActiveConfig.bWireFrame) + out.Write("\tVS_OUTPUT first;\n"); + out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); if (ApiType == API_OPENGL) @@ -221,7 +228,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } out.Write("\t}\n"); - EmitVertex(out, "l", ApiType); + EmitVertex(out, "l", ApiType, true); EmitVertex(out, "r", ApiType); } else if (primitive_type == PRIMITIVE_POINTS) @@ -249,22 +256,19 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } out.Write("\t}\n"); - EmitVertex(out, "ll", ApiType); + EmitVertex(out, "ll", ApiType, true); EmitVertex(out, "lr", ApiType); EmitVertex(out, "ul", ApiType); EmitVertex(out, "ur", ApiType); } else { - EmitVertex(out, "f", ApiType); + EmitVertex(out, "f", ApiType, true); } out.Write("\t}\n"); - if (ApiType == API_OPENGL) - out.Write("\tEndPrimitive();\n"); - else - out.Write("\toutput.RestartStrip();\n"); + EndPrimitive(out, ApiType); if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); @@ -279,8 +283,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } template -static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) +static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex) { + if (g_ActiveConfig.bWireFrame && first_vertex) + out.Write("\tif (i == 0) first = %s;\n", vertex); + if (ApiType == API_OPENGL) out.Write("\tgl_Position = %s.pos;\n", vertex); @@ -291,6 +298,17 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) else out.Write("\toutput.Append(ps);\n"); } +template +static inline void EndPrimitive(T& out, API_TYPE ApiType) +{ + if (g_ActiveConfig.bWireFrame) + EmitVertex(out, "first", ApiType); + + if (ApiType == API_OPENGL) + out.Write("\tEndPrimitive();\n"); + else + out.Write("\toutput.RestartStrip();\n"); +} void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType) { @@ -301,9 +319,3 @@ void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE { GenerateGeometryShader(object, primitive_type, ApiType); } - -bool IsPassthroughGeometryShader(GeometryShaderUid& object) -{ - geometry_shader_uid_data* uid_data = object.GetUidData(); - return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo; -} diff --git a/Source/Core/VideoCommon/GeometryShaderGen.h b/Source/Core/VideoCommon/GeometryShaderGen.h index 0f66f7a4f9..e0d4db7540 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.h +++ b/Source/Core/VideoCommon/GeometryShaderGen.h @@ -5,6 +5,7 @@ #pragma once #include "VideoCommon/ShaderGenCommon.h" +#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoCommon.h" #pragma pack(1) @@ -12,11 +13,13 @@ struct geometry_shader_uid_data { u32 NumValues() const { return sizeof(geometry_shader_uid_data); } + bool IsPassthrough() const { return primitive_type == PRIMITIVE_TRIANGLES && !stereo && !wireframe; } u32 stereo : 1; u32 numTexGens : 4; u32 pixel_lighting : 1; u32 primitive_type : 2; + u32 wireframe : 1; }; #pragma pack() @@ -25,4 +28,3 @@ typedef ShaderUid GeometryShaderUid; void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE ApiType); void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType); -bool IsPassthroughGeometryShader(GeometryShaderUid& object);