gsdx ogl: load shader from C code instead of an external file

* add a perl script to convert shader to char*
* By default use *.glsl file (handy to do some trials). 

Only drawback, glsl2h need to be manually called at the moment



git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5632 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-05-18 09:17:30 +00:00
parent 6760ed552b
commit e3d658b501
9 changed files with 1246 additions and 28 deletions

61
linux_various/glsl2h.pl Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/perl
use strict;
use warnings;
my @res = qw/convert interlace merge shadeboost tfx/;
my $path = "plugins/GSdx/res";
foreach my $r (@res) {
glsl2h($path, $r);
}
sub glsl2h {
my $path = shift;
my $glsl = shift;
open(my $GLSL, "<$path/${glsl}.glsl");
open(my $H, ">$path/${glsl}.h");
my $header = <<EOS;
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* ${glsl}_glsl =
EOS
print $H $header;
my $line;
while(defined($line = <$GLSL>)) {
chomp $line;
$line =~ s/%/\\%/g;
$line =~ s/"/\\"/g;
print $H "\t\"$line\\n\"\n";
}
print $H "\t;\n";
}

View File

@ -21,6 +21,11 @@
#include "GSDeviceOGL.h"
#include "res/convert.h"
#include "res/interlace.h"
#include "res/merge.h"
#include "res/shadeboost.h"
// TODO performance cost to investigate
// Texture attachment/glDrawBuffer. For the moment it set every draw and potentially multiple time (first time in clear, second time in rendering)
// Attachment 1 is only used with the GL_16UI format
@ -258,10 +263,10 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// ****************************************************************
// convert
// ****************************************************************
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs);
CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs);
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs, convert_glsl);
CompileShaderFromSource("convert.glsl", "gs_main", GL_GEOMETRY_SHADER, &m_convert.gs, convert_glsl);
for(uint i = 0; i < countof(m_convert.ps); i++)
CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i]);
CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i], convert_glsl);
// Note the following object are initialized to 0 so disabled.
// Note: maybe enable blend with a factor of 1
@ -321,7 +326,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_merge_obj.cb = new GSUniformBufferOGL(g_merge_cb_index, sizeof(MergeConstantBuffer));
for(uint i = 0; i < countof(m_merge_obj.ps); i++)
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i]);
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge_obj.ps[i], merge_glsl);
m_merge_obj.bs = new GSBlendStateOGL();
m_merge_obj.bs->EnableBlend();
@ -333,7 +338,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_interlace.cb = new GSUniformBufferOGL(g_interlace_cb_index, sizeof(InterlaceConstantBuffer));
for(uint i = 0; i < countof(m_interlace.ps); i++)
CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i]);
CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i], interlace_glsl);
// ****************************************************************
// Shade boost
// ****************************************************************
@ -346,7 +351,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
+ format("#define SB_BRIGHTNESS %d\n", ShadeBoost_Brightness)
+ format("#define SB_CONTRAST %d\n", ShadeBoost_Contrast);
CompileShaderFromSource("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, &m_shadeboost.ps, macro);
CompileShaderFromSource("shadeboost.glsl", "ps_main", GL_FRAGMENT_SHADER, &m_shadeboost.ps, shadeboost_glsl, macro);
// ****************************************************************
// rasterization configuration
@ -379,7 +384,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
// FIXME need to manually set the index...
// FIXME need dofxaa interface too
// m_fxaa.cb = new GSUniformBufferOGL(g_fxaa_cb_index, sizeof(FXAAConstantBuffer));
//CompileShaderFromSource("fxaa.fx", format("ps_main", i), GL_FRAGMENT_SHADER, &m_fxaa.ps);
//CompileShaderFromSource("fxaa.fx", format("ps_main", i), GL_FRAGMENT_SHADER, &m_fxaa.ps, fxaa_glsl);
// ****************************************************************
// date
@ -548,10 +553,7 @@ void GSDeviceOGL::Flip()
#ifdef PRINT_FRAME_NUMBER
fprintf(stderr, "Draw %d (Frame %d)\n", g_draw_count, g_frame_count);
#endif
#ifdef OGL_DEBUG
if (theApp.GetConfig("debug_ogl_dump", 0) != 0)
g_frame_count++;
g_frame_count++;
#endif
}
@ -707,6 +709,8 @@ void GSDeviceOGL::AfterDraw()
{
#ifdef OGL_DEBUG
DebugOutput();
#endif
#if defined(OGL_DEBUG) || defined(PRINT_FRAME_NUMBER)
g_draw_count++;
#endif
}
@ -1343,7 +1347,7 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
}
}
void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const std::string& macro_sel)
void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const char* glsl_h_code, const std::string& macro_sel)
{
// *****************************************************
// Build a header string
@ -1399,6 +1403,7 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
const std::string shader_file = string("plugins/") + glsl_file;
#endif
std::ifstream myfile(shader_file.c_str());
bool failed_to_open_glsl = true;
if (myfile.is_open()) {
while ( myfile.good() )
{
@ -1407,26 +1412,29 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
source += '\n';
}
myfile.close();
} else {
fprintf(stderr, "Error opening %s: ", shader_file.c_str());
*program = 0;
return;
failed_to_open_glsl = false;
}
// Note it is better to separate header and source file to have the good line number
// in the glsl compiler report
const char** sources_array = (const char**)malloc(2*sizeof(char*));
char* source_str = (char*)malloc(source.size() + 1);
char* header_str = (char*)malloc(header.size() + 1);
sources_array[0] = header_str;
sources_array[1] = source_str;
source.copy(source_str, source.size(), 0);
source_str[source.size()] = '\0';
header.copy(header_str, header.size(), 0);
header_str[header.size()] = '\0';
char* source_str = (char*)malloc(source.size() + 1);
if (failed_to_open_glsl) {
sources_array[1] = glsl_h_code;
} else {
sources_array[1] = source_str;
source.copy(source_str, source.size(), 0);
source_str[source.size()] = '\0';
}
#ifndef DISABLE_GL41_SSO
#if 0
// Could be useful one day

View File

@ -623,7 +623,7 @@ class GSDeviceOGL : public GSDevice
GSTexture* Resolve(GSTexture* t);
void CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const std::string& macro_sel = "");
void CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program, const char* glsl_h_code, const std::string& macro_sel = "");
void EndScene();

View File

@ -23,6 +23,8 @@
#include "GSDeviceOGL.h"
#include "GSTables.h"
#include "res/tfx.h"
static const uint32 g_vs_cb_index = 20;
static const uint32 g_ps_cb_index = 21;
@ -66,9 +68,9 @@ void GSDeviceOGL::CreateTextureFX()
// Compile some dummy shaders to allow modification inside Apitrace for debug
GLuint dummy;
std::string macro = "";
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &dummy, macro);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &dummy, macro);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &dummy, macro);
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &dummy, tfx_glsl, macro);
}
void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
@ -87,7 +89,7 @@ void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
+ format("#define VS_RTCOPY %d\n", sel.rtcopy);
GLuint vs;
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &vs, macro);
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &vs, tfx_glsl, macro);
m_vs[sel] = vs;
i = m_vs.find(sel);
@ -118,7 +120,7 @@ void GSDeviceOGL::SetupGS(GSSelector sel)
std::string macro = format("#define GS_IIP %d\n", sel.iip)
+ format("#define GS_PRIM %d\n", sel.prim);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &gs, macro);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &gs, tfx_glsl, macro);
m_gs[sel] = gs;
} else {
@ -160,7 +162,7 @@ void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerS
+ format("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &ps, macro);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &ps, tfx_glsl, macro);
m_ps[sel] = ps;
i = m_ps.find(sel);

196
plugins/GSdx/res/convert.h Normal file
View File

@ -0,0 +1,196 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* convert_glsl =
"//#version 420 // Keep it for editor detection\n"
"\n"
"struct vertex_basic\n"
"{\n"
" vec4 p;\n"
" vec2 t;\n"
"};\n"
"\n"
"\n"
"#ifdef VERTEX_SHADER\n"
"\n"
"out gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"\n"
"layout(location = 0) in vec4 POSITION;\n"
"layout(location = 1) in vec2 TEXCOORD0;\n"
"\n"
"// FIXME set the interpolation (don't know what dx do)\n"
"// flat means that there is no interpolation. The value given to the fragment shader is based on the provoking vertex conventions.\n"
"//\n"
"// noperspective means that there will be linear interpolation in window-space. This is usually not what you want, but it can have its uses.\n"
"//\n"
"// smooth, the default, means to do perspective-correct interpolation.\n"
"//\n"
"// The centroid qualifier only matters when multisampling. If this qualifier is not present, then the value is interpolated to the pixel's center, anywhere in the pixel, or to one of the pixel's samples. This sample may lie outside of the actual primitive being rendered, since a primitive can cover only part of a pixel's area. The centroid qualifier is used to prevent this; the interpolation point must fall within both the pixel's area and the primitive's area.\n"
"layout(location = 0) out vertex_basic VSout;\n"
"\n"
"void vs_main()\n"
"{\n"
" VSout.p = POSITION;\n"
" VSout.t = TEXCOORD0;\n"
" gl_Position = POSITION; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position\n"
"}\n"
"\n"
"#endif\n"
"\n"
"#ifdef GEOMETRY_SHADER\n"
"in gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"} gl_in[];\n"
"\n"
"out gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"\n"
"// FIXME\n"
"// AMD Driver bug again !!!!\n"
"//layout(location = 0) in vertex GSin[];\n"
"in vertex_basic GSin[];\n"
"\n"
"layout(location = 0) out vertex_basic GSout;\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"
" GSout = GSin[i];\n"
" EmitVertex();\n"
" }\n"
" EndPrimitive();\n"
"}\n"
"#endif\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"// NOTE: pixel can be clip with \"discard\"\n"
"\n"
"layout(location = 0) in vertex_basic PSin;\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"layout(location = 1) out uint SV_Target1;\n"
"\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"\n"
"vec4 sample_c()\n"
"{\n"
" return texture(TextureSampler, PSin.t );\n"
"}\n"
"\n"
"vec4 ps_crt(uint i)\n"
"{\n"
" vec4 mask[4] =\n"
" {\n"
" vec4(1, 0, 0, 0),\n"
" vec4(0, 1, 0, 0),\n"
" vec4(0, 0, 1, 0),\n"
" vec4(1, 1, 1, 0)\n"
" };\n"
"\n"
" return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);\n"
"}\n"
"\n"
"void ps_main0()\n"
"{\n"
" SV_Target0 = sample_c();\n"
"}\n"
"\n"
"void ps_main1()\n"
"{\n"
" vec4 c = sample_c();\n"
"\n"
" c.a *= 256.0f / 127.0f; // hm, 0.5 won't give us 1.0 if we just multiply with 2\n"
"\n"
" highp uvec4 i = uvec4(c * vec4(uint(0x001f), uint(0x03e0), uint(0x7c00), uint(0x8000)));\n"
"\n"
" SV_Target1 = (i.x & uint(0x001f)) | (i.y & uint(0x03e0)) | (i.z & uint(0x7c00)) | (i.w & uint(0x8000));\n"
"}\n"
"\n"
"void ps_main7()\n"
"{\n"
" vec4 c = sample_c();\n"
"\n"
" c.a = dot(c.rgb, vec3(0.299, 0.587, 0.114));\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main5() // triangular\n"
"{\n"
" highp uvec4 p = uvec4(PSin.p);\n"
"\n"
" vec4 c = ps_crt(((p.x + ((p.y >> 1u) & 1u) * 3u) >> 1u) \% 3u);\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main6() // diagonal\n"
"{\n"
" uvec4 p = uvec4(PSin.p);\n"
"\n"
" vec4 c = ps_crt((p.x + (p.y \% 3u)) \% 3u);\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main2()\n"
"{\n"
" if((sample_c().a - 128.0f / 255) < 0) // >= 0x80 pass\n"
" discard;\n"
"\n"
" SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
"}\n"
"void ps_main3()\n"
"{\n"
" if((127.95f / 255 - sample_c().a) <0) // < 0x80 pass (== 0x80 should not pass)\n"
" discard;\n"
"\n"
" SV_Target0 = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
"}\n"
"void ps_main4()\n"
"{\n"
" // FIXME mod and fmod are different when value are negative\n"
" // output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255;\n"
" vec4 c = mod(sample_c() * 255 + 0.5f, 256) / 255;\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"#endif\n"
;

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* interlace_glsl =
"//#version 420 // Keep it for editor detection\n"
"\n"
"struct vertex_basic\n"
"{\n"
" vec4 p;\n"
" vec2 t;\n"
"};\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"layout(location = 0) in vertex_basic PSin;\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb11\n"
"#else\n"
"layout(std140, binding = 11) uniform cb11\n"
"#endif\n"
"{\n"
" vec2 ZrH;\n"
" float hH;\n"
"};\n"
"\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"\n"
"// TODO ensure that clip (discard) is < 0 and not <= 0 ???\n"
"void ps_main0()\n"
"{\n"
" // I'm not sure it impact us but be safe to lookup texture before conditional if\n"
" // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control\n"
" vec4 c = texture(TextureSampler, PSin.t);\n"
" if (fract(PSin.t.y * hH) - 0.5 < 0.0)\n"
" discard;\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main1()\n"
"{\n"
" // I'm not sure it impact us but be safe to lookup texture before conditional if\n"
" // see: http://www.opengl.org/wiki/GLSL_Sampler#Non-uniform_flow_control\n"
" vec4 c = texture(TextureSampler, PSin.t);\n"
" if (0.5 - fract(PSin.t.y * hH) < 0.0)\n"
" discard;\n"
"\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main2()\n"
"{\n"
" vec4 c0 = texture(TextureSampler, PSin.t - ZrH);\n"
" vec4 c1 = texture(TextureSampler, PSin.t);\n"
" vec4 c2 = texture(TextureSampler, PSin.t + ZrH);\n"
"\n"
" SV_Target0 = (c0 + c1 * 2 + c2) / 4;\n"
"}\n"
"\n"
"void ps_main3()\n"
"{\n"
" SV_Target0 = texture(TextureSampler, PSin.t);\n"
"}\n"
"\n"
"#endif\n"
;

68
plugins/GSdx/res/merge.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* merge_glsl =
"//#version 420 // Keep it for editor detection\n"
"\n"
"struct vertex_basic\n"
"{\n"
" vec4 p;\n"
" vec2 t;\n"
"};\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"layout(location = 0) in vertex_basic PSin;\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb10\n"
"#else\n"
"layout(std140, binding = 10) uniform cb10\n"
"#endif\n"
"{\n"
" vec4 BGColor;\n"
"};\n"
"\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"\n"
"void ps_main0()\n"
"{\n"
" vec4 c = texture(TextureSampler, PSin.t);\n"
" c.a = min(c.a * 2, 1.0);\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"void ps_main1()\n"
"{\n"
" vec4 c = texture(TextureSampler, PSin.t);\n"
" c.a = BGColor.a;\n"
" SV_Target0 = c;\n"
"}\n"
"\n"
"#endif\n"
;

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* shadeboost_glsl =
"//#version 420 // Keep it for editor detection\n"
"\n"
"/*\n"
"** Contrast, saturation, brightness\n"
"** Code of this function is from TGM's shader pack\n"
"** http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=21057\n"
"*/\n"
"\n"
"struct vertex_basic\n"
"{\n"
" vec4 p;\n"
" vec2 t;\n"
"};\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"\n"
"layout(location = 0) in vertex_basic PSin;\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb12\n"
"#else\n"
"layout(std140, binding = 12) uniform cb12\n"
"#endif\n"
"{\n"
" vec4 BGColor;\n"
"};\n"
"\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"\n"
"// For all settings: 1.0 = 100\% 0.5=50\% 1.5 = 150\% \n"
"vec4 ContrastSaturationBrightness(vec4 color)\n"
"{\n"
" const float sat = SB_SATURATION / 50.0;\n"
" const float brt = SB_BRIGHTNESS / 50.0;\n"
" const float con = SB_CONTRAST / 50.0;\n"
" \n"
" // Increase or decrease theese values to adjust r, g and b color channels seperately\n"
" const float AvgLumR = 0.5;\n"
" const float AvgLumG = 0.5;\n"
" const float AvgLumB = 0.5;\n"
" \n"
" const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);\n"
" \n"
" vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);\n"
" vec3 brtColor = color.rgb * brt;\n"
" float dot_intensity = dot(brtColor, LumCoeff);\n"
" vec3 intensity = vec3(dot_intensity, dot_intensity, dot_intensity);\n"
" vec3 satColor = mix(intensity, brtColor, sat);\n"
" vec3 conColor = mix(AvgLumin, satColor, con);\n"
"\n"
" color.rgb = conColor; \n"
" return color;\n"
"}\n"
"\n"
"\n"
"void ps_main()\n"
"{\n"
" vec4 c = texture(TextureSampler, PSin.t);\n"
" SV_Target0 = ContrastSaturationBrightness(c);\n"
"}\n"
"\n"
"\n"
"#endif\n"
;

697
plugins/GSdx/res/tfx.h Normal file
View File

@ -0,0 +1,697 @@
/*
* Copyright (C) 2011-2013 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This file was generated by glsl2h.pl script
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#pragma once
#include "stdafx.h"
extern const char* tfx_glsl =
"//#version 420 // Keep it for text editor detection\n"
"\n"
"// note lerp => mix\n"
"\n"
"#define FMT_32 0\n"
"#define FMT_24 1\n"
"#define FMT_16 2\n"
"#define FMT_PAL 4 /* flag bit */\n"
"\n"
"// Not sure we have same issue on opengl. Doesn't work anyway on ATI card\n"
"// And I say this as an ATI user.\n"
"#define ATI_SUCKS 0\n"
"\n"
"#ifndef VS_BPPZ\n"
"#define VS_BPPZ 0\n"
"#define VS_TME 1\n"
"#define VS_FST 1\n"
"#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"
"#define PS_WMT 0\n"
"#define PS_FMT FMT_32\n"
"#define PS_AEM 0\n"
"#define PS_TFX 0\n"
"#define PS_TCC 1\n"
"#define PS_ATST 1\n"
"#define PS_FOG 0\n"
"#define PS_CLR1 0\n"
"#define PS_FBA 0\n"
"#define PS_AOUT 0\n"
"#define PS_LTF 1\n"
"#define PS_COLCLIP 0\n"
"#define PS_DATE 0\n"
"#define PS_SPRITEHACK 0\n"
"#define PS_POINT_SAMPLER 0\n"
"#define PS_TCOFFSETHACK 0\n"
"#endif\n"
"\n"
"struct vertex\n"
"{\n"
" vec4 p;\n"
" vec4 t;\n"
" vec4 tp;\n"
" vec4 c;\n"
"};\n"
"\n"
"#ifdef VERTEX_SHADER\n"
"layout(location = 0) in vec2 i_st;\n"
"layout(location = 1) in vec4 i_c;\n"
"layout(location = 2) in float i_q;\n"
"layout(location = 3) in uvec2 i_p;\n"
"layout(location = 4) in uint i_z;\n"
"layout(location = 5) in uvec2 i_uv;\n"
"layout(location = 6) in vec4 i_f;\n"
"\n"
"layout(location = 0) out vertex VSout;\n"
"\n"
"out gl_PerVertex {\n"
" invariant vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb20\n"
"#else\n"
"layout(std140, binding = 20) uniform cb20\n"
"#endif\n"
"{\n"
" vec4 VertexScale;\n"
" vec4 VertexOffset;\n"
" vec2 TextureScale;\n"
"};\n"
"\n"
"void vs_main()\n"
"{\n"
" uint z;\n"
" if(VS_BPPZ == 1) // 24\n"
" z = i_z & uint(0xffffff);\n"
" else if(VS_BPPZ == 2) // 16\n"
" z = i_z & uint(0xffff);\n"
" else\n"
" z = i_z;\n"
"\n"
" // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go)\n"
" // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty\n"
" // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel\n"
" // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133\n"
"\n"
" vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0); \n"
" vec4 final_p = p * VertexScale - VertexOffset;\n"
" // FIXME\n"
" // FLIP vertically\n"
" final_p.y *= -1.0f;\n"
"\n"
" if(VS_LOGZ == 1)\n"
" {\n"
" final_p.z = log2(1.0f + float(z)) / 32.0f;\n"
" }\n"
"\n"
" VSout.p = final_p;\n"
" gl_Position = final_p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position\n"
"#if VS_RTCOPY\n"
" VSout.tp = final_p * vec4(0.5, -0.5, 0, 0) + 0.5;\n"
"#endif\n"
"\n"
"\n"
" if(VS_TME != 0)\n"
" {\n"
" if(VS_FST != 0)\n"
" {\n"
" //VSout.t.xy = i_t * TextureScale;\n"
" VSout.t.xy = i_uv * TextureScale;\n"
" VSout.t.w = 1.0f;\n"
" }\n"
" else\n"
" {\n"
" //VSout.t.xy = i_t;\n"
" VSout.t.xy = i_st;\n"
" VSout.t.w = i_q;\n"
" }\n"
" }\n"
" else\n"
" {\n"
" VSout.t.xy = vec2(0.0f, 0.0f);\n"
" VSout.t.w = 1.0f;\n"
" }\n"
"\n"
" VSout.c = i_c;\n"
" VSout.t.z = i_f.r;\n"
"}\n"
"\n"
"#endif\n"
"\n"
"#ifdef GEOMETRY_SHADER\n"
"in gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"} gl_in[];\n"
"\n"
"out gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"\n"
"layout(location = 0) in vertex GSin[];\n"
"\n"
"layout(location = 0) out vertex GSout;\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; // FIXME is it useful\n"
" GSout = GSin[i];\n"
" EmitVertex();\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; // FIXME is it useful\n"
" GSout = GSin[i];\n"
"#if GS_IIP == 0\n"
" if (i == 0)\n"
" GSout.c = GSin[1].c;\n"
"#endif\n"
" EmitVertex();\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; // FIXME is it useful\n"
" GSout = GSin[i];\n"
"#if GS_IIP == 0\n"
" if (i == 0 || i == 1)\n"
" GSout.c = GSin[2].c;\n"
"#endif\n"
" EmitVertex();\n"
" }\n"
" EndPrimitive();\n"
"}\n"
"\n"
"#elif GS_PRIM == 3\n"
"layout(lines) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n"
"\n"
"void gs_main()\n"
"{\n"
" // left top => GSin[0];\n"
" // right bottom => GSin[1];\n"
" vertex rb = GSin[1];\n"
" vertex lt = GSin[0];\n"
"\n"
" lt.p.z = rb.p.z;\n"
" lt.t.zw = rb.t.zw;\n"
"#if GS_IIP == 0\n"
" lt.c = rb.c;\n"
"#endif\n"
"\n"
" vertex lb = rb;\n"
" lb.p.x = lt.p.x;\n"
" lb.t.x = lt.t.x;\n"
"\n"
" vertex rt = rb;\n"
" rt.p.y = lt.p.y;\n"
" rt.t.y = lt.t.y;\n"
"\n"
" // Triangle 1\n"
" gl_Position = lt.p;\n"
" GSout = lt;\n"
" EmitVertex();\n"
"\n"
" gl_Position = lb.p;\n"
" GSout = lb;\n"
" EmitVertex();\n"
"\n"
" gl_Position = rt.p;\n"
" GSout = rt;\n"
" EmitVertex();\n"
"\n"
" EndPrimitive();\n"
"\n"
" // Triangle 2\n"
" gl_Position = lb.p;\n"
" GSout = lb;\n"
" EmitVertex();\n"
"\n"
" gl_Position = rt.p;\n"
" GSout = rt;\n"
" EmitVertex();\n"
"\n"
" gl_Position = rb.p;\n"
" GSout = rb;\n"
" EmitVertex();\n"
"\n"
" EndPrimitive();\n"
"\n"
"}\n"
"\n"
"#endif\n"
"\n"
"#endif\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"layout(location = 0) in vertex PSin;\n"
"\n"
"// Same buffer but 2 colors for dual source blending\n"
"layout(location = 0, index = 0) out vec4 SV_Target0;\n"
"layout(location = 0, index = 1) out vec4 SV_Target1;\n"
"\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"layout(binding = 1) uniform sampler2D PaletteSampler;\n"
"layout(binding = 2) uniform sampler2D RTCopySampler;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb21\n"
"#else\n"
"layout(std140, binding = 21) uniform cb21\n"
"#endif\n"
"{\n"
" vec3 FogColor;\n"
" float AREF;\n"
" vec4 HalfTexel;\n"
" vec4 WH;\n"
" vec4 MinMax;\n"
" vec2 MinF;\n"
" vec2 TA;\n"
" uvec4 MskFix;\n"
" vec4 TC_OffsetHack;\n"
"};\n"
"\n"
"vec4 sample_c(vec2 uv)\n"
"{\n"
" // FIXME: check the issue on openGL\n"
" if (ATI_SUCKS == 1 && PS_POINT_SAMPLER == 1)\n"
" {\n"
" // Weird issue with ATI cards (happens on at least HD 4xxx and 5xxx),\n"
" // it looks like they add 127/128 of a texel to sampling coordinates\n"
" // occasionally causing point sampling to erroneously round up.\n"
" // I'm manually adjusting coordinates to the centre of texels here,\n"
" // though the centre is just paranoia, the top left corner works fine.\n"
" uv = (trunc(uv * WH.zw) + vec2(0.5, 0.5)) / WH.zw;\n"
" }\n"
"\n"
" // FIXME I'm not sure it is a good solution to flip texture\n"
" return texture(TextureSampler, uv);\n"
" //FIXME another way to FLIP vertically\n"
" //return texture(TextureSampler, vec2(uv.x, 1.0f-uv.y) );\n"
"}\n"
"\n"
"vec4 sample_p(float u)\n"
"{\n"
" //FIXME do we need a 1D sampler. Big impact on opengl to find 1 dim\n"
" // So for the moment cheat with 0.0f dunno if it work\n"
" return texture(PaletteSampler, vec2(u, 0.0f));\n"
"}\n"
"\n"
"vec4 sample_rt(vec2 uv)\n"
"{\n"
" return texture(RTCopySampler, uv);\n"
"}\n"
"\n"
"vec4 wrapuv(vec4 uv)\n"
"{\n"
" vec4 uv_out = uv;\n"
"\n"
" if(PS_WMS == PS_WMT)\n"
" {\n"
" if(PS_WMS == 2)\n"
" {\n"
" uv_out = clamp(uv, MinMax.xyxy, MinMax.zwzw);\n"
" }\n"
" else if(PS_WMS == 3)\n"
" {\n"
" uv_out = vec4(((ivec4(uv * WH.xyxy) & ivec4(MskFix.xyxy)) | ivec4(MskFix.zwzw)) / WH.xyxy);\n"
" }\n"
" }\n"
" else\n"
" {\n"
" if(PS_WMS == 2)\n"
" {\n"
" uv_out.xz = clamp(uv.xz, MinMax.xx, MinMax.zz);\n"
" }\n"
" else if(PS_WMS == 3)\n"
" {\n"
" uv_out.xz = vec2(((ivec2(uv.xz * WH.xx) & ivec2(MskFix.xx)) | ivec2(MskFix.zz)) / WH.xx);\n"
" }\n"
" if(PS_WMT == 2)\n"
" {\n"
" uv_out.yw = clamp(uv.yw, MinMax.yy, MinMax.ww);\n"
" }\n"
" else if(PS_WMT == 3)\n"
" {\n"
" uv_out.yw = vec2(((ivec2(uv.yw * WH.yy) & ivec2(MskFix.yy)) | ivec2(MskFix.ww)) / WH.yy);\n"
" }\n"
" }\n"
"\n"
" return uv_out;\n"
"}\n"
"\n"
"vec2 clampuv(vec2 uv)\n"
"{\n"
" vec2 uv_out = uv;\n"
"\n"
" if(PS_WMS == 2 && PS_WMT == 2) \n"
" {\n"
" uv_out = clamp(uv, MinF, MinMax.zw);\n"
" }\n"
" else if(PS_WMS == 2)\n"
" {\n"
" uv_out.x = clamp(uv.x, MinF.x, MinMax.z);\n"
" }\n"
" else if(PS_WMT == 2)\n"
" {\n"
" uv_out.y = clamp(uv.y, MinF.y, MinMax.w);\n"
" }\n"
"\n"
" return uv_out;\n"
"}\n"
"\n"
"mat4 sample_4c(vec4 uv)\n"
"{\n"
" mat4 c;\n"
"\n"
" c[0] = sample_c(uv.xy);\n"
" c[1] = sample_c(uv.zy);\n"
" c[2] = sample_c(uv.xw);\n"
" c[3] = sample_c(uv.zw);\n"
"\n"
" return c;\n"
"}\n"
"\n"
"vec4 sample_4a(vec4 uv)\n"
"{\n"
" vec4 c;\n"
"\n"
" // XXX\n"
" // I think .a is related to 8bit texture in alpha channel\n"
" // Opengl is only 8 bits on red channel. Not sure exactly of the impact\n"
" c.x = sample_c(uv.xy).a;\n"
" c.y = sample_c(uv.zy).a;\n"
" c.z = sample_c(uv.xw).a;\n"
" c.w = sample_c(uv.zw).a;\n"
"\n"
" return c * 255./256 + 0.5/256;\n"
"}\n"
"\n"
"mat4 sample_4p(vec4 u)\n"
"{\n"
" mat4 c;\n"
"\n"
" c[0] = sample_p(u.x);\n"
" c[1] = sample_p(u.y);\n"
" c[2] = sample_p(u.z);\n"
" c[3] = sample_p(u.w);\n"
"\n"
" return c;\n"
"}\n"
"\n"
"vec4 sample_color(vec2 st, float q)\n"
"{\n"
" if(PS_FST == 0) st /= q;\n"
"\n"
" if(PS_TCOFFSETHACK == 1) st += TC_OffsetHack.xy;\n"
"\n"
" vec4 t;\n"
" mat4 c;\n"
" vec2 dd;\n"
"\n"
" if (PS_LTF == 0 && PS_FMT <= FMT_16 && PS_WMS < 3 && PS_WMT < 3)\n"
" {\n"
" c[0] = sample_c(clampuv(st));\n"
" }\n"
" else\n"
" {\n"
" vec4 uv;\n"
"\n"
" if(PS_LTF != 0)\n"
" {\n"
" uv = st.xyxy + HalfTexel;\n"
" dd = fract(uv.xy * WH.zw);\n"
" }\n"
" else\n"
" {\n"
" uv = st.xyxy;\n"
" }\n"
"\n"
" uv = wrapuv(uv);\n"
"\n"
" if((PS_FMT & FMT_PAL) != 0)\n"
" {\n"
" c = sample_4p(sample_4a(uv));\n"
" }\n"
" else\n"
" {\n"
" c = sample_4c(uv);\n"
" }\n"
" }\n"
"\n"
" // PERF: see the impact of the exansion before/after the interpolation\n"
" for (int i = 0; i < 4; i++)\n"
" {\n"
" if((PS_FMT & ~FMT_PAL) == FMT_24)\n"
" {\n"
" // FIXME GLSL any only support bvec so try to mix it with notEqual\n"
" bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) );\n"
" t.a = ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n"
" }\n"
" else if((PS_FMT & ~FMT_PAL) == FMT_16)\n"
" {\n"
" // FIXME GLSL any only support bvec so try to mix it with notEqual\n"
" bvec3 rgb_check = notEqual( t.rgb, vec3(0.0f, 0.0f, 0.0f) );\n"
" t.a = t.a >= 0.5 ? TA.y : ( (PS_AEM == 0) || any(rgb_check) ) ? TA.x : 0.0f;\n"
" }\n"
" }\n"
"\n"
" if(PS_LTF != 0)\n"
" {\n"
" t = mix(mix(c[0], c[1], dd.x), mix(c[2], c[3], dd.x), dd.y);\n"
" }\n"
" else\n"
" {\n"
" t = c[0];\n"
" }\n"
"\n"
" return t;\n"
"}\n"
"\n"
"vec4 tfx(vec4 t, vec4 c)\n"
"{\n"
" vec4 c_out = c;\n"
" if(PS_TFX == 0)\n"
" {\n"
" if(PS_TCC != 0) \n"
" {\n"
" c_out = c * t * 255.0f / 128;\n"
" }\n"
" else\n"
" {\n"
" c_out.rgb = c.rgb * t.rgb * 255.0f / 128;\n"
" }\n"
" }\n"
" else if(PS_TFX == 1)\n"
" {\n"
" if(PS_TCC != 0) \n"
" {\n"
" c_out = t;\n"
" }\n"
" else\n"
" {\n"
" c_out.rgb = t.rgb;\n"
" }\n"
" }\n"
" else if(PS_TFX == 2)\n"
" {\n"
" c_out.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;\n"
"\n"
" if(PS_TCC != 0) \n"
" {\n"
" c_out.a += t.a;\n"
" }\n"
" }\n"
" else if(PS_TFX == 3)\n"
" {\n"
" c_out.rgb = c.rgb * t.rgb * 255.0f / 128 + c.a;\n"
"\n"
" if(PS_TCC != 0) \n"
" {\n"
" c_out.a = t.a;\n"
" }\n"
" }\n"
"\n"
" 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"
"void datst()\n"
"{\n"
"#if PS_DATE > 0\n"
" float alpha = sample_rt(PSin.tp.xy).a;\n"
" float alpha0x80 = 128. / 255;\n"
"\n"
" if (PS_DATE == 1 && alpha >= alpha0x80)\n"
" discard;\n"
" else if (PS_DATE == 2 && alpha < alpha0x80)\n"
" discard;\n"
"#endif\n"
"}\n"
"\n"
"void atst(vec4 c)\n"
"{\n"
" float a = trunc(c.a * 255 + 0.01);\n"
"\n"
" if(PS_ATST == 0) // never\n"
" {\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 1) // always\n"
" {\n"
" // nothing to do\n"
" }\n"
" else if(PS_ATST == 2 ) // l\n"
" {\n"
" if (PS_SPRITEHACK == 0)\n"
" if ((AREF - a - 0.5f) < 0.0f)\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 3 ) // le\n"
" {\n"
" if ((AREF - a + 0.5f) < 0.0f)\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 4) // e\n"
" {\n"
" if ((0.5f - abs(a - AREF)) < 0.0f)\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 5) // ge\n"
" {\n"
" if ((a-AREF + 0.5f) < 0.0f)\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 6) // g\n"
" {\n"
" if ((a-AREF - 0.5f) < 0.0f)\n"
" discard;\n"
" }\n"
" else if(PS_ATST == 7) // ne\n"
" {\n"
" if ((abs(a - AREF) - 0.5f) < 0.0f)\n"
" discard;\n"
" }\n"
"}\n"
"\n"
"vec4 fog(vec4 c, float f)\n"
"{\n"
" vec4 c_out = c;\n"
" if(PS_FOG != 0)\n"
" {\n"
" c_out.rgb = mix(FogColor, c.rgb, f);\n"
" }\n"
"\n"
" return c_out;\n"
"}\n"
"\n"
"vec4 ps_color()\n"
"{\n"
" datst();\n"
"\n"
" vec4 t = sample_color(PSin.t.xy, PSin.t.w);\n"
"\n"
" vec4 c = tfx(t, PSin.c);\n"
"\n"
" atst(c);\n"
"\n"
" c = fog(c, PSin.t.z);\n"
"\n"
" if (PS_COLCLIP == 2)\n"
" {\n"
" c.rgb = 256.0f/255.0f - c.rgb;\n"
" }\n"
" if (PS_COLCLIP > 0)\n"
" {\n"
" // FIXME !!!!\n"
" //c.rgb *= c.rgb < 128./255;\n"
" bvec3 factor = bvec3(128.0f/255.0f, 128.0f/255.0f, 128.0f/255.0f);\n"
" c.rgb *= vec3(factor);\n"
" }\n"
"\n"
" if(PS_CLR1 != 0) // needed for Cd * (As/Ad/F + 1) blending modes\n"
" {\n"
" c.rgb = vec3(1.0f, 1.0f, 1.0f); \n"
" }\n"
"\n"
" return c;\n"
"}\n"
"\n"
"void ps_main()\n"
"{\n"
" //FIXME\n"
" vec4 c = ps_color();\n"
"\n"
" // FIXME: I'm not sure about the value of others field\n"
" // output.c1 = c.a * 2; // used for alpha blending\n"
"\n"
" float alpha = c.a * 2;\n"
"\n"
" if(PS_AOUT != 0) // 16 bit output\n"
" {\n"
" float a = 128.0f / 255; // alpha output will be 0x80\n"
"\n"
" c.a = (PS_FBA != 0) ? a : step(0.5, c.a) * a;\n"
" }\n"
" else if(PS_FBA != 0)\n"
" {\n"
" if(c.a < 0.5) c.a += 0.5;\n"
" }\n"
"\n"
" SV_Target0 = c;\n"
" SV_Target1 = vec4(alpha, alpha, alpha, alpha);\n"
"}\n"
"#endif\n"
;