[MPlayer-cvslog] r30995 - trunk/libvo/gl_common.c

reimar subversion at mplayerhq.hu
Sun Apr 4 13:45:05 CEST 2010


Author: reimar
Date: Sun Apr  4 13:45:05 2010
New Revision: 30995

Log:
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).

Modified:
   trunk/libvo/gl_common.c

Modified: trunk/libvo/gl_common.c
==============================================================================
--- trunk/libvo/gl_common.c	Sat Apr  3 22:31:03 2010	(r30994)
+++ trunk/libvo/gl_common.c	Sun Apr  4 13:45:05 2010	(r30995)
@@ -763,80 +763,98 @@ static void glSetupYUVCombiners(float uv
 
 /**
  * \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_
       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:


More information about the MPlayer-cvslog mailing list