2014-05-17 2 views
2

J'ai un seul fragment shader qui effectue un traitement sur un imageBuffer en utilisant des opérations de chargement/stockage d'image. Je suis exclusivement préoccupé par le scénario suivant:GLSL cohérent imageBuffer access dans un scénario en un seul passage (fragment shader), en un seul passage

  • J'ai un seul fragment shader (pas de considérations en plusieurs étapes (par exemple vertex puis fragment shaders), et pas de rendu multipass.)
  • variables imageBuffer sont déclarées comme cohérentes. Exclusivement intéressé par les imagesBuffers cohérentes.

Pour rendre les choses parfaitement claires, mon scénario est le suivant:

// Source code of my sole and unique fragment shader: 
coherent layout(1x32) uniform uimageBuffer data; 

void main() 
{ 
    ... 
    various calls to imageLoad(data, ..., ...); 
    ... 
    various calls to imageStore(data, ..., ...); 
    ... 
} 

J'ai largement regardé les spécifications

ARB_shader_image_load_store

surtout ce très paragraphe:

"Utilisation de variables déclarées comme "cohérent" garantit que les résultats de magasins seront immédiatement visibles aux appels de shaders en utilisant des variables déclarées de façon similaire; L'appel MemoryBarrier doit veiller à ce que les magasins sont visibles à d'autres opérations «

Note: mon « données imageBuffer uniforme cohérente; » déclaration est précisément une « variable de la même déclarée » Mon scénario est une seule passe.. ., une seule étape (fragment shader)

maintenant, je l'ai regardé divers sites Web et trébuché (comme la plupart des gens, je pense) sur ce fil sur stackoverflow.com:

How exactly is GLSL's "coherent" memory qualifier interpreted by GPU drivers for multi-pass rendering?

et plus sp ecifically, ce paragraphe:

« Votre shader ne peut même pas faire l'hypothèse que l'émission d'une charge juste après un magasin aura la mémoire qui vient d'être stockée dans ce très shader (oui vraiment. Vous devez mettre un memoryBarrier pour tirer que l'on off) «

Ma question est la suivante:.

Avec le qualificatif cohérent spécifié, dans mon unique shaders, un seul passage scénario de traitement, Est-ce que je peux oui ou non être sûr que imageStore() sera immédiatement visible à TOUTES les invocations de mon fragment shader (par exemple l'invocation actuelle ainsi que d'autres invocations concurrentes)?

En lisant la spécification ARB_shader_image_load_store, il semble que à moi que:

  • la réponse à cette question est oui,
  • Je ne ai pas besoin de tout type de memoryBarrier(),
  • la phrase citée dans le fil mentionné ci-dessus dans stackoverflow peut en effet induire en erreur et le mal.

Merci de votre compréhension.

+0

Vous êtes dans des casse-tête majeurs si vous n'utilisez pas de barrière de mémoire dans ce shader *** qui les charge et les stocke ensuite. Vous pourriez *** être en mesure de retirer cela en toute sécurité si votre tirage ne donne qu'un seul fragment. Mais pour tout ce qui est plus important, vous avez besoin d'une synchronisation entre les invocations simultanées de shader de fragments, sinon les autres peuvent se charger avant les autres. Les shaders de fragmentation peuvent être planifiés dans n'importe quel ordre que le conducteur pense produire des résultats sensés, imageLoad/Store est effectivement ignoré à cet égard parce qu'il est supposé que vous savez ce que vous faites. –

+0

@ AndonM.Coleman vous ne répondez pas à ma question. Cette question est: ** Est-ce que je peux oui ou non être sûr que imageStore() sera immédiatement visible pour TOUTES les invocations de mon fragment shader (par exemple l'invocation actuelle ainsi que d'autres invocations simultanées)? ** En d'autres termes, sont chargés/stockés sur des variables cohérentes et déclarées de façon similaire dans une étape de shader UNIQUE ** garantie ** à exécuter dans l'ordre? La spécification semble dire oui, certains membres du forum disent non. Vous venez de mentionner des problèmes généraux avec la programmation simultanée. Je sais que je n'ai aucun contrôle sur la programmation des invocations de shaders. – fred54

+0

C'est votre question, alors non. –

Répondre

0

Utilisez cette barrière de mémoire. Pour une chose, le GPU peut optimiser et extraire des blocs entiers de memeory pour lire FROM, et avoir une mémoire séparée pour écrire TO. En d'autres termes, si votre shader modifie toujours l'emplacement SIMPLE juste une fois, c'est OK, mais s'il relaie les valeurs des voisins APRES qu'un calcul a été appliqué, alors vous avez besoin d'une barrière de mémoire.

0

Avec le qualificatif cohérent spécifié, dans mon unique shaders, un seul passage scénario de traitement, puis-je être oui ou non sûr que Imagestore() 's sera immédiatement visible pour toutes les invocations de mon shader fragment (par exemple l'invocation actuelle ainsi que d'autres invocations simultanées)?

Si chaque fragment shader écrit à des endroits séparés dans l'image, et chaque fragment shader ne lit que les endroits qu'il a écrit, alors vous ne même pas besoin coherent. Cependant, si une instance de fragment shader veut lire des données écrites par d'autres instances de fragment shader, vous êtes SOL. Il n'y a rien que vous pouvez faire pour celui-là.

S'il s'agissait d'un shader de calcul, vous pouvez lancer l'appel barrier pour synchroniser les opérations au sein d'un groupe de travail. Cela garantirait que les écritures que vous voulez lire se produisent (vous avez toujours besoin de l'appel memoryBarrier pour les rendre visibles). Mais cela ne ferait que garantir que les écritures à partir des instances dans ce groupe de travail se sont produites. Les écritures provenant d'autres instances sont encore indéfinies.

et plus précisément, ce paragraphe:

BTW, ce paragraphe était faux. Très très mal. Dommage que la personne qui a écrit ce paragraphe ne sera jamais identifiée;)

Questions connexes