Advertisement
Guest User

Untitled

a guest
Sep 15th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #version 430 core
  2.  
  3. layout (local_size_x = 6, local_size_y = 6) in;
  4.  
  5. layout (binding = 0, rgba8) writeonly uniform image2D destImg;
  6.  
  7. layout (binding = 0) buffer AstcSource {
  8.     uint astc[];
  9. };
  10.  
  11. const uvec2 block_size = gl_WorkGroupSize.xy;
  12.  
  13. const uint block_width  = block_size.x;
  14. const uint block_height = block_size.y;
  15.  
  16. void assert(bool a) {}
  17.  
  18. uint bit_pop_cnt(uint number) {
  19.     uint counter;
  20.     for (counter = 0; number != 0; counter++) {
  21.         number &= number - 1;
  22.     }
  23.     return counter;
  24. }
  25.  
  26. bool read_bit(uint stream) {
  27.     uint word = astc[stream / 32];
  28.     return (word & (stream % 32)) != 0;
  29. }
  30.  
  31. uint read_astc_bits(inout uint stream, uint len) {
  32.     uint position = stream;
  33.     uint ret_value = 0;
  34.     for (uint i = position; i < position + len; i++) {
  35.         if (read_bit(i)) {
  36.             ret_value |= 1 << (i - position);
  37.         }
  38.     }
  39.     stream += len;
  40.     return ret_value;
  41. }
  42.  
  43. void write_bits(uint size, uint value, inout uint bytes[4], inout uint cursor) {
  44.     uint position = cursor;
  45.     for (uint i = position; i < position + size; i++) {
  46.         if ((value & (i - position)) != 0) {
  47.             bytes[i / 32] |= 1 << (i % 32);
  48.         }
  49.     }
  50.     cursor += size;
  51. }
  52.  
  53. const uint INTEGER_ENCODING_JUST_BITS = 0u;
  54. const uint INTEGER_ENCODING_QUINT     = 1u;
  55. const uint INTEGER_ENCODING_TRIT      = 2u;
  56.  
  57. struct IntegerEncoding {
  58.     uint encoding;
  59.     uint number_bits;
  60.     uint bit_value;
  61.     uint trit_value;
  62.     uint quint_value;
  63. };
  64.  
  65. IntegerEncoding create_integer_encoding(uint max_val) {
  66.     IntegerEncoding encoding;
  67.     encoding.bit_value = 0;
  68.     encoding.trit_value = 0;
  69.     encoding.quint_value = 0;
  70.  
  71.     while (max_val > 0) {
  72.         uint check = max_val + 1;
  73.  
  74.         //is max_val a power of two?
  75.         if ((check & (check - 1)) == 0) {
  76.             encoding.encoding = INTEGER_ENCODING_JUST_BITS;
  77.             encoding.number_bits = bit_pop_cnt(max_val);
  78.             return encoding;
  79.         //is max_val of the type 3*2^n - 1?
  80.         } else if ((check % 3 == 0) && ((check / 3) & ((check / 3) - 1)) == 0) {
  81.             encoding.encoding = INTEGER_ENCODING_TRIT;
  82.             encoding.number_bits = bit_pop_cnt(check / 3 - 1);
  83.             return encoding;
  84.         //is max_val of the type 5*2^n - 1?
  85.         } else if ((check % 5 == 0) && (((check / 5) & (check / 5) - 1)) == 0) {
  86.             encoding.encoding = INTEGER_ENCODING_QUINT;
  87.             encoding.number_bits = bit_pop_cnt(check / 5 - 1);
  88.             return encoding;
  89.         }
  90.         //apparently it can't be represented with a bounded integer sequence; just iterate
  91.         max_val--;
  92.     }
  93.     encoding.encoding = INTEGER_ENCODING_JUST_BITS;
  94.     encoding.number_bits = 0;
  95.     return encoding;
  96. }
  97.  
  98. uint get_bit_length(IntegerEncoding encoding, uint number_vals) {
  99.     uint total_bits = encoding.number_bits * number_vals;
  100.     if (encoding.encoding == INTEGER_ENCODING_TRIT) {
  101.         total_bits += (number_vals * 8 + 4) / 5;
  102.     } else if (encoding.encoding == INTEGER_ENCODING_QUINT) {
  103.         total_bits += (number_vals * 7 + 2) / 3;
  104.     }
  105.     return total_bits;
  106. }
  107.  
  108. struct TexelWeightParams {
  109.     uint width;
  110.     uint height;
  111.     bool dual_plane;
  112.     uint max_weight;
  113.     bool error;
  114.     bool void_extent_ldr;
  115.     bool void_extent_hdr;
  116. };
  117.  
  118. uint get_packed_bit_size(TexelWeightParams params) {
  119.     //how many indices do we have?
  120.     uint indices = params.width * params.height;
  121.     if (params.dual_plane) {
  122.         indices *= 2;
  123.     }
  124.     IntegerEncoding encoding = create_integer_encoding(params.max_weight);
  125.     return get_bit_length(encoding, indices);
  126. }
  127.  
  128. TexelWeightParams decode_block_info(inout uint stream) {
  129.     TexelWeightParams params;
  130.  
  131.     //read the entire block mode all at once
  132.     uint mode_bits = read_astc_bits(stream, 11);
  133.  
  134.     //does this match the void extent block mode?
  135.     if ((mode_bits & 0x01ff) == 0x1fc) {
  136.         if ((mode_bits & 0x200) != 0) {
  137.             params.void_extent_hdr = true;
  138.         } else {
  139.             params.void_extent_ldr = true;
  140.         }
  141.         //next two bits must be one
  142.         if (((mode_bits & 0x400) == 0) || (read_astc_bits(stream, 1) == 0)) {
  143.             params.error = true;
  144.         }
  145.         return params;
  146.     }
  147.  
  148.     //first check if the last four bits are zero
  149.     if ((mode_bits & 0xf) == 0) {
  150.         params.error = true;
  151.         return params;
  152.     }
  153.  
  154.     //if the last two bits are zero, then if bits [6-8] are all ones, this is also reserved
  155.     if ((mode_bits & 0x3) == 0 && (mode_bits & 0x1C0) == 0x1C0) {
  156.         params.error = true;
  157.         return params;
  158.     }
  159.  
  160.     //otherwise, there is no error... figure out the layout of the block mode
  161.     //layout is determined by a number between 0 and 9 corresponding to table C.2.8 of the ASTC spec
  162.     uint layaout = 0;
  163.  
  164.     if ((mode_bits & 0x1) != 0 || (mode_bits & 0x2) != 0) {
  165.         //layout is in [0-4]
  166.         if ((mode_bits & 0x8) != 0) {
  167.             //layout is in [2-4]
  168.             if ((mode_bits & 0x4) != 0) {
  169.                 // layout is in [3-4]
  170.                 if ((mode_bits & 0x100) != 0) {
  171.                     layaout = 4;
  172.                 } else {
  173.                     layaout = 3;
  174.                 }
  175.             } else {
  176.                 layaout = 2;
  177.             }
  178.         } else {
  179.             //layout is in [0-1]
  180.             if ((mode_bits & 0x4) != 0) {
  181.                 layaout = 1;
  182.             } else {
  183.                 layaout = 0;
  184.             }
  185.         }
  186.     } else {
  187.         if ((mode_bits & 0x100) != 0) {
  188.             //layout is in [7-9]
  189.             if ((mode_bits & 0x80) != 0) {
  190.                 // layout is in [7-8]
  191.                 assert((mode_bits & 0x40) == 0);
  192.  
  193.                 if ((mode_bits & 0x20) != 0) {
  194.                     layaout = 8;
  195.                 } else {
  196.                     layaout = 7;
  197.                 }
  198.             } else {
  199.                 layaout = 9;
  200.             }
  201.         } else {
  202.             // layout is in [5-6]
  203.             if ((mode_bits & 0x80) != 0) {
  204.                 layaout = 6;
  205.             } else {
  206.                 layaout = 5;
  207.             }
  208.         }
  209.     }
  210.  
  211.     assert(layaout < 10);
  212.  
  213.     //determine r
  214.     uint r = (mode_bits >> 4) & 1;
  215.     if (layaout < 5) {
  216.         r |= (mode_bits & 0x3) << 1;
  217.     } else {
  218.         r |= (mode_bits & 0xc) >> 1;
  219.     }
  220.  
  221.     assert(2 <= r && r <= 7);
  222.  
  223.     uint a, b;
  224.     switch (layaout) {
  225.         case 0:
  226.             a = (mode_bits >> 5) & 0x3;
  227.             b = (mode_bits >> 7) & 0x3;
  228.             params.width  = b + 4;
  229.             params.height = a + 2;
  230.             break;
  231.         case 1:
  232.             a = (mode_bits >> 5) & 0x3;
  233.             b = (mode_bits >> 7) & 0x3;
  234.             params.width  = b + 8;
  235.             params.height = a + 2;
  236.             break;
  237.         case 2:
  238.             a = (mode_bits >> 5) & 0x3;
  239.             b = (mode_bits >> 7) & 0x3;
  240.             params.width  = a + 2;
  241.             params.height = b + 8;
  242.             break;
  243.         case 3:
  244.             a = (mode_bits >> 5) & 0x3;
  245.             b = (mode_bits >> 7) & 0x1;
  246.             params.width  = a + 2;
  247.             params.height = b + 6;
  248.             break;
  249.         case 4:
  250.             a = (mode_bits >> 5) & 0x3;
  251.             b = (mode_bits >> 7) & 0x1;
  252.             params.width  = b + 2;
  253.             params.height = a + 2;
  254.             break;
  255.         case 5:
  256.             a = (mode_bits >> 5) & 0x3;
  257.             params.width  = 12;
  258.             params.height = a + 2;
  259.             break;
  260.         case 6:
  261.             a = (mode_bits >> 5) & 0x3;
  262.             params.width  = a + 2;
  263.             params.height = 12;
  264.             break;
  265.         case 7:
  266.             params.width  = 6;
  267.             params.height = 10;
  268.             break;
  269.         case 8:
  270.             params.width  = 10;
  271.             params.height = 6;
  272.             break;
  273.         case 9:
  274.             a = (mode_bits >> 5) & 0x3;
  275.             b = (mode_bits >> 9) & 0x3;
  276.             params.width  = a + 6;
  277.             params.height = b + 6;
  278.             break;
  279.         default:
  280.             params.error = true;
  281.             break;
  282.     }
  283.     bool d = ((layaout != 9) && (mode_bits & 0x400) != 0);
  284.     bool h = (layaout != 9) && ((mode_bits & 0x200) != 0);
  285.  
  286.     if (h) {
  287.         const int max_weights[] = { 9, 11, 15, 19, 23, 31 };
  288.         params.max_weight = max_weights[r - 2];
  289.     } else {
  290.         const int max_weights[] = { 1, 2, 3, 4, 5, 7 };
  291.         params.max_weight = max_weights[r - 2];
  292.     }
  293.     params.dual_plane = d;
  294.  
  295.     return params;
  296. }
  297.  
  298. bool decompress_block(uint input_offset) {
  299.     uint stream = input_offset * 8;
  300.     TexelWeightParams params = decode_block_info(stream);
  301.  
  302.     assert(!params.error);
  303.  
  304.     if (params.void_extent_ldr) {
  305.         fill_void_extent_ldr(stream);
  306.         return true;
  307.     }
  308.  
  309.     assert(!params.void_extent_hdr);
  310.     assert(params.width > block_width);
  311.     assert(params.height > block_height);
  312.  
  313.     //read num partitions
  314.     uint number_partitions = read_astc_bits(stream, 2) + 1;
  315.     assert(number_partitions <= 4);
  316.  
  317.     assert(!(number_partitions == 4 && params.dual_plane));
  318.  
  319.     uint partition_index;
  320.     uint color_endpoint_mode[] = { 0, 0, 0, 0 };
  321.  
  322.     //read extra config data
  323.     uint base_color_endpoint_mode = 0;
  324.  
  325.     if (number_partitions == 1) {
  326.         color_endpoint_mode[0] = read_astc_bits(stream, 4);
  327.         partition_index = 0;
  328.     } else {
  329.         partition_index = read_astc_bits(stream, 10);
  330.         base_color_endpoint_mode = read_astc_bits(stream, 6);
  331.     }
  332.  
  333.     uint base_mode = base_color_endpoint_mode & 3;
  334.  
  335.     //remaining bits are color endpoint data...
  336.     uint number_weight_bits = get_packed_bit_size(params);
  337.     uint remaining_bits = 128 - number_weight_bits - stream;
  338.  
  339.     uint extra_color_endpoint_mode_bits = 0;
  340.  
  341.     if (base_mode != 0) {
  342.         switch (number_partitions) {
  343.             case 2:  extra_color_endpoint_mode_bits += 2; break;
  344.             case 3:  extra_color_endpoint_mode_bits += 5; break;
  345.             case 4:  extra_color_endpoint_mode_bits += 8; break;
  346.             default: assert(false); break;
  347.         }
  348.     }
  349.  
  350.     remaining_bits -= extra_color_endpoint_mode_bits;
  351.  
  352.     //do we have a dual plane situation?
  353.     uint plane_selector_bits = 0;
  354.     if (params.dual_plane) {
  355.         plane_selector_bits = 2;
  356.     }
  357.     remaining_bits -= plane_selector_bits;
  358.  
  359.     //read color data
  360.     uint color_data_bits = remaining_bits;
  361.  
  362.     //color endpoint
  363.     uint cep[4];
  364.     uint cep_cursor = 0;
  365.  
  366.     while (remaining_bits > 0) {
  367.         uint number_bits = min(remaining_bits, 8);
  368.         uint bits = read_astc_bits(stream, number_bits);
  369.         write_bits(bits, number_bits, cep, cep_cursor);
  370.         remaining_bits -= 8;
  371.     }
  372.  
  373.     //read the plane selection bits
  374.     uint plane_indices = read_astc_bits(stream, plane_selector_bits);
  375.  
  376.     //read the rest of the CEM
  377.     if (base_mode != 0) {
  378.         uint extra_color_endpoint_mode = read_astc_bits(stream, extra_color_endpoint_mode_bits);
  379.         uint temp_color_endpoint_mode = (extra_color_endpoint_mode << 6) | base_color_endpoint_mode;
  380.         temp_color_endpoint_mode >>= 2;
  381.  
  382.         bool c[] = { false, false, false, false };
  383.         for (uint i = 0; i < number_partitions; i++) {
  384.             c[i] = (temp_color_endpoint_mode & 1) != 0;
  385.             temp_color_endpoint_mode >>= 1;
  386.         }
  387.  
  388.         uint m[] = { 0, 0, 0, 0 };
  389.         for (uint i = 0; i < number_partitions; i++) {
  390.             m[i] = uint(temp_color_endpoint_mode & 3);
  391.             temp_color_endpoint_mode >>= 2;
  392.             assert(m[i] <= 3);
  393.         }
  394.  
  395.         for (uint i = 0; i < number_partitions; i++) {
  396.             color_endpoint_mode[i] = base_mode;
  397.             if (!(c[i])) color_endpoint_mode[i]--;
  398.             color_endpoint_mode[i] <<= 2;
  399.             color_endpoint_mode[i] |= m[i];
  400.         }
  401.     } else if (number_partitions > 1) {
  402.         uint temp_color_endpoint_mode = base_color_endpoint_mode >> 2;
  403.         for (uint i = 0; i < number_partitions; i++) {
  404.             color_endpoint_mode[i] = temp_color_endpoint_mode;
  405.         }
  406.     }
  407.  
  408.     //make sure everything is up till here is name
  409.     for (uint i = 0; i < number_partitions; i++) {
  410.         assert(color_endpoint_mode[i] < 16);
  411.     }
  412.     assert(stream + get_packed_bit_size(params) == 128);
  413.  
  414.     //continue in line 278 ASTCDecoder.cs
  415.     //...
  416. }
  417.  
  418. void decode() {
  419.     uint j = gl_WorkGroupID.x * block_size.x;
  420.     uint i = gl_WorkGroupID.y * block_size.y;
  421.  
  422.    
  423. }
  424.  
  425. void main() {
  426.     uvec2 pixel_coord = gl_WorkGroupID.xy * gl_WorkGroupSize.xy + gl_LocalInvocationID.xy;
  427.  
  428.     vec2 colors = vec2(gl_LocalInvocationID.xy) / vec2(gl_WorkGroupSize.xy);
  429.  
  430.     vec4 final_color = vec4(colors, 0.0, 1.0);
  431.  
  432.     imageStore(destImg, ivec2(pixel_coord), final_color);
  433. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement