X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=decoder.shader;h=616c3e2dfd0896e5cd035bacc42ec0720c5174a1;hb=5e1d27014149311318e97b8e04a6e05ec858e57c;hp=012cbe3bbac0ec13bb40b0cf42bd9ecc4bdcadf0;hpb=3fb87c6b953be3382cd216c74ff6aa025c8eaa2a;p=narabu diff --git a/decoder.shader b/decoder.shader index 012cbe3..616c3e2 100644 --- a/decoder.shader +++ b/decoder.shader @@ -9,8 +9,7 @@ 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(r32i) uniform restrict writeonly iimage2D coeff_tex; -layout(r32i) uniform restrict writeonly iimage2D coeff2_tex; +layout(r16i) uniform restrict writeonly iimage2D coeff_tex; uniform int num_blocks; const uint prob_bits = 12; @@ -72,50 +71,40 @@ layout(std430, binding = 0) buffer whatever3 }; uniform uint sign_bias_per_model[16]; -struct myuint64 { - uint high, low; -}; +const uint RANS_BYTE_L = (1u << 23); // lower bound of our normalization interval -const uint RANS64_L = (1u << 31); // lower bound of our normalization interval +uint get_rans_byte(uint offset) +{ + // We assume little endian. + return bitfieldExtract(data_SSBO[offset >> 2], 8 * int(offset & 3u), 8); +} -myuint64 RansDecInit(inout uint offset) +uint RansDecInit(inout uint offset) { - myuint64 x; - x.low = data_SSBO[offset++]; - x.high = data_SSBO[offset++]; + uint x; + + x = get_rans_byte(offset); + x |= get_rans_byte(offset + 1) << 8; + x |= get_rans_byte(offset + 2) << 16; + x |= get_rans_byte(offset + 3) << 24; + offset += 4; + return x; } -uint RansDecGet(myuint64 r, uint scale_bits) +uint RansDecGet(uint r, uint scale_bits) { - return r.low & ((1u << scale_bits) - 1); + return r & ((1u << scale_bits) - 1); } -void RansDecAdvance(inout myuint64 rans, inout uint offset, const uint start, const uint freq, uint prob_bits) +void RansDecAdvance(inout uint rans, inout uint offset, const uint start, const uint freq, uint prob_bits) { const uint mask = (1u << prob_bits) - 1; - const uint recovered_lowbits = (rans.low & mask) - start; - - // rans >>= prob_bits; - rans.low = (rans.low >> prob_bits) | ((rans.high & mask) << (32 - prob_bits)); - rans.high >>= prob_bits; - - // rans *= freq; - uint h1, l1, h2, l2; - umulExtended(rans.low, freq, h1, l1); - umulExtended(rans.high, freq, h2, l2); - rans.low = l1; - rans.high = l2 + h1; - - // rans += recovered_lowbits; - uint carry; - rans.low = uaddCarry(rans.low, recovered_lowbits, carry); - rans.high += carry; - + rans = freq * (rans >> prob_bits) + (rans & mask) - start; + // renormalize - if (rans.high == 0 && rans.low < RANS64_L) { - rans.high = rans.low; - rans.low = data_SSBO[offset++]; + while (rans < RANS_BYTE_L) { + rans = (rans << 8) | get_rans_byte(offset++); } } @@ -173,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; @@ -232,8 +221,8 @@ void main() const uint sign_bias = sign_bias_per_model[model_num]; // Initialize rANS decoder. - uint offset = streams[stream_num].src_offset >> 2; - myuint64 rans = RansDecInit(offset); + uint offset = streams[stream_num].src_offset; + uint rans = RansDecInit(offset); 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); @@ -252,7 +241,7 @@ void main() bool sign = false; if (bottom_bits >= sign_bias) { bottom_bits -= sign_bias; - rans.low -= sign_bias; + rans -= sign_bias; sign = true; } int k = int(cum2sym(bottom_bits, model_num)); // Can go out-of-bounds; that will return zero. @@ -266,19 +255,17 @@ void main() if (sign) { k = -k; } -#if 0 - if (coeff_num == 0) { - //imageStore(coeff_tex, ivec2((block_row * 40 + block_idx) * 8 + subblock_idx, 0), ivec4(k, 0,0,0)); - imageStore(coeff_tex, ivec2((block_row * 40 + block_idx) * 8 + subblock_idx, 0), ivec4(rans.low, 0,0,0)); - imageStore(coeff2_tex, ivec2((block_row * 40 + block_idx) * 8 + subblock_idx, 0), ivec4(rans.high, 0,0,0)); - } -#endif if (coeff_num == 0) { k += last_k; 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