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

VideoCommon: Handle wireframe mode in the geometry shader. #1716

Merged
merged 4 commits into from
Dec 20, 2014
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1800,9 +1800,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);

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

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);