Skip to content

Commit

Permalink
Merge pull request #1716 from Armada651/geom-wireframe
Browse files Browse the repository at this point in the history
VideoCommon: Handle wireframe mode in the geometry shader.
  • Loading branch information
dolphin-emu-bot committed Dec 20, 2014
2 parents 6a785af + 531b394 commit a560d8f
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D/D3DState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 0 additions & 1 deletion Source/Core/VideoBackends/D3D/D3DState.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ namespace DX11
union RasterizerState
{
BitField<0, 2, D3D11_CULL_MODE> cull_mode;
BitField<2, 1, u32> wireframe;

u32 packed;
};
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/D3D/GeometryShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions Source/Core/VideoBackends/D3D/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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++)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 0 additions & 3 deletions Source/Core/VideoBackends/OGL/Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
54 changes: 33 additions & 21 deletions Source/Core/VideoCommon/GeometryShaderGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -27,7 +26,8 @@ static const char* primitives_d3d[] =
"triangle"
};

template<class T> static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType);
template<class T> static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex = false);
template<class T> static inline void EndPrimitive(T& out, API_TYPE ApiType);

template<class T>
static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType)
Expand All @@ -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)
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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<VertexData> 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<VertexData> 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<VertexData> output)\n{\n", primitives_d3d[primitive_type], vertex_in);
out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream<VertexData> output)\n{\n", primitives_d3d[primitive_type], vertex_in, g_ActiveConfig.bWireFrame ? "Line" : "Triangle");
}

out.Write("\tVertexData ps;\n");
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -221,7 +228,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
}
out.Write("\t}\n");

EmitVertex<T>(out, "l", ApiType);
EmitVertex<T>(out, "l", ApiType, true);
EmitVertex<T>(out, "r", ApiType);
}
else if (primitive_type == PRIMITIVE_POINTS)
Expand Down Expand Up @@ -249,22 +256,19 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
}
out.Write("\t}\n");

EmitVertex<T>(out, "ll", ApiType);
EmitVertex<T>(out, "ll", ApiType, true);
EmitVertex<T>(out, "lr", ApiType);
EmitVertex<T>(out, "ul", ApiType);
EmitVertex<T>(out, "ur", ApiType);
}
else
{
EmitVertex<T>(out, "f", ApiType);
EmitVertex<T>(out, "f", ApiType, true);
}

out.Write("\t}\n");

if (ApiType == API_OPENGL)
out.Write("\tEndPrimitive();\n");
else
out.Write("\toutput.RestartStrip();\n");
EndPrimitive<T>(out, ApiType);

if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing)
out.Write("\t}\n");
Expand All @@ -279,8 +283,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A
}

template<class T>
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);

Expand All @@ -291,6 +298,17 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType)
else
out.Write("\toutput.Append(ps);\n");
}
template<class T>
static inline void EndPrimitive(T& out, API_TYPE ApiType)
{
if (g_ActiveConfig.bWireFrame)
EmitVertex<T>(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)
{
Expand All @@ -301,9 +319,3 @@ void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE
{
GenerateGeometryShader<ShaderCode>(object, primitive_type, ApiType);
}

bool IsPassthroughGeometryShader(GeometryShaderUid& object)
{
geometry_shader_uid_data* uid_data = object.GetUidData<geometry_shader_uid_data>();
return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo;
}
4 changes: 3 additions & 1 deletion Source/Core/VideoCommon/GeometryShaderGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
#pragma once

#include "VideoCommon/ShaderGenCommon.h"
#include "VideoCommon/VertexManagerBase.h"
#include "VideoCommon/VideoCommon.h"

#pragma pack(1)

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()
Expand All @@ -25,4 +28,3 @@ typedef ShaderUid<geometry_shader_uid_data> 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);

0 comments on commit a560d8f

Please sign in to comment.