Advertisement
Guest User

Untitled

a guest
Jul 5th, 2012
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.45 KB | None | 0 0
  1. #version 420 compatibility
  2.  
  3. layout(r32ui) restrict  readonly  uniform uimage2D tex_comp;
  4. layout(r32ui) restrict  readonly  uniform uimage2D tex_offset;
  5. layout(r16ui) restrict  writeonly  uniform uimage2D tex_decomp;
  6.  
  7. struct  STREAM_DATA
  8. {
  9.     uint    data_buffer;
  10.     uint    patch_index_int;                           
  11.     uint    bits_left;                                 
  12. };
  13.  
  14. STREAM_DATA     s_stream_data;
  15.  
  16. uint s_get_bits_en(in  uint bit_num );                 
  17. uint s_clz();                                          
  18. uint s_texel_fetch_linearly(in  uint linear_index );   
  19. void set_offset(in uint patch_offset);                 
  20. int  get_residual(uint op_k,uint qbpp,uint max_q);     
  21.  
  22. const uint tex_comp_width = uint(1024);                 //the width of tex_comp
  23. const uint glimit = uint(32);                       //
  24. const uint patch_size = uint(8);                    //the size of the patch
  25. const uint int_length = uint(32);                   //
  26.  
  27. void main()
  28. {
  29.     ivec2   itex_coord      = ivec2(gl_Vertex.xz);                                 
  30.     ivec2   patch_base      = ivec2(itex_coord*patch_size);                        
  31.  
  32.     uint    patch_offset    = imageLoad(tex_offset, itex_coord).r;                  //locate the compressed patch in the tex_comp
  33.  
  34.     set_offset(patch_offset);
  35.  
  36.     uint first_pix  = s_get_bits_en(uint(16));                                     
  37.     uint op_k       = s_get_bits_en(uint(4));
  38.     uint qbpp       = s_get_bits_en(uint(4));
  39.     uint max_q      = glimit-qbpp-uint(1);
  40.  
  41.     uint xLength = patch_size;
  42.     uint yLength = patch_size;
  43.  
  44.     int h1 = int(first_pix);
  45.     imageStore(tex_decomp,ivec2(0,0) + patch_base ,uvec4(first_pix,0,0,0));
  46.  
  47.     int h2;
  48.  
  49.  
  50.     /******************************************************************************
  51.     the code is a little long, but the essence is below: read, decopress, and write.
  52.     *******************************************************************************/
  53.     for( int i=1; i< xLength; i++ )
  54.     {
  55.         h2 = h1 + get_residual(op_k,qbpp,max_q);
  56.         imageStore(tex_decomp,ivec2(i,0) + patch_base ,uvec4(h2,0,0,0));
  57.         h1 = h2;
  58.     }
  59.  
  60.     for(  int j=1; j< yLength; j++  )
  61.     {
  62.         for( int i=0; i<xLength; i++ )
  63.         {
  64.             h2 = h1 + get_residual(op_k,qbpp,max_q);
  65.             imageStore(tex_decomp,ivec2(i,j) + patch_base ,uvec4(h2,0,0,0));
  66.             h1 = h2;
  67.         }
  68.     }
  69. }
  70.  
  71. //get bit_num bits from the compressed patch
  72. uint s_get_bits_en(in  uint bit_num )
  73. {
  74.     uint value = uint(0);
  75.  
  76.     if( s_stream_data.bits_left>= bit_num )
  77.     {
  78.         value = s_stream_data.data_buffer>>( int_length-bit_num );
  79.         s_stream_data.data_buffer = s_stream_data.data_buffer<<bit_num;
  80.         s_stream_data.bits_left -= bit_num;
  81.     }
  82.  
  83.     else
  84.     {
  85.         value = s_stream_data.data_buffer>>( int_length-bit_num );
  86.  
  87.         uint still_need_copy = bit_num - s_stream_data.bits_left;
  88.  
  89.         s_stream_data.data_buffer = s_texel_fetch_linearly(s_stream_data.patch_index_int);
  90.         s_stream_data.patch_index_int += uint(1);
  91.         s_stream_data.bits_left = int_length;
  92.  
  93.         value += s_stream_data.data_buffer>>( int_length-still_need_copy );
  94.         s_stream_data.data_buffer = s_stream_data.data_buffer<<still_need_copy;
  95.         if( 32 == still_need_copy )
  96.             s_stream_data.data_buffer = 0;
  97.         s_stream_data.bits_left -= still_need_copy;
  98.     }
  99.  
  100.     return value;
  101. }
  102.  
  103. //count leading zero
  104. uint s_clz()
  105. {
  106.     uint value = uint(0);
  107.  
  108.     if( s_stream_data.bits_left == int_length )                            
  109.         value = s_stream_data.data_buffer;
  110.  
  111.     else                                                                   
  112.     {
  113.         value = s_stream_data.data_buffer;                                 
  114.         uint temp = s_texel_fetch_linearly(s_stream_data.patch_index_int); 
  115.         value += temp>>( s_stream_data.bits_left );                        
  116.     }
  117.  
  118.     return int_length - findMSB(value) - uint(1);
  119. }
  120.  
  121.  
  122. uint s_texel_fetch_linearly(in  uint linear_index )
  123. {
  124.     uint    cody = linear_index/tex_comp_width;
  125.     uint    codx = linear_index - tex_comp_width*cody;                     
  126.     uint    val  = imageLoad(tex_comp,ivec2(codx,cody)).x;
  127.  
  128.     return val;
  129. }
  130.  
  131. //set the position of the index for reading
  132. void set_offset(in uint patch_offset)
  133. {
  134.     s_stream_data.patch_index_int = patch_offset/int_length;                           
  135.     uint    index_inside  = patch_offset - s_stream_data.patch_index_int*int_length;   
  136.     s_stream_data.bits_left = uint(0);
  137.     s_stream_data.data_buffer = uint(0);
  138.     s_get_bits_en(index_inside);                                                       
  139. }
  140.  
  141. int get_residual(uint op_k,uint qbpp,uint max_q)
  142. {
  143.     uint q = s_clz();                                          
  144.  
  145.     uint mm = ( q - max_q )>>uint(31);                         
  146.     uint nn = uint(1)-mm;
  147.  
  148.     uint next_bits = op_k*mm + qbpp*nn;
  149.     uint r = s_get_bits_en(next_bits+uint(1)+q);               
  150.     r &= ~(uint(1)<<(next_bits));                              
  151.  
  152.     if( 0==mm )
  153.         r+=1;                                                  
  154.  
  155.     q = (q<<op_k)*mm;
  156.  
  157.     uint value = q+r;
  158.  
  159.     uint parity = value & uint(1);                             
  160.  
  161.     int even = int(value)/2;
  162.     int odd  = -(int(value)+1)/2;
  163.     int residual_true = odd*int(parity) + even*(1-int(parity));
  164.     return residual_true;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement