title: How to extend vertex shader capabalities for GPGPU
body: <p>I'm trying to implement Scrypt hasher (for LTC miner) on GLSL (don't ask me why).</p>
  
  <p>And, actually, I'm stucked with HMAC SHA-256 algorithm. Despite I've implemented SHA-256 correctly (it retuns corrent hash for input), fragment shader stops to compile when I add  the last step (hashing previous hash concated with oKey).</p>
  
  <p>The shader can't do more than three rounds of SHA-256. It just stops to compile. What are the limits? It doesn't use much memory, 174 vec2 objects in total. It seems, it doesn't relate to memory, because any extra SHA256 round doesn't require new memory. And it seems, it doesn't relate to viewport size. It stops to work on both 1x1 and 1x128 viewports.</p>
  
  <p>I've started to do miner on WebGL, but after limit appeared, I've tried to run the same shader in the Qt on the full featured OpenGL. In result, desktop OpenGL allows one SHA256 round lesser then OpenGL ES in WebGL (why?).</p>
  
  <p><strong>Forgot to mention</strong>. Shader fails on the linkage stage. The shader compiles well itself, but the program linkage fails.</p>
  
  <p>I don't use any textures, any extensions, slow things etc. Just simple square (4 vec2 vertecies) and several uniforms for fragment shader. 
  Input data is just 80 bytes, the result of fragment shader is binary (black or white), so the task ideally fits the GLSL principes. </p>
  
  <p>My videocard is Radeon HD7970 with plenty of VRAM, which is able to fit hundreds of scrypt threads (scrypt uses 128kB per hash, but I can't achieve just HMAC-SHA-256). My card supports OpenGL 4.4.</p>
  
  <p>I'm newbie in OpenGL, and may understand something wrong. I understand that fragment shader runs for each pixel separately, but if I have 1x128 viewport, there are only 128x348 bytes used. Where is the limit of fragment shader. </p>
  
  <p>Here is the common code I use to let you understand, how I'm trying to solve the problem.</p>
  
  <pre><code>uniform vec2 base_nonce[2];
  uniform vec2 header[20];    /* Header of the block */
  uniform vec2 H[8];
  uniform vec2 K[64];
  
  void sha256_round(inout vec2 w[64], inout vec2 t[8], inout vec2 hash[8]) {
      for (int i = 0; i &lt; 64; i++) {
          if( i &gt; 15 ) {
              w[i] = blend(w[i-16], w[i-15], w[i-7], w[i-2]);
          }
  
          _s0 = e0(t[0]);
          _maj = maj(t[0],t[1],t[2]);
          _t2 = safe_add(_s0, _maj);
          _s1 = e1(t[4]);
          _ch = ch(t[4], t[5], t[6]);
          _t1 = safe_add(safe_add(safe_add(safe_add(t[7], _s1), _ch), K[i]), w[i]);
  
          t[7] = t[6]; t[6] = t[5]; t[5] = t[4];
          t[4] = safe_add(t[3], _t1);
          t[3] = t[2]; t[2] = t[1]; t[1] = t[0];
          t[0] = safe_add(_t1, _t2);
      }
      for (int i = 0; i &lt; 8; i++) {
          hash[i] = safe_add(t[i], hash[i]);
          t[i] = hash[i];
      }
  }
  
  void main () {
      vec2 key_hash[8]; /* Our SHA-256 hash */
      vec2 i_key[16];
      vec2 i_key_hash[8];
      vec2 o_key[16];
  
      vec2 nonced_header[20]; /* Header with nonce */
      set_nonce_to_header(nonced_header);
  
      vec2 P[32]; /* Padded SHA-256 message */
      pad_the_header(P, nonced_header);
  
      /* Hash HMAC secret key */
      sha256(P, key_hash);
  
      /* Make iKey and oKey */
      for(int i = 0; i &lt; 16; i++) {
          if (i &lt; 8) {
              i_key[i] = xor(key_hash[i], vec2(Ox3636, Ox3636));
              o_key[i] = xor(key_hash[i], vec2(Ox5c5c, Ox5c5c));
          } else {
              i_key[i] = vec2(Ox3636, Ox3636);
              o_key[i] = vec2(Ox5c5c, Ox5c5c);
          }
      }
  
      /* SHA256 hash of iKey */
  
      for (int i = 0; i &lt; 8; i++) {
          i_key_hash[i] = H[i];
          t[i] = i_key_hash[i];
      }
  
      for (int i = 0; i &lt; 16; i++) { w[i] = i_key[i]; }
      sha256_round(w, t, i_key_hash);
  
      gl_FragColor = toRGBA(i_key_hash[0]);
  }
  </code></pre>
  
  <p>What solutions can I use to improve the situation? Is there something cool in OpenGL 4.4, in OpenGL ES 3.1? Is it even possible to do such calculations and keep so much (128kB) in fragment shader? What are limits for the vertex shader? Can I do the same on the vertex shader instead the fragment?</p>