2
\$\begingroup\$

I made a shader to display a YUYV surface (data arranged as: Y0 U0 Y1 V0). It's working, but I don't know anything about shaders, or openGL, or anything graphic related as a matter of fact. I feel more like a mad scientist patching random bits of code together than a programmer. Thus, I would appreciate if anyone could look it up and tell me what I could improve, performance-wise, logic-wise or syntax-wise. I also have some questions:

  • What desktop hardware will that work on? Is there any restriction, or will it work on any 10 years old desktop?
  • Would that work on an android tablet?
  • Will any interpolation of pixel be performed, if my rendering surface is the same size as the texture? Is it possible to have interpolation (with some flag, not by implementing it)?

I load my YUYV texture as RGBA texture of width/2 by height. The rest should be self-explanatory:

#version 330 core
uniform sampler2D tex;
uniform mat4 convMat; /* Color conversion matrix */
uniform vec2 dim; /* Width and height of image */
in vec2 UV;
out vec3 color;

void main(){
    vec4 yuv;
    ivec2 iUV = ivec2(UV*dim*vec2(0.5, 1)); /* Absolute coordinate of desired pixel in texture */

    yuv = texelFetch(texy, iUV, 0);
    if (int(UV.x*dim.x) % 2 == 1){
        /* There are 2 Y in a texture RGBA pixel, choose the right one based on absolute pixel coordinate */
        yuv.x = yuv.z;
    };
    yuv.z = yuv.w;
    yuv.w = 1;
    color = (convMat*yuv).rgb;
};
\$\endgroup\$
  • \$\begingroup\$ @JonathanDrolet, FYI, in this site it is preferred to avoid changing a question after receiving answers. Read this meta discussion. I don't think any harm was done here, so you can leave it as it is, but the best course of action would be posting another question with the updated code. \$\endgroup\$ – glampert Apr 28 '15 at 17:53
4
\$\begingroup\$

Okay, trying to answer a few of your questions to the best of my knowledge:


What desktop hardware will that work on? Is there any restriction, or will it work on any 10 years old desktop?

Probably not in a 10yo PC. Your code is currently targeting GLSL version 3.3, which was released circa 2010. You can check a version history here. However, if you need to be backward compatible, there are changes you can make to this code to target older OpenGL versions. I'll mention those at the end.


Would that work on an android tablet?

No. Android devices use OpenGL-ES, which is a variant of Desktop OpenGL version 2.0. You wouldn't have the texelFetch() function neither integer types in the current OpenGL-ES used by both Android and iOS devices.


Will any interpolation of pixel be performed, if my rendering surface is the same size as the texture? Is it possible to have interpolation (with some flag, not by implementing it)?

What exactly do you mean by interpolation? By any chance are you talking about texture filtering? By using texelFetch(), you have opted-out of texture filtering. It is not clear to my why you did this however. If you were to switch your texture sampling to a function like texture() (or texture2D if targeting older versions) you would be able to have filtered lookup and also avoid the non-portable texelFetch(). texture()/texture2D() also take the UVs as normalized 0-1 range texture coordinates, so it would make your shader faster too by eliminating the integer conversions.


Backward compatibility: You can make this code backward compatible with older OpenGL version by replacing texelFetch() with texture()/texture2D(), as I've mentioned before. That would also be necessary for current OpenGL-ES compat. You would also have to remove any integer conversions. Older OpenGL and OpenGL-ES hardware can only operate on floating point types! (no int or ivec).

A comment on performance: Branching is still an expensive operation on a lot of graphics hardware out there. So the most obvious improvement here would be to eliminate the conditional if test. You might be able to pull it off using several clever tricks. Maybe the mod function might be of help.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the input. There was a perfectly valid reason for texelFetch, but since I can't remember it's probably not relevant anymore. I removed it as well as integer reference in favor of mod. I also created a version using a permutation matrix instead of the if statement, but I have a hard time believing it "better", I added it to the question, care to comment if it's better than the if it replaces? \$\endgroup\$ – Jonathan Drolet Apr 28 '15 at 14:46
  • \$\begingroup\$ @JonathanDrolet, I like the new version but I don't think you're going to be able to measure any benefits indeed. Unfortunately, benchmarking shaders is really hard, and we lack good profiling tools. \$\endgroup\$ – glampert Apr 28 '15 at 17:42
  • \$\begingroup\$ BTW, the last parameter in texture() (bias) is optional, so you might omit the 0. \$\endgroup\$ – glampert Apr 28 '15 at 17:42
  • 1
    \$\begingroup\$ If you are interested in attempting to measure execution times, then I think a Timer Query is where you can start. \$\endgroup\$ – glampert Apr 28 '15 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.