рдпрд╣ рдХреНрдпрд╛ рд╣реИ
ARM рдиреАрдпрди рдХреНрдпрд╛ рд╣реИ? -
ARM┬о NEON тДв рдПрдХ SIMD рдЗрдВрдЬрди рд╣реИ ... - рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрд╣ x86 CPU SSE / SSE2 рдЬреИрд╕рд╛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдирд┐рд░реНрджреЗрд╢ рд╕реЗрдЯ рд╣реИ, рд▓реЗрдХрд┐рди ARM рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╡рд╛рд▓реЗ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд▓рд┐рдПред
рдХреНрдпреЛрдВ?
рдЬрдм рддрдХ рдореИрдВрдиреЗ FSAA рд╕рдорд░реНрдерди рдирд╣реАрдВ рдЬреЛрдбрд╝рд╛ рддрдм рддрдХ рд╕рдм рдХреБрдЫ рдареАрдХ рдерд╛ред рдЙрд╕рдХреЗ рдмрд╛рдж, рдПрдлрдкреАрдПрд╕ 15 рд╕реЗ рдХрдо рд╣реЛ рдЧрдпрд╛ред
рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдлрд┐рд░ рд╕реЗ рд▓рдЧрднрдЧ 25 рдПрдлрдкреАрдПрд╕ред рд▓реЗрдХрд┐рди рд╕реНрдореГрддрд┐ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдерд╛ рдЬреЛ рдкреНрд░рддрд┐ рдлреНрд░реЗрдо 10% рд╕рдордп рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рдерд╛ рдЬрд┐рд╕рдореЗрдВ рдореБрдЭреЗ рдЕрдм рдирд╣реАрдВ рдкрддрд╛ рдерд╛ рдХрд┐ рдХреНрдпрд╛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдореЗрд░реЗ рдПрдХ рджреЛрд╕реНрдд рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рд╕рдордп-рд╕рдордп рдкрд░ рдПрдХ рд╕рд╡рд╛рд▓ рдкреВрдЫрд╛, "рдХреНрдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдЗрдВрдЬрди рдореЗрдВ рдиреАрдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ", рдореИрдВрдиреЗ рддрдп рдХрд┐рдпрд╛ рдХрд┐ рдЗрд╕ рд╕рдорд╛рд░реЛрд╣ рдХреЛ рдлрд┐рд░ рд╕реЗ рдиреАрдпрди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП (рдЙрдирдХреЗ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде)ред
рд╕рдВрд░рдЪрдирд╛рдПрдВ:
рдПрдХрд▓ рд╡рдЬрди рдкрд░рд┐рд╡рд░реНрддрди:
forceinline void transformPointNormal4x3Weight_NoW(const Matrix44f& mat,const Vec3f& inV, const Vec3f& inN, BaseRenderScene::PN& outPN) { outPN.p.vec[0] = (inV.vec[0]*mat.mat[0][0] + inV.vec[1]*mat.mat[1][0] + inV.vec[2]*mat.mat[2][0] + mat.mat[3][0]); outPN.n.vec[0] = (inN.vec[0]*mat.mat[0][0] + inN.vec[1]*mat.mat[1][0] + inN.vec[2]*mat.mat[2][0]); outPN.p.vec[1] = (inV.vec[0]*mat.mat[0][1] + inV.vec[1]*mat.mat[1][1] + inV.vec[2]*mat.mat[2][1] + mat.mat[3][1]); outPN.n.vec[1] = (inN.vec[0]*mat.mat[0][1] + inN.vec[1]*mat.mat[1][1] + inN.vec[2]*mat.mat[2][1]); outPN.p.vec[2] = (inV.vec[0]*mat.mat[0][2] + inV.vec[1]*mat.mat[1][2] + inV.vec[2]*mat.mat[2][2] + mat.mat[3][2]); outPN.n.vec[2] = (inN.vec[0]*mat.mat[0][2] + inN.vec[1]*mat.mat[1][2] + inN.vec[2]*mat.mat[2][2]); } forceinline void transformPointNormal4x3Weight(const Matrix44f& mat,const Vec3f& inV, const Vec3f& inN, BaseRenderScene::PN& outPN,float w ) { outPN.p.vec[0] = (inV.vec[0]*mat.mat[0][0] + inV.vec[1]*mat.mat[1][0] + inV.vec[2]*mat.mat[2][0] + mat.mat[3][0])*w; outPN.n.vec[0] = (inN.vec[0]*mat.mat[0][0] + inN.vec[1]*mat.mat[1][0] + inN.vec[2]*mat.mat[2][0])*w; outPN.p.vec[1] = (inV.vec[0]*mat.mat[0][1] + inV.vec[1]*mat.mat[1][1] + inV.vec[2]*mat.mat[2][1] + mat.mat[3][1])*w; outPN.n.vec[1] = (inN.vec[0]*mat.mat[0][1] + inN.vec[1]*mat.mat[1][1] + inN.vec[2]*mat.mat[2][1])*w; outPN.p.vec[2] = (inV.vec[0]*mat.mat[0][2] + inV.vec[1]*mat.mat[1][2] + inV.vec[2]*mat.mat[2][2] + mat.mat[3][2])*w; outPN.n.vec[2] = (inN.vec[0]*mat.mat[0][2] + inN.vec[1]*mat.mat[1][2] + inN.vec[2]*mat.mat[2][2])*w; } forceinline void transformPointNormal4x3AddWeighted(const Matrix44f& mat,const Vec3f& inV, const Vec3f& inN, BaseRenderScene::PN& outPN,float w ) { outPN.p.vec[0] += (inV.vec[0]*mat.mat[0][0] + inV.vec[1]*mat.mat[1][0] + inV.vec[2]*mat.mat[2][0] + mat.mat[3][0])*w; outPN.n.vec[0] += (inN.vec[0]*mat.mat[0][0] + inN.vec[1]*mat.mat[1][0] + inN.vec[2]*mat.mat[2][0])*w; outPN.p.vec[1] += (inV.vec[0]*mat.mat[0][1] + inV.vec[1]*mat.mat[1][1] + inV.vec[2]*mat.mat[2][1] + mat.mat[3][1])*w; outPN.n.vec[1] += (inN.vec[0]*mat.mat[0][1] + inN.vec[1]*mat.mat[1][1] + inN.vec[2]*mat.mat[2][1])*w; outPN.p.vec[2] += (inV.vec[0]*mat.mat[0][2] + inV.vec[1]*mat.mat[1][2] + inV.vec[2]*mat.mat[2][2] + mat.mat[3][2])*w; outPN.n.vec[2] += (inN.vec[0]*mat.mat[0][2] + inN.vec[1]*mat.mat[1][2] + inN.vec[2]*mat.mat[2][2])*w; }
рдПрдХ рд╢реАрд░реНрд╖ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди:
const Vec3f& vx = pVerticies[v]; const Vec3f& vxN = pNormals[v]; float w = pVertexWeight[v].vec[0]; int boneIndex = pVertexBones[v].vec[0]; const Matrix44f& boneTM = pBoneTMList[boneIndex]; if( wCount==1 ) { transformPointNormal4x3Weight_NoW(boneTM,vx,vxN,skinTempPN[v]); } else {
рдПрдХ рдЬреНрдЮрд╛рдиреА рд╡реНрдпрдХреНрддрд┐ рддреБрд░рдВрдд рдзреНрдпрд╛рди рджреЗрдЧрд╛ рдХрд┐ рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рд╢реАрд░реНрд╖ рдХреЗ рд▓рд┐рдП рдЧреИрд░-рд╢реВрдиреНрдп рднрд╛рд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реВрдВред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд▓рдЧрднрдЧ 30% рдЪреЛрдЯрд┐рдпрд╛рдБ рд╕рдорд╛рди рд╡рдЬрди рдХреЗ рд╕рд╛рде рдереАрдВ, рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдереЛрдбрд╝рд╛ рд╕рдордп рдЬреАрддрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред
NEON (xCode рд╢реИрд▓реА) рдХреЗ рд╕рд╛рде рдПрдПрд╕рдПрдо
рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб asm / C рдХреЛрдб ARM NEON рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реИред
рдХреБрдЫ рдмрд╛рд░реАрдХрд┐рдпрд╛рдБ:
- ARM NEON рдХреЗ рд▓рд┐рдП, рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ 16 рдмрд╛рдЗрдЯреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдХрд╛рд░рдг, рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╕рднреА рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкрджреЛрдВ рдФрд░ рдорд╛рдирджрдВрдбреЛрдВ рдХреЛ Vec4f рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ред
- рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдбреЗрдЯрд╛ рдЕрднреА рднреА 4 рдмрд╛рдЗрдЯреНрд╕ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд░реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдиреЗ рдореБрдЭреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рдмрд┐рдирд╛ рд╕реАрдзреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдлрд░ рдореЗрдВ рдЕрдкрд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред 16 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рдВрд░реЗрдЦрд┐рдд рдбреЗрдЯрд╛ рд╡рд╛рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП, рдЕрддрд┐рд░рд┐рдХреНрдд 4 + 4 рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд░реНрдЯреЗрдХреНрд╕ рдмрдлрд░ рдореЗрдВ рдбреНрд░рд╛рдЗрд╡ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ (рдФрд░ рдпрд╣ рд╣рд░ рдлреНрд░реЗрдо рдкрд░ рд╣реЛрддрд╛ рд╣реИ)ред
#if defined(__ARM_NEON__) #define USE_NEON #endif #if defined(USE_NEON) #ifdef __thumb__ #error "This file should be compiled in ARM mode only."
рдкрд░рд┐рдгрд╛рдо
рдореИрдВрдиреЗ рдХреЛрдИ рд╕рд┐рдВрдереЗрдЯрд┐рдХ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ - рдореИрдВрдиреЗ рдПрдХ рдХрд╛рдо рдХреЗ рдорд╕реМрджреЗ рдкрд░ рд╕рдм рдХреБрдЫ рдЬрд╛рдВрдЪрд╛ред
502ms (c ++) рдмрдирд╛рдо 307ms (рдЖрд░реНрдо рдиреАрдпрди) iPhone 4 рдХреЗ рд▓рд┐рдП ~ 10 рд╕реЗрдХрдВрдб рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдкрд░ (39% C рд╕реЗ рддреЗрдЬ)ред
рдкреНрд░рд╢реНрди рдФрд░ рдЙрддреНрддрд░
рдПрдХ рд╕рд╛рде рдХрдИ рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ?
рдкреНрд░рд╢реНрди: рдпрд╣ рдХреНрдпреЛрдВ рд╡рд░реНрдгрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ ARM рдиреАрдпрди рдХреНрдпрд╛ рд╣реИ?
рдПрдХ: рдпрд╣ рдРрдирдХ рдРрдирдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред
рдХреНрдпреВ: рдПрдХ shader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ?
рдПрдХ: OpenGL 1.1
рдХреНрдпреВ: рдХреНрдпреЛрдВ рдирд╣реАрдВ OpenGL 2.0+ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ?
рдПрдХ: рдХреЗрд╡рд▓ рд╡рд┐рдВрдбреЛрдЬ рдлреЛрди 8 рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж (рдХреЛрдИ рдПрдлрдПрдл рдирд╣реАрдВ рд╣реИ рдФрд░ рдЙрд╕ рдкрд▓ рдореЗрдВ рдореИрдВ рдЗрдВрдЬрди рдореЗрдВ рдФрд░ рдлрд┐рд░ рдЬреАрдПрд▓ 2.0 рдореЗрдВ "shader" рдЬреЛрдбрд╝реВрдВрдЧрд╛)ред
рдкреНрд░рд╢реНрди: FF рдХреЗ рд▓рд┐рдП GL_OES_matrix_palette рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?
рдП: рдЖрдкрдХреЛ рдореЙрдбрд▓ рдХреЛ 11 (iphone рдХреЗ рд▓рд┐рдП) рдореИрдЯреНрд░рд┐рд╕ рдХреЗ рд╕рдореВрд╣реЛрдВ рдореЗрдВ рд╣рд░рд╛ рджреЗрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдордп рдирд╣реАрдВ рд╣реИ - рд╕рдВрднрд╡рддрдГ рднрд╡рд┐рд╖реНрдп рдореЗрдВред
рдкреНрд░рд╢реНрди: рдФрд░ рдореИрдВ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рдФрд░ рдЕрдзрд┐рдорд╛рдирддрдГ рдХрд╣рд╛рдВ рд╕реАрдЦ рд╕рдХрддрд╛ рд╣реВрдВ?
A: рдореИрдВ рдЖрдкрдХреЛ рдпрд╣рд╛рдБ рджреЗрдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдБ
ред рд╡рд╣рд╛рдВ рджреЗрдЦреЛ LGPLред
рдкреНрд░рд╢реНрди: рдХрд┐рддрдирд╛ рд▓рд┐рдпрд╛?
рдП: рдПрдХ рд╕рдкреНрддрд╛рд╣ - рдпрд╣ рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рд╣реА рдХрд╛рд░рдг рд╣реИ (рдпрджрд┐ рдХреЛрдИ рд╕рдордп рдмрдЪрд╛рддрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ рдЦреБрд╢реА рд╣реЛрдЧреА)ред
рдкреНрд░рд╢реНрди: рдореБрдЭреЗ рдХреБрдЫ рднреА рд╕рдордЭ рдирд╣реАрдВ рдЖрдпрд╛, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдпрд╣ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╕рдВрднрд╡ рд╣реИ?
рдП: рдпрд╣ рд╕рдВрднрд╡ рд╣реИ (рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ), рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред
рдкреБрдирд╢реНрдЪред рдкреАрдПрдо рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВред