diff --git a/samples/shader_translator/shader_translator.cpp b/samples/shader_translator/shader_translator.cpp index fb72363f23..676ad3d5ed 100644 --- a/samples/shader_translator/shader_translator.cpp +++ b/samples/shader_translator/shader_translator.cpp @@ -6,6 +6,65 @@ #include "GLSLANG/ShaderLang.h" +// ---------------------------------------------------------------------------- +// POC: CityHash64 v1.03 -- bit-identical to chromium base::legacy::CityHash64, +// which gpu/command_buffer/service/gles2_cmd_decoder.cc installs as ANGLE's +// ShBuiltInResources::HashFunction in the validating command decoder. +// ---------------------------------------------------------------------------- +#include +#include +#include +namespace poc_city { +typedef uint8_t uint8; typedef uint32_t uint32; typedef uint64_t uint64; +typedef std::pair uint128; +static inline uint64 U128Lo(const uint128&x){return x.first;} +static inline uint64 U128Hi(const uint128&x){return x.second;} +static inline uint64 H128to64(const uint128&x){const uint64 kMul=0x9ddfea08eb382d69ULL; + uint64 a=(U128Lo(x)^U128Hi(x))*kMul;a^=(a>>47);uint64 b=(U128Hi(x)^a)*kMul;b^=(b>>47);b*=kMul;return b;} +static uint64 F64(const char*p){uint64 r;memcpy(&r,p,8);return r;} +static uint32 F32(const char*p){uint32 r;memcpy(&r,p,4);return r;} +static const uint64 k0=0xc3a5c85c97cb3127ULL,k1=0xb492b66fbe98f273ULL, + k2=0x9ae16a3b2f90404fULL,k3=0xc949d7c7509e6557ULL; +static uint64 Rot(uint64 v,int s){return s==0?v:((v>>s)|(v<<(64-s)));} +static uint64 Rot1(uint64 v,size_t s){return (v>>s)|(v<<(64-s));} +static uint64 SM(uint64 v){return v^(v>>47);} +static uint64 HL16(uint64 u,uint64 v){return H128to64(uint128(u,v));} +static uint64 H0_16(const char*s,size_t l){ + if(l>8){uint64 a=F64(s),b=F64(s+l-8);return HL16(a,Rot1(b+l,l))^b;} + if(l>=4){uint64 a=F32(s);return HL16(l+(a<<3),F32(s+l-4));} + if(l>0){uint8 a=(uint8)s[0],b=(uint8)s[l>>1],c=(uint8)s[l-1]; + uint32 y=(uint32)a+((uint32)b<<8),z=(uint32)l+((uint32)c<<2); + return SM(y*k2^z*k3)*k2;}return k2;} +static uint64 H17_32(const char*s,size_t l){uint64 a=F64(s)*k1,b=F64(s+8), + c=F64(s+l-8)*k2,d=F64(s+l-16)*k0; + return HL16(Rot(a-b,43)+Rot(c,30)+d,a+Rot(b^k3,20)-c+l);} +static std::pair WH32(uint64 w,uint64 x,uint64 y,uint64 z,uint64 a,uint64 b){ + a+=w;b=Rot(b+a+z,21);uint64 c=a;a+=x;a+=y;b+=Rot(a,44);return std::make_pair(a+z,b+c);} +static std::pair WH32(const char*s,uint64 a,uint64 b){ + return WH32(F64(s),F64(s+8),F64(s+16),F64(s+24),a,b);} +static uint64 H33_64(const char*s,size_t l){uint64 z=F64(s+24), + a=F64(s)+(l+F64(s+l-16))*k0,b=Rot(a+z,52),c=Rot(a,37); + a+=F64(s+8);c+=Rot(a,7);a+=F64(s+16);uint64 vf=a+z,vs=b+Rot(a,31)+c; + a=F64(s+16)+F64(s+l-32);z=F64(s+l-8);b=Rot(a+z,52);c=Rot(a,37); + a+=F64(s+l-24);c+=Rot(a,7);a+=F64(s+l-16);uint64 wf=a+z,ws=b+Rot(a,31)+c; + uint64 r=SM((vf+ws)*k2+(wf+vs)*k0);return SM(r*k0+vs)*k2;} +uint64 CityHash64(const char*s,size_t l){ + if(l<=32){if(l<=16)return H0_16(s,l);return H17_32(s,l);} + if(l<=64)return H33_64(s,l); + uint64 x=F64(s+l-40),y=F64(s+l-16)+F64(s+l-56),z=HL16(F64(s+l-48)+l,F64(s+l-24)); + std::pair v=WH32(s+l-64,l,z),w=WH32(s+l-32,y+k1,x);x=x*k1+F64(s); + l=(l-1)&~(size_t)63; + do{x=Rot(x+y+v.first+F64(s+8),37)*k1;y=Rot(y+v.second+F64(s+48),42)*k1; + x^=w.second;y+=v.first+F64(s+40);z=Rot(z+w.first,33)*k1; + v=WH32(s,v.second*k1,x+w.first);w=WH32(s+32,z+w.second,y+F64(s+16)); + std::swap(z,x);s+=64;l-=64;}while(l!=0); + return HL16(HL16(v.first,w.first)+SM(y)*k1+z,HL16(v.second,w.second)+x);} +} // namespace poc_city +extern "C" khronos_uint64_t PocCityHash64(const char*s,size_t l){ + return poc_city::CityHash64(s,l); +} +// ---------------------------------------------------------------------------- + #include #include #include @@ -108,6 +167,17 @@ int main(int argc, char *argv[]) case 'i': compileOptions.intermediateTree = true; break; + case 'p': + // POC: mirror the validating-decoder configuration from + // chromium gpu/command_buffer/service/{gles2_cmd_decoder.cc, + // shader_translator.cc}: CityHash64 identifier hashing and + // indirect-array-bounds clamping. + resources.HashFunction = PocCityHash64; + compileOptions.clampIndirectArrayBounds = true; + compileOptions.initOutputVariables = true; + compileOptions.limitExpressionComplexity = true; + compileOptions.limitCallStackDepth = true; + break; case 'o': compileOptions.objectCode = true; break;