7
votes

Pourquoi les fonctions arithmétiques de GLSL donnent-elles des résultats si différents sur l'iPad que sur le simulateur?

Je poursuis actuellement des bugs dans mon code de shader de My OpenGL ES 2.0 en cours d'exécution sur des périphériques iOS. Le code fonctionne bien dans le simulateur, mais sur l'iPad, il a des problèmes énormes et certains des calculs produisent des résultats très différents, j'ai eu par exemple 0,0 sur l'iPad et 4013.17 sur le simulateur, donc je ne parle pas de petites différences qui pourraient être le résultat de certaines erreurs d'arrondi.

Une des choses que j'ai remarquées est que, sur l'iPad, xxx

peut donner des résultats très différents des résultats de xxx

spécifiquement, lors de l'utilisation de pow (x, 2.0) sur une variable contenant un nombre négatif plus grand comme -8 , il semblait renvoyer une valeur qui a satisfait à la condition si (powresult <= 0,0) .

aussi, Le résultat des deux opérations ( pow (x, 2.0) ainsi que x * x ) donne différents résultats dans le simulateur que sur l'iPad.

Les flotteurs d'occasion sont mediump , mais je reçois les mêmes choses avec highp .

y a-t-il une explication simple pour ceux qui diffèrent

Je réduit le problème, mais cela prend tellement de temps, alors peut-être que quelqu'un peut m'aider ici avec une explication simple.


1 commentaires

Je pense que vous constaterez que vous obtiendrez même des résultats légèrement différents sur les différents GPU de périphérique IOS eux-mêmes (iPad vs. iPad 2 vs. iPhone 4, etc.). C'est l'un des domaines où vous avez presque besoin de tester sur tous les appareils que vous souhaitez soutenir.


3 Réponses :


1
votes

Le simulateur utilise une unité de point flottante X86 et des bibliothèques numériques Mac OS X. L'iPad utilise soit un FPU à bras.

aussi POW () est une routine de bibliothèque qui utilise un algorithme d'approximation.


6 commentaires

Donc, vous dites que l'iPad et le simulateur peuvent donner des nombres aussi différents, même s'ils sont conformes à la conformité de la norme OpenGL ES 2.0 ', et donc (IIRC) à la norme IEEE pour l'arithmétique de point flottant (IEEE 754 ) ? Je pensais que ces normes sont faites pour prévenir exactement quelque chose comme ça.


Notez qu'ils posent des questions sur GLSL Shaders, il s'agit donc d'un calcul effectué sur le GPU, non pas sur les bibliothèques standard liées à la CPU. Nous ne parlons pas du bras vs. x86 ici, mais PowerVR vs. L'émulation (principalement logicielle) utilisée dans le simulateur IOS.


@cheeesus OpenGL ES 2 Standard n'impose pas une conformité stricte de la norme IEEE 754, jetez un coup d'œil à la spécification GLSL ES dans le chapitre «Qualificateurs de précision et de précision», les exigences concernent des gammes de précision minimales.


Merci tout le monde. La fonction pow () était la raison de ces vastes différences, la mise en œuvre de pow () sur le GPU de l'iPad a vraiment des problèmes, spécialement avec des nombres négatifs. @Jamesthiele, vous pourriez peut-être éditer votre message pour refléter les remarques de Bradlarson.


-1: Quel brad dit sur le fait que ceux-ci sont sur le GPU PowerVR.


Dans OpenGL, la POW est incomplètement mise en œuvre; La spécification ne le définit pas pour x <0. 0. Voir ma réponse.) Sur la CPU principale, le POW devrait être assez bon et POW (X, 2) peut être optimisé pour x * x par le compilateur.



17
votes

the Documentation GLSL ES dit POW non définie Si x <0 ou si x = 0 et y ≤ 0.


2 commentaires

Merci! Cela fixe une fin à une longue session de débogage. Mais sérieusement: wtf?


Pour être plus précis: khronos.org/registry/opengl-fpages /gl4/html/pow.xhtml .



1
votes

dans GLSL pow est implémenté en fonction de exp2 et log2 . Depuis le La fonction LOGARITHM n'est pas définie pour les numéros réels négatifs, pow () n'est pas non plus non plus.

Voir le Spécification GLSL ES 3.0 Page 47 , ou Spécification GLSL 4.4 Page 88.

pow (x, y) hérité de exp2 (x * log2 (Y))

Aussi de la spécification:

generype pow (generype x, gentype y)

  • retourne x élevé à la puissance y, c'est-à-dire x ^ y Les résultats
  • ne sont indéfinis si x <0.
  • Les résultats sont indéfinis si x = 0 et y <= 0.

0 commentaires