gsdx shader: RGB => YUV conversion

Required for write feedback emulation
This commit is contained in:
Gregory Hainaut 2016-10-09 14:28:49 +02:00
parent 6ef5607d99
commit 317a464278
5 changed files with 114 additions and 0 deletions

View File

@ -46,6 +46,7 @@ enum ShaderConvert {
ShaderConvert_RGB5A1_TO_FLOAT16,
ShaderConvert_RGBA_TO_8I = 17,
ShaderConvert_OSD,
ShaderConvert_YUV,
ShaderConvert_Count
};

View File

@ -389,6 +389,7 @@ public:
{
GSVector4i ScalingFactor;
GSVector4i ChannelShuffle;
GSVector4i EMOD_AC;
MiscConstantBuffer() {memset(this, 0, sizeof(*this));}
};

View File

@ -49,6 +49,11 @@ layout(std140, binding = 15) uniform cb15
{
ivec4 ScalingFactor;
ivec4 ChannelShuffle;
int EMODA;
int EMODC;
int _pad0;
int _pad1;
};
#endif

View File

@ -387,4 +387,55 @@ void ps_main4()
}
#endif
#ifdef ps_main19
void ps_main19()
{
vec4 i = sample_c();
vec4 o;
mat3 rgb2yuv; // Value from GS manual
rgb2yuv[0] = vec3(0.587, -0.311, -0.419);
rgb2yuv[1] = vec3(0.114, 0.500, -0.081);
rgb2yuv[2] = vec3(0.299, -0.169, 0.500);
vec3 yuv = rgb2yuv * i.gbr;
float Y = float(0xDB)/255.0f * yuv.x + float(0x10)/255.0f;
float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f;
float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f;
switch(EMODA) {
case 0:
o.a = i.a;
break;
case 1:
o.a = Y;
break;
case 2:
o.a = Y/2.0f;
break;
case 3:
o.a = 0.0f;
break;
}
switch(EMODC) {
case 0:
o.rgb = i.rgb;
break;
case 1:
o.rgb = vec3(Y);
break;
case 2:
o.rgb = vec3(Y, Cb, Cr);
break;
case 3:
o.rgb = vec3(i.a);
break;
}
SV_Target0 = o;
}
#endif
#endif

View File

@ -77,6 +77,11 @@ static const char* const common_header_glsl =
"{\n"
" ivec4 ScalingFactor;\n"
" ivec4 ChannelShuffle;\n"
"\n"
" int EMODA;\n"
" int EMODC;\n"
" int _pad0;\n"
" int _pad1;\n"
"};\n"
"#endif\n"
"\n"
@ -522,6 +527,57 @@ static const char* const convert_glsl =
"}\n"
"#endif\n"
"\n"
"#ifdef ps_main19\n"
"void ps_main19()\n"
"{\n"
" vec4 i = sample_c();\n"
" vec4 o;\n"
"\n"
" mat3 rgb2yuv; // Value from GS manual\n"
" rgb2yuv[0] = vec3(0.587, -0.311, -0.419);\n"
" rgb2yuv[1] = vec3(0.114, 0.500, -0.081);\n"
" rgb2yuv[2] = vec3(0.299, -0.169, 0.500);\n"
"\n"
" vec3 yuv = rgb2yuv * i.gbr;\n"
"\n"
" float Y = float(0xDB)/255.0f * yuv.x + float(0x10)/255.0f;\n"
" float Cr = float(0xE0)/255.0f * yuv.y + float(0x80)/255.0f;\n"
" float Cb = float(0xE0)/255.0f * yuv.z + float(0x80)/255.0f;\n"
"\n"
" switch(EMODA) {\n"
" case 0:\n"
" o.a = i.a;\n"
" break;\n"
" case 1:\n"
" o.a = Y;\n"
" break;\n"
" case 2:\n"
" o.a = Y/2.0f;\n"
" break;\n"
" case 3:\n"
" o.a = 0.0f;\n"
" break;\n"
" }\n"
"\n"
" switch(EMODC) {\n"
" case 0:\n"
" o.rgb = i.rgb;\n"
" break;\n"
" case 1:\n"
" o.rgb = vec3(Y);\n"
" break;\n"
" case 2:\n"
" o.rgb = vec3(Y, Cb, Cr);\n"
" break;\n"
" case 3:\n"
" o.rgb = vec3(i.a);\n"
" break;\n"
" }\n"
"\n"
" SV_Target0 = o;\n"
"}\n"
"#endif\n"
"\n"
"#endif\n"
;