gsdx ogl: Used a basic flat interpolation for color interpolation (line & tri primitives)

Card that support gs:
remain only a gs to generate sprite from a line. Even dummy gs are costly for the GPU.

Card that don't support gs:
remove useless copy of color for line and triangle primitives

Note for dx: opengl 3.2 (maybe not gles) supports both flat interpolation
convention (GL_FIRST_VERTEX_CONVENTION or GL_LAST_VERTEX_CONVENTION).  It might
be possible to shuffle vertex index to put the last vertex in first position.

- buff[0] = head + 0;
- buff[1] = head + 1;
- buff[2] = head + 2;
+ buff[0] = head + 2;
+ buff[1] = head + 1;
+ buff[2] = head + 0;



git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5718 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-08-14 10:18:38 +00:00
parent 6673166cb5
commit b4084047be
7 changed files with 141 additions and 334 deletions

View File

@ -180,7 +180,7 @@ namespace GLLoader {
#ifndef ENABLE_GLES
if ( (major_gl < 3) || ( major_gl == 3 && minor_gl < 2 ) ) {
fprintf(stderr, "Geometry shaders are not supported. Required openGL3.2\n");
fprintf(stderr, "Geometry shaders are not supported. Required openGL 3.2\n");
found_geometry_shader = false;
}
#ifdef _LINUX

View File

@ -112,7 +112,7 @@ GSDeviceOGL::~GSDeviceOGL()
delete m_vb;
for (uint32 key = 0; key < VSSelector::size(); key++) m_shader->Delete(m_vs[key]);
for (uint32 key = 0; key < GSSelector::size(); key++) m_shader->Delete(m_gs[key]);
m_shader->Delete(m_gs);
for (auto it = m_ps.begin(); it != m_ps.end() ; it++) m_shader->Delete(it->second);
m_ps.clear();
@ -578,25 +578,19 @@ GLuint GSDeviceOGL::CompileVS(VSSelector sel)
std::string macro = format("#define VS_BPPZ %d\n", sel.bppz)
+ format("#define VS_LOGZ %d\n", sel.logz)
+ format("#define VS_TME %d\n", sel.tme)
+ format("#define VS_FST %d\n", sel.fst);
+ format("#define VS_FST %d\n", sel.fst)
;
return m_shader->Compile("tfx.glsl", "vs_main", GL_VERTEX_SHADER, tfx_glsl, macro);
}
/* Note: must be here because tfx_glsl is static */
GLuint GSDeviceOGL::CompileGS(GSSelector sel)
GLuint GSDeviceOGL::CompileGS()
{
// Easy case
if(! (sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)))
return 0;
std::string macro = format("#define GS_IIP %d\n", sel.iip)
+ format("#define GS_PRIM %d\n", sel.prim);
#ifdef ENABLE_GLES
return 0;
#else
return m_shader->Compile("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, tfx_glsl, macro);
return m_shader->Compile("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, tfx_glsl, "");
#endif
}
@ -620,7 +614,9 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
+ format("#define PS_DATE %d\n", sel.date)
+ format("#define PS_SPRITEHACK %d\n", sel.spritehack)
+ format("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler);
+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
+ format("#define PS_IIP %d\n", sel.iip)
;
return m_shader->Compile("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, tfx_glsl, macro);
}
@ -968,8 +964,7 @@ void GSDeviceOGL::PSSetShaderResource(GLuint sr)
GLState::tex_unit[0] = sr;
if (GLLoader::found_GL_ARB_multi_bind) {
GLuint textures[1] = {sr};
gl_BindTextures(0, 1, textures);
gl_BindTextures(0, 1, &sr);
} else {
gl_ActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sr);

View File

@ -326,27 +326,6 @@ class GSDeviceOGL : public GSDevice
}
};
struct GSSelector
{
union
{
struct
{
uint32 iip:1;
uint32 prim:2;
};
uint32 key;
};
operator uint32() {return key & 0x7;}
GSSelector() : key(0) {}
GSSelector(uint32 k) : key(k) {}
static uint32 size() { return 1 << 3; }
};
struct PSSelector
{
union
@ -371,12 +350,13 @@ class GSDeviceOGL : public GSDevice
uint32 spritehack:1;
uint32 tcoffsethack:1;
uint32 point_sampler:1;
uint32 iip:1;
};
uint32 key;
};
operator uint32() {return key & 0xfffffff;}
operator uint32() {return key & 0x1fffffff;}
PSSelector() : key(0) {}
};
@ -526,7 +506,7 @@ class GSDeviceOGL : public GSDevice
GSShaderOGL* m_shader;
GLuint m_vs[1<<5];
GLuint m_gs[1<<3];
GLuint m_gs;
GLuint m_ps_ss[1<<3];
GSDepthStencilOGL* m_om_dss[1<<6];
hash_map<uint32, GLuint > m_ps;
@ -617,7 +597,7 @@ class GSDeviceOGL : public GSDevice
void CreateTextureFX();
GLuint CompileVS(VSSelector sel);
GLuint CompileGS(GSSelector sel);
GLuint CompileGS();
GLuint CompilePS(PSSelector sel);
GLuint CreateSampler(bool bilinear, bool tau, bool tav);
GLuint CreateSampler(PSSamplerSelector sel);
@ -627,7 +607,7 @@ class GSDeviceOGL : public GSDevice
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
void SetupVS(VSSelector sel);
void SetupGS(GSSelector sel);
void SetupGS(bool enable);
void SetupPS(PSSelector sel);
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
void SetupSampler(PSSelector sel, PSSamplerSelector ssel);

View File

@ -53,101 +53,65 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
void GSRendererOGL::EmulateGS()
{
switch(m_vt.m_primclass)
if (m_vt.m_primclass != GS_SPRITE_CLASS) return;
// each sprite converted to quad needs twice the space
while(m_vertex.tail * 2 > m_vertex.maxcount)
{
case GS_LINE_CLASS:
GrowVertexBuffer();
}
if(PRIM->IIP == 0)
// assume vertices are tightly packed and sequentially indexed (it should be the case)
if(m_vertex.next >= 2)
{
size_t count = m_vertex.next;
int i = (int)count * 2 - 4;
GSVertex* s = &m_vertex.buff[count - 2];
GSVertex* q = &m_vertex.buff[count * 2 - 4];
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 2)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 1];
m_index.buff[i + 1] = tmp;
}
GSVertex v0 = s[0];
GSVertex v1 = s[1];
v0.RGBAQ = v1.RGBAQ;
v0.XYZ.Z = v1.XYZ.Z;
v0.FOG = v1.FOG;
q[0] = v0;
q[3] = v1;
// swap x, s, u
uint16 x = v0.XYZ.X;
v0.XYZ.X = v1.XYZ.X;
v1.XYZ.X = x;
float s = v0.ST.S;
v0.ST.S = v1.ST.S;
v1.ST.S = s;
uint16 u = v0.U;
v0.U = v1.U;
v1.U = u;
q[1] = v0;
q[2] = v1;
index[0] = i + 0;
index[1] = i + 1;
index[2] = i + 2;
index[3] = i + 1;
index[4] = i + 2;
index[5] = i + 3;
}
break;
case GS_TRIANGLE_CLASS:
if(PRIM->IIP == 0)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 3)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 2];
m_index.buff[i + 2] = tmp;
}
}
break;
case GS_SPRITE_CLASS:
// each sprite converted to quad needs twice the space
while(m_vertex.tail * 2 > m_vertex.maxcount)
{
GrowVertexBuffer();
}
// assume vertices are tightly packed and sequentially indexed (it should be the case)
if(m_vertex.next >= 2)
{
size_t count = m_vertex.next;
int i = (int)count * 2 - 4;
GSVertex* s = &m_vertex.buff[count - 2];
GSVertex* q = &m_vertex.buff[count * 2 - 4];
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
{
GSVertex v0 = s[0];
GSVertex v1 = s[1];
v0.RGBAQ = v1.RGBAQ;
v0.XYZ.Z = v1.XYZ.Z;
v0.FOG = v1.FOG;
q[0] = v0;
q[3] = v1;
// swap x, s, u
uint16 x = v0.XYZ.X;
v0.XYZ.X = v1.XYZ.X;
v1.XYZ.X = x;
float s = v0.ST.S;
v0.ST.S = v1.ST.S;
v1.ST.S = s;
uint16 u = v0.U;
v0.U = v1.U;
v1.U = u;
q[1] = v0;
q[2] = v1;
index[0] = i + 0;
index[1] = i + 1;
index[2] = i + 2;
index[3] = i + 1;
index[4] = i + 2;
index[5] = i + 3;
}
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
m_index.tail = count * 3;
}
break;
default:
__assume(0);
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
m_index.tail = count * 3;
}
}
@ -378,19 +342,15 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
vs_cb.Vertex_Scale_Offset = GSVector4(sx, sy, ox * sx + ox2 + 1, oy * sy + oy2 + 1);
// END of FIXME
// gs
GSDeviceOGL::GSSelector gs_sel;
gs_sel.iip = PRIM->IIP;
gs_sel.prim = m_vt.m_primclass;
// ps
GSDeviceOGL::PSSelector ps_sel;
GSDeviceOGL::PSSamplerSelector ps_ssel;
GSDeviceOGL::PSConstantBuffer ps_cb;
// GS_SPRITE_CLASS are already flat (either by CPU or the GS)
ps_sel.iip = (m_vt.m_primclass == GS_SPRITE_CLASS) ? 1 : PRIM->IIP;
if(DATE)
{
om_dssel.date = 1;
@ -504,7 +464,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// 2/ bindless texture uniform
// 3/ others uniform?
dev->SetupVS(vs_sel);
dev->SetupGS(gs_sel);
dev->SetupGS(m_vt.m_primclass == GS_SPRITE_CLASS);
dev->SetupPS(ps_sel);
// Note: bindless texture will use uniform so it must be done after the program setup

View File

@ -46,15 +46,9 @@ void GSDeviceOGL::CreateTextureFX()
};
m_vb = new GSVertexBufferStateOGL(sizeof(GSVertex), vert_format, countof(vert_format));
// Compile some dummy shaders to allow modification inside Apitrace for debug
CompileVS(VSSelector());
CompileGS(GSSelector());
CompilePS(PSSelector());
// Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution
for (uint32 key = 0; key < GSSelector::size(); key++)
m_gs[key] = CompileGS(GSSelector(key));
m_gs = CompileGS();
for (uint32 key = 0; key < VSSelector::size(); key++)
m_vs[key] = CompileVS(VSSelector(key));
@ -64,7 +58,6 @@ void GSDeviceOGL::CreateTextureFX()
for (uint32 key = 0; key < OMDepthStencilSelector::size(); key++)
m_om_dss[key] = CreateDepthStencil(OMDepthStencilSelector(key));
}
GLuint GSDeviceOGL::CreateSampler(PSSamplerSelector sel)
@ -152,11 +145,12 @@ void GSDeviceOGL::SetupVS(VSSelector sel)
m_shader->VS(vs);
}
void GSDeviceOGL::SetupGS(GSSelector sel)
void GSDeviceOGL::SetupGS(bool enable)
{
GLuint gs = m_gs[sel];
m_shader->GS(gs);
if (enable)
m_shader->GS(m_gs);
else
m_shader->GS(0);
}
void GSDeviceOGL::SetupPS(PSSelector sel)

View File

@ -528,11 +528,6 @@ static const char* tfx_glsl =
"#define VS_LOGZ 0\n"
"#endif\n"
"\n"
"#ifndef GS_IIP\n"
"#define GS_IIP 0\n"
"#define GS_PRIM 3\n"
"#endif\n"
"\n"
"#ifndef PS_FST\n"
"#define PS_FST 0\n"
"#define PS_WMS 0\n"
@ -552,13 +547,14 @@ static const char* tfx_glsl =
"#define PS_SPRITEHACK 0\n"
"#define PS_POINT_SAMPLER 0\n"
"#define PS_TCOFFSETHACK 0\n"
"#define PS_IIP 1\n"
"#endif\n"
"\n"
"struct vertex\n"
"{\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
" vec4 fc;\n"
"};\n"
"\n"
"#ifdef VERTEX_SHADER\n"
@ -575,28 +571,28 @@ static const char* tfx_glsl =
"out SHADER\n"
"{\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
" flat vec4 fc;\n"
"} VSout;\n"
"\n"
"#define VSout_t (VSout.t)\n"
"#define VSout_tp (VSout.tp)\n"
"#define VSout_c (VSout.c)\n"
"#define VSout_fc (VSout.fc)\n"
"\n"
"#else\n"
"\n"
"#ifdef DISABLE_SSO\n"
"out vec4 SHADERt;\n"
"out vec4 SHADERtp;\n"
"out vec4 SHADERc;\n"
"flat out vec4 SHADERfc;\n"
"#else\n"
"layout(location = 0) out vec4 SHADERt;\n"
"layout(location = 1) out vec4 SHADERtp;\n"
"layout(location = 2) out vec4 SHADERc;\n"
"layout(location = 1) out vec4 SHADERc;\n"
"flat layout(location = 2) out vec4 SHADERfc;\n"
"#endif\n"
"#define VSout_t SHADERt\n"
"#define VSout_tp SHADERtp\n"
"#define VSout_c SHADERc\n"
"#define VSout_fc SHADERfc\n"
"\n"
"#endif\n"
"\n"
@ -666,6 +662,7 @@ static const char* tfx_glsl =
" }\n"
"\n"
" VSout_c = i_c;\n"
" VSout_fc = i_c;\n"
" VSout_t.z = i_f.r;\n"
"}\n"
"\n"
@ -689,85 +686,26 @@ static const char* tfx_glsl =
"in SHADER\n"
"{\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
" flat vec4 fc;\n"
"} GSin[];\n"
"\n"
"out SHADER\n"
"{\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
" flat vec4 fc;\n"
"} GSout;\n"
"\n"
"void out_vertex(in vertex v)\n"
"{\n"
" GSout.t = v.t;\n"
" GSout.tp = v.tp;\n"
" GSout.c = v.c;\n"
" GSout.fc = v.fc;\n"
" gl_PrimitiveID = gl_PrimitiveIDIn;\n"
" EmitVertex();\n"
"}\n"
"\n"
"void out_vertex_elem(in vec4 t, in vec4 tp, in vec4 c)\n"
"{\n"
" GSout.t = t;\n"
" GSout.tp = tp;\n"
" GSout.c = c;\n"
" gl_PrimitiveID = gl_PrimitiveIDIn;\n"
" EmitVertex();\n"
"}\n"
"\n"
"#if GS_PRIM == 0\n"
"layout(points) in;\n"
"layout(points, max_vertices = 1) out;\n"
"\n"
"void gs_main()\n"
"{\n"
" for(int i = 0; i < gl_in.length(); i++) {\n"
" gl_Position = gl_in[i].gl_Position;\n"
" out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);\n"
" }\n"
" EndPrimitive();\n"
"}\n"
"\n"
"#elif GS_PRIM == 1\n"
"layout(lines) in;\n"
"layout(line_strip, max_vertices = 2) out;\n"
"\n"
"void gs_main()\n"
"{\n"
" for(int i = 0; i < gl_in.length(); i++) {\n"
" gl_Position = gl_in[i].gl_Position;\n"
"#if GS_IIP == 0\n"
" // use latest color\n"
" out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[1].c);\n"
"#else\n"
" out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);\n"
"#endif\n"
" }\n"
" EndPrimitive();\n"
"}\n"
"\n"
"#elif GS_PRIM == 2\n"
"layout(triangles) in;\n"
"layout(triangle_strip, max_vertices = 3) out;\n"
"\n"
"void gs_main()\n"
"{\n"
" for(int i = 0; i < gl_in.length(); i++) {\n"
" gl_Position = gl_in[i].gl_Position;\n"
"#if GS_IIP == 0\n"
" // use latest color\n"
" out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[2].c);\n"
"#else\n"
" out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);\n"
"#endif\n"
" }\n"
" EndPrimitive();\n"
"}\n"
"\n"
"#elif GS_PRIM == 3\n"
"layout(lines) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n"
"\n"
@ -775,23 +713,22 @@ static const char* tfx_glsl =
"{\n"
" // left top => GSin[0];\n"
" // right bottom => GSin[1];\n"
" vertex rb = vertex(GSin[1].t, GSin[1].tp, GSin[1].c);\n"
" vertex lt = vertex(GSin[0].t, GSin[0].tp, GSin[0].c);\n"
"#if 0\n"
" vertex rb = GSin[1];\n"
" vertex lt = GSin[0];\n"
"#endif\n"
" vertex rb = vertex(GSin[1].t, GSin[1].c, GSin[1].fc);\n"
" vertex lt = vertex(GSin[0].t, GSin[0].c, GSin[0].fc);\n"
"\n"
" vec4 rb_p = gl_in[1].gl_Position;\n"
" vec4 lb_p = gl_in[1].gl_Position;\n"
" vec4 rt_p = gl_in[1].gl_Position;\n"
" vec4 lt_p = gl_in[0].gl_Position;\n"
"\n"
" // flat depth\n"
" lt_p.z = rb_p.z;\n"
" // flat fog and texture perspective\n"
" lt.t.zw = rb.t.zw;\n"
"#if GS_IIP == 0\n"
" // flat color\n"
" lt.c = rb.c;\n"
"#endif\n"
"\n"
" // Swap texture and position coordinate\n"
" vertex lb = rb;\n"
" lb_p.x = lt_p.x;\n"
" lb.t.x = lt.t.x;\n"
@ -827,8 +764,6 @@ static const char* tfx_glsl =
"\n"
"#endif\n"
"\n"
"#endif\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"\n"
"#if !GL_ES && __VERSION__ > 140\n"
@ -836,28 +771,28 @@ static const char* tfx_glsl =
"in SHADER\n"
"{\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
" flat vec4 fc;\n"
"} PSin;\n"
"\n"
"#define PSin_t (PSin.t)\n"
"#define PSin_tp (PSin.tp)\n"
"#define PSin_c (PSin.c)\n"
"#define PSin_fc (PSin.fc)\n"
"\n"
"#else\n"
"\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERt;\n"
"in vec4 SHADERtp;\n"
"in vec4 SHADERc;\n"
"flat in vec4 SHADERfc;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERt;\n"
"layout(location = 1) in vec4 SHADERtp;\n"
"layout(location = 2) in vec4 SHADERc;\n"
"layout(location = 1) in vec4 SHADERc;\n"
"flat layout(location = 2) in vec4 SHADERfc;\n"
"#endif\n"
"#define PSin_t SHADERt\n"
"#define PSin_tp SHADERtp\n"
"#define PSin_c SHADERc\n"
"#define PSin_fc SHADERfc\n"
"\n"
"#endif\n"
"\n"
@ -1153,6 +1088,7 @@ static const char* tfx_glsl =
" return clamp(c_out, vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f));\n"
"}\n"
"\n"
"#if 0\n"
"void datst()\n"
"{\n"
"#if PS_DATE > 0\n"
@ -1165,6 +1101,7 @@ static const char* tfx_glsl =
" discard;\n"
"#endif\n"
"}\n"
"#endif\n"
"\n"
"// Note layout stuff might require gl4.3\n"
"#ifdef SUBROUTINE_GL40\n"
@ -1343,11 +1280,13 @@ static const char* tfx_glsl =
"\n"
"vec4 ps_color()\n"
"{\n"
" //datst();\n"
"\n"
" vec4 t = sample_color(PSin_t.xy, PSin_t.w);\n"
"\n"
"#if PS_IIP == 1\n"
" vec4 c = tfx(t, PSin_c);\n"
"#else\n"
" vec4 c = tfx(t, PSin_fc);\n"
"#endif\n"
"\n"
" atst(c);\n"
"\n"

View File

@ -18,11 +18,6 @@
#define VS_LOGZ 0
#endif
#ifndef GS_IIP
#define GS_IIP 0
#define GS_PRIM 3
#endif
#ifndef PS_FST
#define PS_FST 0
#define PS_WMS 0
@ -42,13 +37,14 @@
#define PS_SPRITEHACK 0
#define PS_POINT_SAMPLER 0
#define PS_TCOFFSETHACK 0
#define PS_IIP 1
#endif
struct vertex
{
vec4 t;
vec4 tp;
vec4 c;
vec4 fc;
};
#ifdef VERTEX_SHADER
@ -65,28 +61,28 @@ layout(location = 6) in vec4 i_f;
out SHADER
{
vec4 t;
vec4 tp;
vec4 c;
flat vec4 fc;
} VSout;
#define VSout_t (VSout.t)
#define VSout_tp (VSout.tp)
#define VSout_c (VSout.c)
#define VSout_fc (VSout.fc)
#else
#ifdef DISABLE_SSO
out vec4 SHADERt;
out vec4 SHADERtp;
out vec4 SHADERc;
flat out vec4 SHADERfc;
#else
layout(location = 0) out vec4 SHADERt;
layout(location = 1) out vec4 SHADERtp;
layout(location = 2) out vec4 SHADERc;
layout(location = 1) out vec4 SHADERc;
flat layout(location = 2) out vec4 SHADERfc;
#endif
#define VSout_t SHADERt
#define VSout_tp SHADERtp
#define VSout_c SHADERc
#define VSout_fc SHADERfc
#endif
@ -156,6 +152,7 @@ void vs_main()
}
VSout_c = i_c;
VSout_fc = i_c;
VSout_t.z = i_f.r;
}
@ -179,85 +176,26 @@ out gl_PerVertex {
in SHADER
{
vec4 t;
vec4 tp;
vec4 c;
flat vec4 fc;
} GSin[];
out SHADER
{
vec4 t;
vec4 tp;
vec4 c;
flat vec4 fc;
} GSout;
void out_vertex(in vertex v)
{
GSout.t = v.t;
GSout.tp = v.tp;
GSout.c = v.c;
GSout.fc = v.fc;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
void out_vertex_elem(in vec4 t, in vec4 tp, in vec4 c)
{
GSout.t = t;
GSout.tp = tp;
GSout.c = c;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
#if GS_PRIM == 0
layout(points) in;
layout(points, max_vertices = 1) out;
void gs_main()
{
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);
}
EndPrimitive();
}
#elif GS_PRIM == 1
layout(lines) in;
layout(line_strip, max_vertices = 2) out;
void gs_main()
{
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
#if GS_IIP == 0
// use latest color
out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[1].c);
#else
out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);
#endif
}
EndPrimitive();
}
#elif GS_PRIM == 2
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
void gs_main()
{
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = gl_in[i].gl_Position;
#if GS_IIP == 0
// use latest color
out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[2].c);
#else
out_vertex_elem(GSin[i].t, GSin[i].tp, GSin[i].c);
#endif
}
EndPrimitive();
}
#elif GS_PRIM == 3
layout(lines) in;
layout(triangle_strip, max_vertices = 6) out;
@ -265,23 +203,22 @@ void gs_main()
{
// left top => GSin[0];
// right bottom => GSin[1];
vertex rb = vertex(GSin[1].t, GSin[1].tp, GSin[1].c);
vertex lt = vertex(GSin[0].t, GSin[0].tp, GSin[0].c);
#if 0
vertex rb = GSin[1];
vertex lt = GSin[0];
#endif
vertex rb = vertex(GSin[1].t, GSin[1].c, GSin[1].fc);
vertex lt = vertex(GSin[0].t, GSin[0].c, GSin[0].fc);
vec4 rb_p = gl_in[1].gl_Position;
vec4 lb_p = gl_in[1].gl_Position;
vec4 rt_p = gl_in[1].gl_Position;
vec4 lt_p = gl_in[0].gl_Position;
// flat depth
lt_p.z = rb_p.z;
// flat fog and texture perspective
lt.t.zw = rb.t.zw;
#if GS_IIP == 0
// flat color
lt.c = rb.c;
#endif
// Swap texture and position coordinate
vertex lb = rb;
lb_p.x = lt_p.x;
lb.t.x = lt.t.x;
@ -317,8 +254,6 @@ void gs_main()
#endif
#endif
#ifdef FRAGMENT_SHADER
#if !GL_ES && __VERSION__ > 140
@ -326,28 +261,28 @@ void gs_main()
in SHADER
{
vec4 t;
vec4 tp;
vec4 c;
flat vec4 fc;
} PSin;
#define PSin_t (PSin.t)
#define PSin_tp (PSin.tp)
#define PSin_c (PSin.c)
#define PSin_fc (PSin.fc)
#else
#ifdef DISABLE_SSO
in vec4 SHADERt;
in vec4 SHADERtp;
in vec4 SHADERc;
flat in vec4 SHADERfc;
#else
layout(location = 0) in vec4 SHADERt;
layout(location = 1) in vec4 SHADERtp;
layout(location = 2) in vec4 SHADERc;
layout(location = 1) in vec4 SHADERc;
flat layout(location = 2) in vec4 SHADERfc;
#endif
#define PSin_t SHADERt
#define PSin_tp SHADERtp
#define PSin_c SHADERc
#define PSin_fc SHADERfc
#endif
@ -643,6 +578,7 @@ vec4 tfx(vec4 t, vec4 c)
return clamp(c_out, vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f));
}
#if 0
void datst()
{
#if PS_DATE > 0
@ -655,6 +591,7 @@ void datst()
discard;
#endif
}
#endif
// Note layout stuff might require gl4.3
#ifdef SUBROUTINE_GL40
@ -833,11 +770,13 @@ void fog(vec4 c, float f)
vec4 ps_color()
{
//datst();
vec4 t = sample_color(PSin_t.xy, PSin_t.w);
#if PS_IIP == 1
vec4 c = tfx(t, PSin_c);
#else
vec4 c = tfx(t, PSin_fc);
#endif
atst(c);