]> git.sesse.net Git - narabu/blobdiff - decoder.shader
Make the encoder 100% GPU. Not working yet, though.
[narabu] / decoder.shader
index 77ae2869f08c54cf3a4fafbc6d101e6dba62a408..616c3e2dfd0896e5cd035bacc42ec0720c5174a1 100644 (file)
@@ -9,11 +9,14 @@ layout(local_size_x = 64*PARALLEL_SLICES) in;
 layout(r8ui) uniform restrict readonly uimage2D cum2sym_tex;
 layout(rg16ui) uniform restrict readonly uimage2D dsyms_tex;
 layout(r8) uniform restrict writeonly image2D out_tex;
+layout(r16i) uniform restrict writeonly iimage2D coeff_tex;
+uniform int num_blocks;
 
 const uint prob_bits = 12;
 const uint prob_scale = 1 << prob_bits;
 const uint NUM_SYMS = 256;
 const uint ESCAPE_LIMIT = NUM_SYMS - 1;
+const uint BLOCKS_PER_STREAM = 320;
 
 // These need to be folded into quant_matrix.
 const float dc_scalefac = 8.0;
@@ -39,6 +42,16 @@ const uint ff_zigzag_direct[64] = {
     58, 59, 52, 45, 38, 31, 39, 46,
     53, 60, 61, 54, 47, 55, 62, 63
 };
+const uint stream_mapping[64] = {
+       0, 0, 1, 1, 2, 2, 3, 3,
+       0, 0, 1, 2, 2, 2, 3, 3,
+       1, 1, 2, 2, 2, 3, 3, 3,
+       1, 1, 2, 2, 2, 3, 3, 3,
+       1, 2, 2, 2, 2, 3, 3, 3,
+       2, 2, 2, 2, 3, 3, 3, 3,
+       2, 2, 3, 3, 3, 3, 3, 3,
+       3, 3, 3, 3, 3, 3, 3, 3,
+};
 
 layout(std430, binding = 9) buffer layoutName
 {
@@ -149,8 +162,8 @@ void idct_1d(inout float y0, inout float y1, inout float y2, inout float y3, ino
        y0 = p6_0 + p6_7;
        y1 = p6_1 + p6_6;
        y2 = p6_2 + p6_5;
-       y3 = p6_3 - p4_4;
-       y4 = p6_3 + p4_4;
+       y3 = p6_3 + p4_4;
+       y4 = p6_3 - p4_4;
        y5 = p6_2 - p6_5;
        y6 = p6_1 - p6_6;
        y7 = p6_0 - p6_7;
@@ -191,11 +204,12 @@ void main()
        local_timing[0] = start;
 #endif
 
+       const uint blocks_per_row = (imageSize(out_tex).x + 7) / 8;
+
        const uint local_x = gl_LocalInvocationID.x % 8;
        const uint local_y = (gl_LocalInvocationID.x / 8) % 8;
        const uint local_z = gl_LocalInvocationID.x / 64;
 
-       const uint num_blocks = 720 / 16;  // FIXME: make a uniform
        const uint slice_num = local_z;
        const uint thread_num = local_y * 8 + local_x;
 
@@ -203,7 +217,7 @@ void main()
        //const uint coeff_num = ff_zigzag_direct[thread_num];
        const uint coeff_num = thread_num;
        const uint stream_num = coeff_num * num_blocks + block_row;
-       const uint model_num = min((coeff_num % 8) + (coeff_num / 8), 7);
+       const uint model_num = stream_mapping[coeff_num];
        const uint sign_bias = sign_bias_per_model[model_num];
 
        // Initialize rANS decoder.
@@ -213,15 +227,11 @@ void main()
        float q = (coeff_num == 0) ? 1.0 : (quant_matrix[coeff_num] * quant_scalefac / 128.0 / sqrt(2.0));  // FIXME: fold
        q *= (1.0 / 255.0);
        //int w = (coeff_num == 0) ? 32 : int(quant_matrix[coeff_num]);
-       int last_k = 0;
+       int last_k = 128;
 
        pick_timer(start, local_timing[0]);
 
-       for (uint block_idx = 40; block_idx --> 0; ) {
-               uint block_x = block_idx % 20;
-               uint block_y = block_idx / 20;
-               if (block_x == 19) last_k = 0;
-
+       for (uint block_idx = BLOCKS_PER_STREAM / 8; block_idx --> 0; ) {
                pick_timer(start, local_timing[1]);
 
                // rANS decode one coefficient across eight blocks (so 64x8 coefficients).
@@ -251,6 +261,12 @@ void main()
                                last_k = k;
                        }
 
+#if 0
+                       uint y = block_row * 16 + block_y * 8 + local_y;
+                       uint x = block_x * 64 + subblock_idx * 8 + local_x;
+                       imageStore(coeff_tex, ivec2(x, y), ivec4(k, 0,0,0));
+#endif
+
                        temp[slice_num * 64 * 8 + subblock_idx * 64 + coeff_num] = k * q;
                        //temp[subblock_idx * 64 + 8 * y + x] = (2 * k * w * 4) / 32;  // 100% matching unquant
                }
@@ -292,8 +308,12 @@ void main()
 
                pick_timer(start, local_timing[6]);
 
-               uint y = block_row * 16 + block_y * 8;
-               uint x = block_x * 64 + local_y * 8 + local_x;
+               uint global_block_idx = (block_row * 40 + block_idx) * 8 + local_y;
+               uint block_x = global_block_idx % blocks_per_row;
+               uint block_y = global_block_idx / blocks_per_row;
+
+               uint y = block_y * 8;
+               uint x = block_x * 8 + local_x;
                for (uint yl = 0; yl < 8; ++yl) {
                        imageStore(out_tex, ivec2(x, yl + y), vec4(temp[row_offset + yl * 8], 0.0, 0.0, 1.0));
                }