//=============================================================================== // Copyright (c) 2007-2016 Advanced Micro Devices, Inc. All rights reserved. // Copyright (c) 2004-2006 ATI Technologies Inc. //=============================================================================== // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files(the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions : // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #include #include #include #include "3dquant_constants.h" #include "3dquant_vpc.h" #include "shake.h" #include "bc7_utils.h" #include "debug.h" #include "bc7_encode.h" #define LOG_CL_BASE 2 #define BIT_BASE 5 #define LOG_CL_RANGE 5 #define BIT_RANGE 9 #define CLT(cl) (cl-LOG_CL_BASE) #define BTT(bits) (bits-BIT_BASE) int npv_nd[][2*MAX_DIMENSION_BIG]= { {}, // 0 - for alingment {}, // 1 {}, // 2 {1,2,4,8,16,32}, //3 {1,2,4} //4 }; // Reworking these tables // Since endpoints can be flipped for the encoding (reclaims an index bit) this means // that the parity tables must be symmetric for the two endpoints, as parity could also be flipped // The tables above do not guarantee this behaviour, but this one does int par_vectors_nd[][2*MAX_DIMENSION_BIG][(1<<(2*MAX_DIMENSION_BIG-1))][2][MAX_DIMENSION_BIG] = { {{{}}}, // 0 - for alingment {{{}}}, //1D {{{}}}, //2D { {{}}, // 3*n+1 BCC 3*n+1 Cartesian 3*n //same parity { // SAME_PAR {{0,0,0},{0,0,0}}, {{1,1,1},{1,1,1}} }, // 3*n+2 BCC 3*n+1 BCC 3*n+1 { // BCC {{0,0,0},{0,0,0}}, {{0,0,0},{1,1,1}}, {{1,1,1},{0,0,0}}, {{1,1,1},{1,1,1}} }, // 3*n+3 FCC ??? // ?????? // BCC with FCC same or inverted, symmetric { // BCC_SAME_FCC {{0,0,0},{0,0,0}}, {{1,1,0},{1,1,0}}, {{1,0,1},{1,0,1}}, {{0,1,1},{0,1,1}}, {{0,0,0},{1,1,1}}, {{1,1,1},{0,0,0}}, {{0,1,0},{0,1,0}}, // ?? {{1,1,1},{1,1,1}}, }, // 3*n+4 FCC 3*n+2 FCC 3*n+2 { {{0,0,0},{0,0,0}}, {{1,1,0},{0,0,0}}, {{1,0,1},{0,0,0}}, {{0,1,1},{0,0,0}}, {{0,0,0},{1,1,0}}, {{1,1,0},{1,1,0}}, {{1,0,1},{1,1,0}}, {{0,1,1},{1,1,0}}, {{0,0,0},{1,0,1}}, {{1,1,0},{1,0,1}}, {{1,0,1},{1,0,1}}, {{0,1,1},{1,0,1}}, {{0,0,0},{0,1,1}}, {{1,1,0},{0,1,1}}, {{1,0,1},{0,1,1}}, {{0,1,1},{0,1,1}} }, // 3*n+5 Cartesian 3*n+3 FCC 3*n+2 //D^*[6] { {{0,0,0},{0,0,0}}, {{1,1,0},{0,0,0}}, {{1,0,1},{0,0,0}}, {{0,1,1},{0,0,0}}, {{0,0,0},{1,1,0}}, {{1,1,0},{1,1,0}}, {{1,0,1},{1,1,0}}, {{0,1,1},{1,1,0}}, {{0,0,0},{1,0,1}}, {{1,1,0},{1,0,1}}, {{1,0,1},{1,0,1}}, {{0,1,1},{1,0,1}}, {{0,0,0},{0,1,1}}, {{1,1,0},{0,1,1}}, {{1,0,1},{0,1,1}}, {{0,1,1},{0,1,1}}, {{1,0,0},{1,1,1}}, {{0,1,0},{1,1,1}}, {{0,0,1},{1,1,1}}, {{1,1,1},{1,1,1}}, {{1,0,0},{0,0,1}}, {{0,1,0},{0,0,1}}, {{0,0,1},{0,0,1}}, {{1,1,1},{0,0,1}}, {{1,0,0},{1,0,0}}, {{0,1,0},{1,0,0}}, {{0,0,1},{1,0,0}}, {{1,1,1},{1,0,0}}, {{1,0,0},{0,1,0}}, {{0,1,0},{0,1,0}}, {{0,0,1},{0,1,0}}, {{1,1,1},{0,1,0}} } }, { {{}}, // 3*n+1 BCC 3*n+1 Cartesian 3*n //same parity { // SAME_PAR {{0,0,0,0},{0,0,0,0}}, {{1,1,1,1},{1,1,1,1}} }, // 3*n+2 BCC 3*n+1 BCC 3*n+1 { // BCC {{0,0,0,0},{0,0,0,0}}, {{0,0,0,0},{1,1,1,1}}, {{1,1,1,1},{0,0,0,0}}, {{1,1,1,1},{1,1,1,1}} }, // 3 PBIT { {{0,0,0,0},{0,0,0,0}}, {{0,0,0,0},{0,1,1,1}}, {{0,1,1,1},{0,0,0,0}}, {{0,1,1,1},{0,1,1,1}}, {{1,0,0,0},{1,0,0,0}}, {{1,0,0,0},{1,1,1,1}}, {{1,1,1,1},{1,0,0,0}}, {{1,1,1,1},{1,1,1,1}} }, // 4 PBIT { {{0,0,0,0},{0,0,0,0}}, {{0,0,0,0},{0,1,1,1}}, {{0,1,1,1},{0,0,0,0}}, {{0,1,1,1},{0,1,1,1}}, {{1,0,0,0},{1,0,0,0}}, {{1,0,0,0},{1,1,1,1}}, {{1,1,1,1},{1,0,0,0}}, {{1,1,1,1},{1,1,1,1}}, {{0,0,0,0},{0,0,0,0}}, {{0,0,0,0},{0,0,1,1}}, {{0,0,1,1},{0,0,0,0}}, {{0,1,0,1},{0,1,0,1}}, {{1,0,0,0},{1,0,0,0}}, {{1,0,0,0},{1,0,1,1}}, {{1,0,1,1},{1,0,0,0}}, {{1,1,0,1},{1,1,0,1}}, }, }, //4 }; //#define GIG_TABLE #ifdef GIG_TABLE static double ramp_err[LOG_CL_RANGE-LOG_CL_BASE][BIT_RANGE-BIT_BASE][256][256][256][16]; #endif static double ramp[LOG_CL_RANGE-LOG_CL_BASE][BIT_RANGE-BIT_BASE][256][256][16]; static double ep_d[BIT_RANGE-BIT_BASE][256]; // inverted table // , bits, value, par1, par2, static int sp_idx[LOG_CL_RANGE-LOG_CL_BASE][BIT_RANGE-BIT_BASE][256][2][2][MAX_CLUSTERS_BIG][2]; // , bits, value, par1, par2, static double sp_err[LOG_CL_RANGE-LOG_CL_BASE][BIT_RANGE-BIT_BASE][256][2][2][MAX_CLUSTERS_BIG]; //#endif // int expand_ (int bits, int v) { assert(bits >=4); return ( v << (8-bits) | v >> (2* bits - 8)); } static bool ramp_init = false; void init_ramps (void) { if (ramp_init) return; #ifdef USE_DBGTRACE DbgTrace(()); #endif int clog1; int bits; int p1; int p2; int i,j; int o1,o2; for (bits=BIT_BASE; bits= 0 && sp_err[CLT(clog1)][BTT(bits)][j-k][o1][o2][i]==0) || (j+k < 256 && sp_err[CLT(clog1)][BTT(bits)][j+k][o1][o2][i]==0) ) break; { if ( (j-k >= 0 && sp_err[CLT(clog1)][BTT(bits)][j-k][o1][o2][i]==0)) { sp_idx[CLT(clog1)][BTT(bits)][j][o1][o2][i][0]=sp_idx[CLT(clog1)][BTT(bits)][j-k][o1][o2][i][0]; sp_idx[CLT(clog1)][BTT(bits)][j][o1][o2][i][1]=sp_idx[CLT(clog1)][BTT(bits)][j-k][o1][o2][i][1]; } else if ((j+k < 256 && sp_err[CLT(clog1)][BTT(bits)][j+k][o1][o2][i]==0)) { sp_idx[CLT(clog1)][BTT(bits)][j][o1][o2][i][0]=sp_idx[CLT(clog1)][BTT(bits)][j+k][o1][o2][i][0]; sp_idx[CLT(clog1)][BTT(bits)][j][o1][o2][i][1]=sp_idx[CLT(clog1)][BTT(bits)][j+k][o1][o2][i][1]; } sp_err[CLT(clog1)][BTT(bits)][j][o1][o2][i]=k*k; } } ramp_init = true; } // finds "floor in the set" if exists, otherwise returns min inline int ep_find_floor( double v, int bits, int use_par, int odd) { assert(use_par==0 || use_par==1 || odd==0 || odd==1 ); double *p = ep_d[BTT(bits)]; int i1=0; int i2=1<<(bits-use_par); odd = use_par ? odd : 0; while (i2-i1>1) { int j = (i1+i2)/2; if (v >= p[(j<0); int i,j; int same = 1; for(i=1; i< n; i++) for(j=0; j< DIMENSION; j++) same = same && (d[0][j] ==d[i][j]); return(same); } inline int all_same_d (double d[][MAX_DIMENSION_BIG], int n, int dimension) { assert(n>0); int i,j; int same = 1; for(i=1; i< n; i++) for(j=0; j< dimension; j++) same = same && (d[0][j] ==d[i][j]); #ifdef USE_DBGTRACE DbgTrace(("[%d]",same)); #endif return(same); } inline int max_i (int a[], int n) { assert(n>0); int i,m=a[0]; for(i=0; i< n; i++) m = m > a[i] ? m : a[i]; return (m); } void index_collapse_ (int index[], int numEntries) { #ifdef USE_DBGTRACE DbgTrace(()); #endif int k; int d,D; int mi; int Mi; if (numEntries ==0) return; mi=Mi=index[0]; for (k=1; k index[k] ? Mi : index[k]; } D=1; for (d=2; d<=Mi-mi; d++) { for (k=0; k=numEntries) D =d; } for (k=0; k>=1) clog2++; assert((1<=0 && tc <=255.); if ( sp_err[CLT(clog2)][BTT(bits[j])][tf][t1][t2][i] > sp_err[CLT(clog2)][BTT(bits[j])][tc][t1][t2][i]) // if they are not equal, the same representalbe point is used for // both of them, as all representable points are integers in the rage dr[j]=tc; else if (sp_err[CLT(clog2)][BTT(bits[j])][ tf ][t1][t2][i] < sp_err[CLT(clog2)][BTT(bits[j])][ tc ][t1][t2][i]) dr[j]=tf; else dr[j]=(int)floor(data[0][j]+0.5); tr = sp_err[CLT(clog2)][BTT(bits[j])][dr[j]][t1][t2][i] + 2*sqrt(sp_err[CLT(clog2)][BTT(bits[j])][dr[j]][t1][t2][i]) * fabs((double)dr[j]-data[0][j])+ (dr[j]-data[0][j])* (dr[j]-data[0][j]); if (tr < t_) { t_=tr; t1o[j]=t1; t2o[j]=t2; dr_0[j]=dr[j]; } } } t += t_; } if (t < err_0) { idx=i; for (j=0; j")); #endif int i,j,k; // //############################### // decode for "new style" interface, this can be passed in directly // int max_bits[MAX_DIMENSION_BIG]; int type = bits % (2*dimension); int use_par =(type !=0); for (j=0; j>=1) clog3++; assert((1<>1)-1 ? epi[i][0] : (size>>1)-1 ) ) & (~use_par); epi[i][1]+= ((1<>1) ? (1<>1) ) & (~use_par); } int p1,p2, step=(1< 0) { t += (rbp[ci[_mc-1]]-data[_mc-1][j])*(rbp[ci[_mc-1]]-data[_mc-1][j]); _mc--; } if (t>=1) clog4++; assert((1<> (2 *j)) & 0x3) !=0) { j0 =j; // new cords ei0 = ( ( (s^g) >>(2 *j)) & 0x1); ei1 = ( ( (s^g) >>(2 *j+1)) & 0x1); } } s = s ^ g; r[j0]= ramp[CLT(clog4)][BTT(bits[j0])][epi[0][j0][ei0]][epi[1][j0][ei1]]; err_0 = 0; for (i=0; i>(2 *j) ) & 0x1); ei1 = ( ( s1 >>(2 *j+1)) & 0x1); epo_1[0][j]=epi[0][j][ei0]; epo_1[1][j]=epi[1][j][ei1]; } } } } if (err_1 < err_2) { // best in the curent ep cube run for (i=0; i < numEntries; i++) { idx_2[i]=idx_1[i]; for (j=0; j