Advertisement
Guest User

BC1V float CppSPMD kernel

a guest
Apr 28th, 2020
419
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.08 KB | None | 0 0
  1. // bc1v_kernel.h
  2.  
  3. struct CPPSPMD_MAKE_NAME(bc1v_kernel) : CPPSPMD::spmd_kernel
  4. {
  5.     struct bc1_block
  6.     {
  7.         uint16_t m_lo;
  8.         uint16_t m_hi;
  9.         uint32_t m_sels;
  10.     };
  11.  
  12.     struct vvec3F { vfloat c[3]; };
  13.     struct vcolor3 { vfloat c[3]; };
  14.  
  15.     static CPPSPMD_FORCE_INLINE vfloat squarevf(const vfloat &a)
  16.     {
  17.         return a * a;
  18.     }
  19.  
  20.     static CPPSPMD_FORCE_INLINE vfloat to_5(vfloat v)
  21.     {
  22.         vfloat t = fma(v, 31.0 * (1.0f/256.0f), 128.0f * (1.0f/256.0f));
  23.         return floor( fma(t, 1.0f/256.0f, t) );
  24.     }
  25.  
  26.     static CPPSPMD_FORCE_INLINE vfloat to_6(vfloat v)
  27.     {
  28.         vfloat t = fma(v, 63.0 * (1.0f/256.0f), 128.0f * (1.0f/256.0f));
  29.         return floor( fma(t, 1.0f/256.0f, t) );
  30.     }
  31.  
  32.     static void global_init()
  33.     {
  34.     }
  35.  
  36.     CPPSPMD_FORCE_INLINE void bc1_get_block_colors4(vfloat block_r[4], vfloat block_g[4], vfloat block_b[4], const vfloat &lr, const vfloat &lg, const vfloat &lb, const vfloat &hr, const vfloat &hg, const vfloat &hb)
  37.     {
  38.         store_all(block_r[0], fma(lr, 8.0f, floor(lr * .25f)));
  39.         store_all(block_g[0], fma(lg, 4.0f, floor(lg * .0625f)));
  40.         store_all(block_b[0], fma(lb, 8.0f, floor(lb * .25f)));
  41.  
  42.         store_all(block_r[3], fma(hr, 8.0f, floor(hr * .25f)));
  43.         store_all(block_g[3], fma(hg, 4.0f, floor(hg * .0625f)));
  44.         store_all(block_b[3], fma(hb, 8.0f, floor(hb * .25f)));
  45.                
  46.         vfloat delta_r = block_r[3] - block_r[0];
  47.         vfloat delta_g = block_g[3] - block_g[0];
  48.         vfloat delta_b = block_b[3] - block_b[0];
  49.  
  50.         store_all( block_r[1], floor(fma(delta_r, 1.0f/3.0f, block_r[0])) );
  51.         store_all( block_g[1], floor(fma(delta_g, 1.0f/3.0f, block_g[0])) );
  52.         store_all( block_b[1], floor(fma(delta_b, 1.0f/3.0f, block_b[0])) );
  53.  
  54.         store_all( block_r[2], floor(fma(delta_r, 2.0f/3.0f, block_r[0])) );
  55.         store_all( block_g[2], floor(fma(delta_g, 2.0f/3.0f, block_g[0])) );
  56.         store_all( block_b[2], floor(fma(delta_b, 2.0f/3.0f, block_b[0])) );
  57.     }
  58.        
  59.     CPPSPMD_FORCE_INLINE void bc1_find_sels4_noerr(const vcolor3* pSrc_pixels, const vfloat &lr, const vfloat &lg, const vfloat &lb, const vfloat &hr, const vfloat &hg, const vfloat &hb, vfloat sels[16])
  60.     {
  61.         vfloat block_r[4], block_g[4], block_b[4];
  62.         bc1_get_block_colors4(block_r, block_g, block_b, lr, lg, lb, hr, hg, hb);
  63.                
  64.         vfloat ar = block_r[3] - block_r[0], ag = block_g[3] - block_g[0], ab = block_b[3] - block_b[0];
  65.  
  66.         vfloat dots[4];
  67.         for (uint32_t i = 0; i < 4; i++)
  68.             store_all(dots[i], block_r[i] * ar + block_g[i] * ag + block_b[i] * ab);
  69.  
  70.         vfloat t0 = dots[0] + dots[1], t1 = dots[1] + dots[2], t2 = dots[2] + dots[3];
  71.  
  72.         vfloat ar_scaled = ar * 2.0f, ag_scaled = ag * 2.0f, ab_scaled = ab * 2.0f;
  73.        
  74.         for (uint32_t i = 0; i < 16; i += 4)
  75.         {
  76.             const vfloat d0 = pSrc_pixels[i+0].c[0] * ar_scaled + pSrc_pixels[i+0].c[1] * ag_scaled + pSrc_pixels[i+0].c[2] * ab_scaled;
  77.             const vfloat d1 = pSrc_pixels[i+1].c[0] * ar_scaled + pSrc_pixels[i+1].c[1] * ag_scaled + pSrc_pixels[i+1].c[2] * ab_scaled;
  78.             const vfloat d2 = pSrc_pixels[i+2].c[0] * ar_scaled + pSrc_pixels[i+2].c[1] * ag_scaled + pSrc_pixels[i+2].c[2] * ab_scaled;
  79.             const vfloat d3 = pSrc_pixels[i+3].c[0] * ar_scaled + pSrc_pixels[i+3].c[1] * ag_scaled + pSrc_pixels[i+3].c[2] * ab_scaled;
  80.  
  81.             vfloat sel0 = (vfloat)(d0 > t0) + (vfloat)(d0 >= t1) + (vfloat)(d0 >= t2);
  82.             vfloat sel1 = (vfloat)(d1 > t0) + (vfloat)(d1 >= t1) + (vfloat)(d1 >= t2);
  83.             vfloat sel2 = (vfloat)(d2 > t0) + (vfloat)(d2 >= t1) + (vfloat)(d2 >= t2);
  84.             vfloat sel3 = (vfloat)(d3 > t0) + (vfloat)(d3 >= t1) + (vfloat)(d3 >= t2);
  85.  
  86.             store(sels[i+0], sel0);
  87.             store(sels[i+1], sel1);
  88.             store(sels[i+2], sel2);
  89.             store(sels[i+3], sel3);
  90.         }
  91.     }
  92.  
  93.     CPPSPMD_FORCE_INLINE vfloat select4(const vfloat x[4], const vfloat &sel)
  94.     {
  95.         return vfloat(
  96.             spmd_ternaryf(sel == 0.0f, x[0], spmd_ternaryf(sel == 1.0f, x[1], spmd_ternaryf(sel == 2.0f, x[2], x[3] ) ) )
  97.                 );
  98.     }
  99.  
  100.     CPPSPMD_FORCE_INLINE vbool compute_least_squares_endpoints4_rgb(const vcolor3* pColors, const vfloat* pSelectors, vvec3F* pXl, vvec3F* pXh, const vfloat &total_r, const vfloat &total_g, const vfloat &total_b)
  101.     {
  102.         vfloat q00_r = 0.0f, q00_g = 0.0f, q00_b = 0.0f;
  103.         vfloat z00 = 0.0f, z10 = 0.0f, z11 = 0.0f;
  104.         for (uint32_t i = 0; i < 16; i++)
  105.         {
  106.             const vfloat r = pColors[i].c[0], g = pColors[i].c[1], b = pColors[i].c[2];
  107.             const vfloat sel = pSelectors[i];
  108.            
  109.             const vfloat w = sel * (1.0f/3.0f);
  110.             const vfloat one_minus_w = 1.0f - w;
  111.                        
  112.             store_all(z00, z00 + w * w);
  113.             store_all(z10, z10 + one_minus_w * w);
  114.             store_all(z11, z11 + one_minus_w * one_minus_w);
  115.  
  116.             store_all(q00_r, q00_r + w * r);
  117.             store_all(q00_g, q00_g + w * g);
  118.             store_all(q00_b, q00_b + w * b);
  119.         }
  120.  
  121.         vfloat q10_r = total_r - q00_r;
  122.         vfloat q10_g = total_g - q00_g;
  123.         vfloat q10_b = total_b - q00_b;
  124.  
  125.         vfloat z01 = z10;
  126.  
  127.         vfloat det = z00 * z11 - z01 * z10;
  128.  
  129.         vbool valid_mask = (abs(det) >= 1e-4f);
  130.        
  131.         vfloat det_fixed = spmd_ternaryf(valid_mask, det, 1e+10f);
  132.  
  133.         vfloat det_scaled = (1.0f / 255.0f) / det_fixed;
  134.  
  135.         vfloat iz00 = z11 * det_scaled;
  136.         vfloat iz01 = -z01 * det_scaled;
  137.         vfloat iz10 = -z10 * det_scaled;
  138.         vfloat iz11 = z00 * det_scaled;
  139.  
  140.         store_all(pXl->c[0], iz00 * q00_r + iz01 * q10_r);
  141.         store_all(pXh->c[0], iz10 * q00_r + iz11 * q10_r);
  142.  
  143.         store_all(pXl->c[1], iz00 * q00_g + iz01 * q10_g);
  144.         store_all(pXh->c[1], iz10 * q00_g + iz11 * q10_g);
  145.  
  146.         store_all(pXl->c[2], iz00 * q00_b + iz01 * q10_b);
  147.         store_all(pXh->c[2], iz10 * q00_b + iz11 * q10_b);
  148.  
  149.         return valid_mask;
  150.     }
  151.  
  152.     CPPSPMD_FORCE_INLINE void precise_round_565(const vvec3F &xl, const vvec3F &xh,
  153.         vfloat &trial_lr, vfloat &trial_lg, vfloat &trial_lb,
  154.         vfloat &trial_hr, vfloat &trial_hg, vfloat &trial_hb)
  155.     {
  156.         // FIXME: Use precise BC1 rounding.
  157.         store_all(trial_lr, clamp(round_nearest(xl.c[0] * 31.0f), 0.0f, 31.0f));
  158.         store_all(trial_lg, clamp(round_nearest(xl.c[1] * 63.0f), 0.0f, 63.0f));
  159.         store_all(trial_lb, clamp(round_nearest(xl.c[2] * 31.0f), 0.0f, 31.0f));
  160.  
  161.         store_all(trial_hr, clamp(round_nearest(xh.c[0] * 31.0f), 0.0f, 31.0f));
  162.         store_all(trial_hg, clamp(round_nearest(xh.c[1] * 63.0f), 0.0f, 63.0f));
  163.         store_all(trial_hb, clamp(round_nearest(xh.c[2] * 31.0f), 0.0f, 31.0f));
  164.     }
  165.        
  166.     static CPPSPMD_FORCE_INLINE vfloat fix_sels(vfloat sels, float m)
  167.     {
  168.         return spmd_ternaryf(sels == 0.0f, 0.0f, spmd_ternaryf(sels == 1.0f, 2.0f * m, spmd_ternaryf(sels == 2.0f, 3.0f * m, m ) ) );
  169.     }
  170.  
  171.     CPPSPMD_FORCE_INLINE void bc1_encode4(lint indices, bc1_block *pDst_blocks, const vfloat lr, const vfloat lg, const vfloat lb, const vfloat hr, const vfloat hg, const vfloat hb, vfloat sels[16], int pcount)
  172.     {
  173.         vfloat lc16i = lb + (lg * 32.0f) + (lr * 2048.0f);
  174.         vfloat hc16i = hb + (hg * 32.0f) + (hr * 2048.0f);
  175.  
  176.         SPMD_SIMPLE_IF(lc16i == hc16i)
  177.         {
  178.             SPMD_SIMPLE_IF(hc16i > 0.0f)
  179.             {
  180.                 store(hc16i, hc16i - 1.0f);
  181.             }
  182.             SPMD_SIMPLE_ELSE(hc16i > 0.0f)
  183.             {
  184.                 store(hc16i, 0.0f);
  185.                 store(lc16i, 1.0f);
  186.                 for (uint32_t i = 0; i < 16; i++)
  187.                     store(sels[i], 3.0f);
  188.             }
  189.             SPMD_SIMPLE_END_IF
  190.         }
  191.         SPMD_SIMPLE_ELSE(lc16i == hc16i)
  192.         {
  193.             SPMD_SIMPLE_IF(lc16i < hc16i)
  194.             {
  195.                 swap(lc16i, hc16i);
  196.  
  197.                 for (uint32_t i = 0; i < 16; i++)
  198.                     store(sels[i], 3.0f - sels[i]);
  199.             }
  200.             SPMD_SIMPLE_END_IF
  201.         }
  202.         SPMD_SIMPLE_END_IF
  203.                    
  204.         vfloat sels0 = fix_sels(sels[0], 1.0f) + fix_sels(sels[1], 4.0f) + fix_sels(sels[2], 16.0f) + fix_sels(sels[3], 64.0f) +
  205.             fix_sels(sels[4], 256.0f) + fix_sels(sels[5], 1024.0f) + fix_sels(sels[6], 4096.0f) + fix_sels(sels[7], 16384.0f);
  206.  
  207.         vfloat sels1 = fix_sels(sels[8], 1.0f) + fix_sels(sels[9], 4.0f) + fix_sels(sels[10], 16.0f) + fix_sels(sels[11], 64.0f) +
  208.             fix_sels(sels[12], 256.0f) + fix_sels(sels[13], 1024.0f) + fix_sels(sels[14], 4096.0f) + fix_sels(sels[15], 16384.0f);
  209.                
  210.         vint endpoints = vint(lc16i) | VINT_SHIFT_LEFT(vint(hc16i), 16);
  211.         vint selectors = vint(sels0) | VINT_SHIFT_LEFT(vint(sels1), 16);
  212.  
  213.         //int *pDst_ints = reinterpret_cast<int *>(pDst_blocks);
  214.         //vint vindices(vint(indices) * 2);
  215.         //store(vindices[pDst_ints], endpoints);
  216.         //store((vindices + 1)[pDst_ints],  selectors);
  217.  
  218.         int *pDst_ints = reinterpret_cast<int *>(pDst_blocks) + indices.get_first_value() * 2;
  219.         store_strided(pDst_ints, 2, endpoints);
  220.         store_strided(pDst_ints + 1, 2, selectors);
  221.     }
  222.                
  223.     CPPSPMD_FORCE_INLINE void encode_bc1_pick_initial(const vcolor3 *pSrc_pixels, const vbool grayscale_flag,
  224.             const vfloat min_r, const vfloat min_g, const vfloat min_b, const vfloat max_r, const vfloat max_g, const vfloat max_b,
  225.             const vfloat avg_r, const vfloat avg_g, const vfloat avg_b, const vfloat total_r, const vfloat total_g, const vfloat total_b,
  226.             vfloat &lr, vfloat &lg, vfloat &lb, vfloat &hr, vfloat &hg, vfloat &hb)
  227.     {
  228.         SPMD_SIMPLE_IF(grayscale_flag)
  229.         {          
  230.             // Grayscale blocks are a common enough case to specialize.
  231.             SPMD_SIMPLE_IF( (max_r - min_r) < 2.0f )
  232.             {
  233.                 const vfloat fr = pSrc_pixels[0].c[0];
  234.  
  235.                 vfloat fr5 = to_5(fr);
  236.                 vfloat fr6 = to_6(fr);
  237.  
  238.                 store_all(lr, fr5);
  239.                 store_all(lg, fr6);
  240.                 store_all(lb, fr5);
  241.  
  242.                 store_all(hr, fr5);
  243.                 store_all(hg, fr6);
  244.                 store_all(hb, fr5);
  245.             }
  246.             SPMD_SIMPLE_ELSE( (max_r - min_r) < 2.0f )
  247.             {
  248.                 vfloat min_r5 = to_5(min_r);
  249.                 vfloat min_r6 = to_6(min_r);
  250.  
  251.                 vfloat max_r5 = to_5(max_r);
  252.                 vfloat max_r6 = to_6(max_r);
  253.  
  254.                 store(lr, min_r5);
  255.                 store(lg, min_r6);
  256.                 store(lb, min_r5);
  257.  
  258.                 store(hr, max_r5);
  259.                 store(hg, max_r6);
  260.                 store(hb, max_r5);
  261.             }
  262.             SPMD_SIMPLE_END_IF
  263.         }
  264.         SPMD_SIMPLE_ELSE(grayscale_flag)
  265.         {
  266.             // Select 2 colors along the principle axis. (There must be a faster/simpler way.)
  267.             vfloat icov0 = 0.0f, icov1 = 0.0f, icov2 = 0.0f, icov3 = 0.0f, icov4 = 0.0f, icov5 = 0.0f;
  268.  
  269.             for (uint32_t i = 0; i < 16; i++)
  270.             {
  271.                 vfloat r = pSrc_pixels[i].c[0] - avg_r;
  272.                 vfloat g = pSrc_pixels[i].c[1] - avg_g;
  273.                 vfloat b = pSrc_pixels[i].c[2] - avg_b;
  274.  
  275.                 store_all(icov0, icov0 + r * r);
  276.                 store_all(icov1, icov1 + r * g);
  277.                 store_all(icov2, icov2 + r * b);
  278.                 store_all(icov3, icov3 + g * g);
  279.                 store_all(icov4, icov4 + g * b);
  280.                 store_all(icov5, icov5 + b * b);
  281.             }
  282.            
  283.             vfloat saxis_r = 306.0f, saxis_g = 601.0f, saxis_b = 117.0f;
  284.  
  285.             vfloat xr = max_r - min_r;
  286.             vfloat xg = max_g - min_g;
  287.             vfloat xb = max_b - min_b;
  288.  
  289.             store_all(xr, spmd_ternaryf(icov2 < 0.0f, -xr, xr));
  290.             store_all(xg, spmd_ternaryf(icov4 < 0.0f, -xg, xg));
  291.  
  292.             vfloat cov0 = icov0 * (1.0f/255.0f);
  293.             vfloat cov1 = icov1 * (1.0f/255.0f);
  294.             vfloat cov2 = icov2 * (1.0f/255.0f);
  295.             vfloat cov3 = icov3 * (1.0f/255.0f);
  296.             vfloat cov4 = icov4 * (1.0f/255.0f);
  297.             vfloat cov5 = icov5 * (1.0f/255.0f);
  298.  
  299.             const uint32_t total_power_iters = 4;
  300.             for (uint32_t power_iter = 0; power_iter < total_power_iters; power_iter++)
  301.             {
  302.                 vfloat r = xr * cov0 + xg * cov1 + xb * cov2;
  303.                 vfloat g = xr * cov1 + xg * cov3 + xb * cov4;
  304.                 vfloat b = xr * cov2 + xg * cov4 + xb * cov5;
  305.  
  306.                 store_all(xr, r);
  307.                 store_all(xg, g);
  308.                 store_all(xb, b);
  309.             }
  310.  
  311.             vfloat k = max(max(abs(xr), abs(xg)), abs(xb));
  312.                
  313.             SPMD_SIMPLE_IF(k >= 2.0f)
  314.             {
  315.                 vfloat m = 2048.0f / k;
  316.                 store(saxis_r, xr * m);
  317.                 store(saxis_g, xg * m);
  318.                 store(saxis_b, xb * m);
  319.             }
  320.             SPMD_SIMPLE_END_IF
  321.                                                
  322.             vfloat br = pSrc_pixels[0].c[0], bg = pSrc_pixels[0].c[1], bb = pSrc_pixels[0].c[2];
  323.             vfloat bdot = br * saxis_r + bg * saxis_g + bb * saxis_b;
  324.            
  325.             vfloat lo_dot = bdot, hi_dot = bdot;
  326.             vfloat lo_r(br), lo_g(bg), lo_b(bb), hi_r(br), hi_g(bg), hi_b(bb);
  327.  
  328.             for (uint32_t i = 1; i < 16; i++)
  329.             {
  330.                 vfloat r = pSrc_pixels[i].c[0], g = pSrc_pixels[i].c[1], b = pSrc_pixels[i].c[2];
  331.                 vfloat dot = r * saxis_r + g * saxis_g + b * saxis_b;
  332.                                
  333.                 vbool l = dot < lo_dot;
  334.                 vbool h = dot > hi_dot;
  335.  
  336.                 store_all(lo_dot, spmd_ternaryf(l, dot, lo_dot));
  337.                 store_all(lo_r, spmd_ternaryf(l, r, lo_r));
  338.                 store_all(lo_g, spmd_ternaryf(l, g, lo_g));
  339.                 store_all(lo_b, spmd_ternaryf(l, b, lo_b));
  340.                    
  341.                 store_all(hi_dot, spmd_ternaryf(h, dot, hi_dot));
  342.                 store_all(hi_r, spmd_ternaryf(h, r, hi_r));
  343.                 store_all(hi_g, spmd_ternaryf(h, g, hi_g));
  344.                 store_all(hi_b, spmd_ternaryf(h, b, hi_b));
  345.             }
  346.            
  347.             store(lr, to_5(lo_r));
  348.             store(lg, to_6(lo_g));
  349.             store(lb, to_5(lo_b));
  350.  
  351.             store(hr, to_5(hi_r));
  352.             store(hg, to_6(hi_g));
  353.             store(hb, to_5(hi_b));
  354.         }
  355.         SPMD_SIMPLE_END_IF
  356.     }
  357.  
  358.     CPPSPMD_FORCE_INLINE void encode_bc1_internal(const lint index, bc1_block* pDst_blocks, const vcolor3 *pSrc_pixels, int pcount)
  359.     {
  360.         const vfloat fr = pSrc_pixels[0].c[0], fg = pSrc_pixels[0].c[1], fb = pSrc_pixels[0].c[2];
  361.  
  362.         vfloat total_r(fr), total_g(fg), total_b(fb), min_r(fr), min_g(fg), min_b(fb), max_r(fr), max_g(fg), max_b(fb);
  363.  
  364.         vbool grayscale_flag(true);
  365.         for (uint32_t i = 1; i < 16; i++)
  366.         {
  367.             const vfloat r = pSrc_pixels[i].c[0], g = pSrc_pixels[i].c[1], b = pSrc_pixels[i].c[2];
  368.            
  369.             store_all(grayscale_flag, grayscale_flag && (r == g) && (r == b));
  370.  
  371.             store_all(min_r, min(min_r, r));
  372.             store_all(min_g, min(min_g, g));
  373.             store_all(min_b, min(min_b, b));
  374.  
  375.             store_all(max_r, max(max_r, r));
  376.             store_all(max_g, max(max_g, g));
  377.             store_all(max_b, max(max_b, b));
  378.            
  379.             store_all(total_r, total_r + r);
  380.             store_all(total_g, total_g + g);
  381.             store_all(total_b, total_b + b);
  382.         }
  383.  
  384.         vfloat avg_r = floor((total_r + 8) * (1.0f/16.0f));
  385.         vfloat avg_g = floor((total_g + 8) * (1.0f/16.0f));
  386.         vfloat avg_b = floor((total_b + 8) * (1.0f/16.0f));
  387.        
  388.         vfloat lr, lg, lb, hr, hg, hb;
  389.  
  390.         encode_bc1_pick_initial(pSrc_pixels, grayscale_flag,
  391.             min_r, min_g, min_b, max_r, max_g, max_b,
  392.             avg_r, avg_g, avg_b, total_r, total_g, total_b,
  393.             lr, lg, lb, hr, hg, hb);
  394.  
  395.         vfloat sels[16];
  396.         bc1_find_sels4_noerr(pSrc_pixels, lr, lg, lb, hr, hg, hb, sels);
  397.  
  398.         vfloat trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb;
  399.  
  400.         vvec3F xl, xh;
  401.         vbool result = compute_least_squares_endpoints4_rgb(pSrc_pixels, sels, &xl, &xh, total_r, total_g, total_b);
  402.  
  403.         SPMD_SIMPLE_IF(result)
  404.         {
  405.             precise_round_565(xl, xh, trial_hr, trial_hg, trial_hb, trial_lr, trial_lg, trial_lb);
  406.        
  407.             bc1_find_sels4_noerr(pSrc_pixels, trial_lr, trial_lg, trial_lb, trial_hr, trial_hg, trial_hb, sels);
  408.  
  409.             store(lr, trial_lr);
  410.             store(lg, trial_lg);
  411.             store(lb, trial_lb);
  412.  
  413.             store(hr, trial_hr);
  414.             store(hg, trial_hg);
  415.             store(hb, trial_hb);
  416.         }
  417.         SPMD_SIMPLE_END_IF
  418.  
  419.         bc1_encode4(index, pDst_blocks, lr, lg, lb, hr, hg, hb, sels, pcount);
  420.     }
  421.  
  422.     void _call(bc1_block* pDst_blocks, const uint8_t *pSrc_pixels, int n)
  423.     {
  424.         spmd_foreach(0, n,
  425.             [&](const lint index, int pcount)
  426.             {
  427.                 const int first_index = index.get_first_value();
  428.  
  429.                 vcolor3 src_pixels[16];
  430.  
  431.                 if ((CPPSPMD_AVX) && (pcount == CPPSPMD::PROGRAM_COUNT))
  432.                 {
  433.                     int32_t *pSrc_int32 = (int32_t *)pSrc_pixels;
  434.  
  435. #if CPPSPMD_AVX2                   
  436.                     vint vindex16 = vint(index) * 16;
  437. #else
  438.                     int32_t *pCur_int32 = pSrc_int32 + first_index * 16;
  439. #endif
  440.  
  441.                     for (uint32_t i = 0; i < 16; i++)
  442.                     {
  443. #if CPPSPMD_AVX2
  444.                         vint v = load_all((vindex16 + i)[pSrc_int32]);
  445. #else
  446.                         vint v = load_all_strided(pCur_int32, 16);
  447.                         pCur_int32++;
  448. #endif
  449.                         vfloat r = vfloat(v & 0xFF);
  450.                         vfloat g = vfloat(VINT_SHIFT_RIGHT(v, 8) & 0xFF);
  451.                         vfloat b = vfloat(VINT_SHIFT_RIGHT(v, 16) & 0xFF);
  452.  
  453.                         store_all(src_pixels[i].c[2], b);
  454.                         store_all(src_pixels[i].c[1], g);
  455.                         store_all(src_pixels[i].c[0], r);
  456.                     }
  457.                 }
  458.                 else
  459.                 {
  460.                     const uint8_t *pSrc = pSrc_pixels + first_index * 16 * 4;
  461.  
  462.                     for (int p = 0; p < CPPSPMD::PROGRAM_COUNT; p++)
  463.                     {
  464.                         if (p < pcount)
  465.                         {
  466.                             for (uint32_t i = 0; i < 16; i++, pSrc += 4)
  467.                             {
  468.                                 uint32_t v = *(uint32_t *)pSrc;
  469.  
  470.                                 ((float *)&src_pixels[i].c[0])[p] = (float)(v & 0xFF);
  471.                                 ((float *)&src_pixels[i].c[1])[p] = (float)((v >> 8) & 0xFF);
  472.                                 ((float *)&src_pixels[i].c[2])[p] = (float)((v >> 16) & 0xFF);
  473.                             }
  474.                         }
  475.                         else
  476.                         {
  477.                             for (uint32_t i = 0; i < 16; i++, pSrc += 4)
  478.                             {
  479.                                 ((float *)&src_pixels[i].c[0])[p] = 0;
  480.                                 ((float *)&src_pixels[i].c[1])[p] = 0;
  481.                                 ((float *)&src_pixels[i].c[2])[p] = 0;
  482.                             }
  483.                         }
  484.                     }
  485.                 }
  486.  
  487.                 encode_bc1_internal(index, pDst_blocks, src_pixels, pcount);
  488.             }
  489.         );
  490.  
  491.     }
  492. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement