diff --git a/plugins/GSdx/GSDevice.h b/plugins/GSdx/GSDevice.h index 7780b3b0ee..8f8b9fe1cf 100644 --- a/plugins/GSdx/GSDevice.h +++ b/plugins/GSdx/GSDevice.h @@ -46,6 +46,7 @@ enum ShaderConvert { ShaderConvert_RGB5A1_TO_FLOAT16, ShaderConvert_RGBA_TO_8I = 17, ShaderConvert_OSD, + ShaderConvert_YUV, ShaderConvert_Count }; diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index 884c0e1700..899438c277 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -389,6 +389,7 @@ public: { GSVector4i ScalingFactor; GSVector4i ChannelShuffle; + GSVector4i EMOD_AC; MiscConstantBuffer() {memset(this, 0, sizeof(*this));} }; diff --git a/plugins/GSdx/res/glsl/common_header.glsl b/plugins/GSdx/res/glsl/common_header.glsl index ad8c35e62f..668a9acc12 100644 --- a/plugins/GSdx/res/glsl/common_header.glsl +++ b/plugins/GSdx/res/glsl/common_header.glsl @@ -49,6 +49,11 @@ layout(std140, binding = 15) uniform cb15 { ivec4 ScalingFactor; ivec4 ChannelShuffle; + + int EMODA; + int EMODC; + int _pad0; + int _pad1; }; #endif diff --git a/plugins/GSdx/res/glsl/convert.glsl b/plugins/GSdx/res/glsl/convert.glsl index 600d563ca8..a261101611 100644 --- a/plugins/GSdx/res/glsl/convert.glsl +++ b/plugins/GSdx/res/glsl/convert.glsl @@ -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 diff --git a/plugins/GSdx/res/glsl_source.h b/plugins/GSdx/res/glsl_source.h index 09d2c2f00d..6d1906702e 100644 --- a/plugins/GSdx/res/glsl_source.h +++ b/plugins/GSdx/res/glsl_source.h @@ -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" ;