summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-04-04 11:45:05 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-04-04 11:45:05 +0000
commit22f6170009bb4442a9e0c2c2e44954df50a64d58 (patch)
treec205d67b2857fa0c23ef4901d24dd9d97048afcd /libvo
parent4a8486f8440ac70186f6e5bb0d5dcbef4ffe4f43 (diff)
downloadmpv-22f6170009bb4442a9e0c2c2e44954df50a64d58.tar.bz2
mpv-22f6170009bb4442a9e0c2c2e44954df50a64d58.tar.xz
Share more code between the two ATI fragment shader YUV to RGB
conversion methods and extend them to support more accurate conversion (though at the cost of some speed). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30995 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libvo')
-rw-r--r--libvo/gl_common.c156
1 files changed, 87 insertions, 69 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c
index 3408fb2996..07593989ae 100644
--- a/libvo/gl_common.c
+++ b/libvo/gl_common.c
@@ -763,80 +763,98 @@ static void glSetupYUVCombiners(float uvcos, float uvsin) {
/**
* \brief Setup ATI version of register combiners for YUV to RGB conversion.
- * \param uvcos used for saturation and hue adjustment
- * \param uvsin used for saturation and hue adjustment
- *
- * ATI called this fragment shader, but the name is confusing in the
- * light of a very different OpenGL 2.0 extension with the same name
+ * \param csp_params parameters used for colorspace conversion
+ * \param text if set use the GL_ATI_text_fragment_shader API as
+ * used on OS X.
*/
-static void glSetupYUVCombinersATI(float uvcos, float uvsin) {
- GLfloat ucoef[4];
- GLfloat vcoef[4];
+static void glSetupYUVFragmentATI(struct mp_csp_params *csp_params,
+ int text) {
GLint i;
- if (!mpglBeginFragmentShader || !mpglEndFragmentShader ||
- !mpglSetFragmentShaderConstant || !mpglSampleMap ||
- !mpglColorFragmentOp2 || !mpglColorFragmentOp3) {
- mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Combiner (ATI) functions missing!\n");
- return;
- }
- mpglGetIntegerv(GL_NUM_FRAGMENT_REGISTERS_ATI, &i);
- if (i < 3)
- mp_msg(MSGT_VO, MSGL_ERR,
- "[gl] 3 registers needed for YUV combiner (ATI) support (found %i)\n", i);
+ float yuv2rgb[3][4];
+
mpglGetIntegerv (GL_MAX_TEXTURE_UNITS, &i);
if (i < 3)
mp_msg(MSGT_VO, MSGL_ERR,
"[gl] 3 texture units needed for YUV combiner (ATI) support (found %i)\n", i);
- fillUVcoeff(ucoef, vcoef, uvcos, uvsin);
- mpglBeginFragmentShader();
- mpglSetFragmentShaderConstant(GL_CON_0_ATI, ucoef);
- mpglSetFragmentShaderConstant(GL_CON_1_ATI, vcoef);
- mpglSampleMap(GL_REG_0_ATI, GL_TEXTURE0, GL_SWIZZLE_STR_ATI);
- mpglSampleMap(GL_REG_1_ATI, GL_TEXTURE1, GL_SWIZZLE_STR_ATI);
- mpglSampleMap(GL_REG_2_ATI, GL_TEXTURE2, GL_SWIZZLE_STR_ATI);
- // UV first, like this green component cannot overflow
- mpglColorFragmentOp2(GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_NONE,
- GL_REG_1_ATI, GL_NONE, GL_BIAS_BIT_ATI,
- GL_CON_0_ATI, GL_NONE, GL_BIAS_BIT_ATI);
- mpglColorFragmentOp3(GL_MAD_ATI, GL_REG_2_ATI, GL_NONE, GL_4X_BIT_ATI,
- GL_REG_2_ATI, GL_NONE, GL_BIAS_BIT_ATI,
- GL_CON_1_ATI, GL_NONE, GL_BIAS_BIT_ATI,
- GL_REG_1_ATI, GL_NONE, GL_NONE);
- mpglColorFragmentOp2(GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
- GL_REG_0_ATI, GL_NONE, GL_NONE,
- GL_REG_2_ATI, GL_NONE, GL_NONE);
- mpglEndFragmentShader();
-}
-
-/**
- * \brief Variant of glYUVSetupCombinersATI using the API
- * implemented by Apple.
- */
-static void glSetupYUVTextFragment(float uvcos, float uvsin) {
- static const char template[] =
- "!!ATIfs1.0\n"
- "StartConstants;\n"
- " CONSTANT c0 = {%f, %f, %f};\n"
- " CONSTANT c1 = {%f, %f, %f};\n"
- "EndConstants;\n"
- "StartOutputPass;\n"
- " SampleMap r0, t0.str;\n"
- " SampleMap r1, t1.str;\n"
- " SampleMap r2, t2.str;\n"
- " MUL r1, r1.bias, c0.bias;\n"
- " MAD r2.4x, r2.bias, c1.bias, r1;\n"
- " ADD r0, r0, r2;\n"
- "EndPass;\n";
- GLfloat ucoef[4];
- GLfloat vcoef[4];
- char buffer[512];
- fillUVcoeff(ucoef, vcoef, uvcos, uvsin);
- snprintf(buffer, sizeof(buffer), template,
- ucoef[0], ucoef[1], ucoef[2],
- vcoef[0], vcoef[1], vcoef[2]);
- mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n", buffer);
- loadGPUProgram(GL_TEXT_FRAGMENT_SHADER_ATI, buffer);
+ mp_get_yuv2rgb_coeffs(csp_params, yuv2rgb);
+ for (i = 0; i < 3; i++) {
+ int j;
+ yuv2rgb[i][3] -= -0.5 * (yuv2rgb[i][1] + yuv2rgb[i][2]);
+ for (j = 0; j < 4; j++) {
+ yuv2rgb[i][j] *= 0.125;
+ yuv2rgb[i][j] += 0.5;
+ if (yuv2rgb[i][j] > 1)
+ yuv2rgb[i][j] = 1;
+ if (yuv2rgb[i][j] < 0)
+ yuv2rgb[i][j] = 0;
+ }
+ }
+ if (text == 0) {
+ GLfloat c0[4] = {yuv2rgb[0][0], yuv2rgb[1][0], yuv2rgb[2][0]};
+ GLfloat c1[4] = {yuv2rgb[0][1], yuv2rgb[1][1], yuv2rgb[2][1]};
+ GLfloat c2[4] = {yuv2rgb[0][2], yuv2rgb[1][2], yuv2rgb[2][2]};
+ GLfloat c3[4] = {yuv2rgb[0][3], yuv2rgb[1][3], yuv2rgb[2][3]};
+ if (!mpglBeginFragmentShader || !mpglEndFragmentShader ||
+ !mpglSetFragmentShaderConstant || !mpglSampleMap ||
+ !mpglColorFragmentOp2 || !mpglColorFragmentOp3) {
+ mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Combiner (ATI) functions missing!\n");
+ return;
+ }
+ mpglGetIntegerv(GL_NUM_FRAGMENT_REGISTERS_ATI, &i);
+ if (i < 3)
+ mp_msg(MSGT_VO, MSGL_ERR,
+ "[gl] 3 registers needed for YUV combiner (ATI) support (found %i)\n", i);
+ mpglBeginFragmentShader();
+ mpglSetFragmentShaderConstant(GL_CON_0_ATI, c0);
+ mpglSetFragmentShaderConstant(GL_CON_1_ATI, c1);
+ mpglSetFragmentShaderConstant(GL_CON_2_ATI, c2);
+ mpglSetFragmentShaderConstant(GL_CON_3_ATI, c3);
+ mpglSampleMap(GL_REG_0_ATI, GL_TEXTURE0, GL_SWIZZLE_STR_ATI);
+ mpglSampleMap(GL_REG_1_ATI, GL_TEXTURE1, GL_SWIZZLE_STR_ATI);
+ mpglSampleMap(GL_REG_2_ATI, GL_TEXTURE2, GL_SWIZZLE_STR_ATI);
+ mpglColorFragmentOp2(GL_MUL_ATI, GL_REG_1_ATI, GL_NONE, GL_NONE,
+ GL_REG_1_ATI, GL_NONE, GL_BIAS_BIT_ATI,
+ GL_CON_1_ATI, GL_NONE, GL_BIAS_BIT_ATI);
+ mpglColorFragmentOp3(GL_MAD_ATI, GL_REG_2_ATI, GL_NONE, GL_NONE,
+ GL_REG_2_ATI, GL_NONE, GL_BIAS_BIT_ATI,
+ GL_CON_2_ATI, GL_NONE, GL_BIAS_BIT_ATI,
+ GL_REG_1_ATI, GL_NONE, GL_NONE);
+ mpglColorFragmentOp3(GL_MAD_ATI, GL_REG_0_ATI, GL_NONE, GL_NONE,
+ GL_REG_0_ATI, GL_NONE, GL_NONE,
+ GL_CON_0_ATI, GL_NONE, GL_BIAS_BIT_ATI,
+ GL_REG_2_ATI, GL_NONE, GL_NONE);
+ mpglColorFragmentOp2(GL_ADD_ATI, GL_REG_0_ATI, GL_NONE, GL_8X_BIT_ATI,
+ GL_REG_0_ATI, GL_NONE, GL_NONE,
+ GL_CON_3_ATI, GL_NONE, GL_BIAS_BIT_ATI);
+ mpglEndFragmentShader();
+ } else {
+ static const char template[] =
+ "!!ATIfs1.0\n"
+ "StartConstants;\n"
+ " CONSTANT c0 = {%e, %e, %e};\n"
+ " CONSTANT c1 = {%e, %e, %e};\n"
+ " CONSTANT c2 = {%e, %e, %e};\n"
+ " CONSTANT c3 = {%e, %e, %e};\n"
+ "EndConstants;\n"
+ "StartOutputPass;\n"
+ " SampleMap r0, t0.str;\n"
+ " SampleMap r1, t1.str;\n"
+ " SampleMap r2, t2.str;\n"
+ " MUL r1.rgb, r1.bias, c1.bias;\n"
+ " MAD r2.rgb, r2.bias, c2.bias, r1;\n"
+ " MAD r0.rgb, r0, c0.bias, r2;\n"
+ " ADD r0.rgb.8x, r0, c3.bias;\n"
+ "EndPass;\n";
+ char buffer[512];
+ snprintf(buffer, sizeof(buffer), template,
+ yuv2rgb[0][0], yuv2rgb[1][0], yuv2rgb[2][0],
+ yuv2rgb[0][1], yuv2rgb[1][1], yuv2rgb[2][1],
+ yuv2rgb[0][2], yuv2rgb[1][2], yuv2rgb[2][2],
+ yuv2rgb[0][3], yuv2rgb[1][3], yuv2rgb[2][3]);
+ mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n", buffer);
+ loadGPUProgram(GL_TEXT_FRAGMENT_SHADER_ATI, buffer);
+ }
}
/**
@@ -1375,10 +1393,10 @@ void glSetupYUVConversion(gl_conversion_params_t *params) {
glSetupYUVCombiners(uvcos, uvsin);
break;
case YUV_CONVERSION_COMBINERS_ATI:
- glSetupYUVCombinersATI(uvcos, uvsin);
+ glSetupYUVFragmentATI(&params->csp_params, 0);
break;
case YUV_CONVERSION_TEXT_FRAGMENT:
- glSetupYUVTextFragment(uvcos, uvsin);
+ glSetupYUVFragmentATI(&params->csp_params, 1);
break;
case YUV_CONVERSION_FRAGMENT_LOOKUP:
case YUV_CONVERSION_FRAGMENT_LOOKUP3D: