2010-04-13 6 views
5

J'ai remarqué que mes shaders GLSL ne sont pas compilable lorsque la version GLSL est inférieure à 130.OpenGL Shading Language rétrocompatibilité

Quels sont les éléments les plus critiques pour avoir une source de shaders rétrocompatible? Je ne veux pas avoir une rétrocompatibilité complète, mais j'aimerais comprendre les principales lignes directrices pour avoir des shaders simples (compatibles avec les versions antérieures) fonctionnant sur GPU avec un GLSL inférieur à 130.

Bien sûr, le problème pourrait être résolu avec le préprocesseur

#if __VERSION__ < 130 
#define VERTEX_IN attribute 
#else 
#define VERTER_IN in 
#endif 

Mais il ya probablement beaucoup de problèmes que j'ignore.

Répondre

2

Les activités récentes ont soulevé cette vieille question, et j'ai réalisé que j'ai résolu le problème. Ce n'était pas facile, mais c'est une solution réussie, prouvée par de nombreux shaders basés sur elle et le nombre de pilotes qui compile la source shader.

Essentiellement, je l'extension GL_ARB_shading_language_include (et je l'ai également mis en place un préprocesseur source pour les systèmes qui ne met pas en œuvre), et je fini par définir le shader suivant comprennent source:

// Copyright (C) 2011-2013 Luca Piccioni 
// 
// This program is free software: you can redistribute it and/or modify 
// it under the terms of the GNU General Public License as published by 
// the Free Software Foundation, either version 3 of the License, or 
// (at your option) any later version. 
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
// GNU General Public License for more details. 
// 
// You should have received a copy of the GNU General Public License 
// along with this program. If not, see <http://www.gnu.org/licenses/>. 

// @BeginInterface 

// Shader renderer 

// Symbol defined if running on NVIDIA renderer. 
#define DS_VENDOR_NVIDIA   1 
// Symbol defined if running on ATI/AMD renderer. 
#define DS_VENDOR_AMD    2 
// Symbol defined if running on INTEL renderer 
#define DS_VENDOR_INTEL    3 

// Shader inputs and outputs keywords 
// 
// - ATTRIBUTE: used to mark a vertex shader inputs 
// - SHADER_IN: used to mark a non-vertex shader inputs 
// - SHADER_OUT: used to mark a non-fragment shader output 
// - OUT: used to mark a fragment shader output 
#if __VERSION__ >= 130 

#define ATTRIBUTE in 
#define SHADER_IN in 
#define SHADER_OUT out 
#define OUT out 

#else 

#define ATTRIBUTE attribute 
#define SHADER_IN varying 
#define SHADER_OUT varying 
#define OUT 

#endif 

// Support array attributes 
#if __VERSION__ >= 130 

#define ARRAY_ATTRIBUTE(name, size) name[size] 

#else 

#define ARRAY_ATTRIBUTE(name, size) name[size] 

#endif 

// Uniform blocks 
#if __VERSION__ >= 130 

#define BEGIN_UNIFORM_BLOCK(name) uniform name { 

#define END_UNIFORM_BLOCK() }; 

#else 

#define BEGIN_UNIFORM_BLOCK(name) 

#define END_UNIFORM_BLOCK() 

#endif 

// Input and output blocks 
#if __VERSION__ >= 150 

#define BEGIN_INPUT_BLOCK(name) in name { 
#define END_INPUT_BLOCK() }; 

#define BEGIN_OUTPUT_BLOCK(name) out name { 
#define END_OUTPUT_BLOCK() }; 

#else 

#define BEGIN_INPUT_BLOCK(name) 
#define END_INPUT_BLOCK() 

#define BEGIN_OUTPUT_BLOCK(name) 
#define END_OUTPUT_BLOCK() 

#endif 

// Texturing functions 
#if __VERSION__ >= 130 

#define TEXTURE_2D texture 
#define TEXTURE_3D texture 
#define TEXTURE_RECT texture 
#define TEXTURE_CUBE texture 

#if __VERSION__ >= 150 
#define TEXTURE_SIZE(sampler) textureSize(sampler) 
#else 
#define TEXTURE_SIZE(sampler) sampler ## _Size 
#endif 

#else 

#define TEXTURE_2D texture2D 
#define TEXTURE_3D texture3D 
#define TEXTURE_RECT texture2DRect 
#define TEXTURE_CUBE textureCube 

#endif 

// Invariance 
#if __VERSION__ >= 120 
#define INVARIANT invariant 
#else 
#define INVARIANT 
#endif 

// Attribute location 
#if defined(GL_ARB_explicit_attrib_location) 
#define LOCATION(loc)  layout(location = loc) 
#else 
#define LOCATION(loc) 
#endif 

// Geometry shader layout 
#if __VERSION__ >= 150 
#define GEOMETRY_LAYOUT_IN(from) layout (from) in 
#define GEOMETRY_LAYOUT(to, max) layout (to, max_vertices = max) out 
#else 
#define GEOMETRY_LAYOUT_IN(from) 
#define GEOMETRY_LAYOUT(to, max) 
#endif 

// @EndInterface 

En effet, y compris le shader inclus avant la source de shader, le framework peut compiler sur une large gamme de compilateurs. Bien sûr, le framework doit détecter les capacités réelles du système et définir les paramètres du compilateur afin de faire les choses correctement (pensez à un shader de ligne car la largeur de ligne> 1.0 deprecation).

Bien sûr, l'infrastructure de shader peut définir une exigence minimale. Une fois que le shader a besoin du profil de base GLSL 1.50 ou plus récent, il n'y a plus besoin du shader ci-dessus.

1
  • mis #version 110 ou 120 #version comme la première ligne de vos shaders
  • les tester dans le ShaderAnalyst d'ATI
  • tester votre code sur beaucoup de cartes graphiques réelles de différents fournisseurs
0

Lecture "OpenGL Shading Language, Bill Licea-Kane, AMD, SIGGRAPH 2009". Vous avez probablement besoin d'ajouter le code suivant à votre application afin de soutenir GLSL-140, 130 et 120 versions:

#version 150 compatibility 
+0

Merci, mais ce que j'essayais c'est d'éviter le drapeau de compatibilité, en rendant le code source shader compilable pour différentes versions en utilisant seulement le préprocesseur. – Luca

0

prendre le #version ligne de vos shaders et testez votre code sur de nombreux ordinateurs différents avec des capacités GPU variables. Vous verrez que votre compatibilité avec les shaders va augmenter. La directive #version provoque parfois l'échec d'un shader même si le GPU de cette machine peut exécuter tout le code shader lorsqu'il ne reçoit pas de numéro de version.

+0

Oui, la directive #version est insérée au moment de l'exécution en fonction des capacités du système depuis le début. Il est essentiel d'avoir un moteur évolutif; Cependant, la plupart des systèmes prennent en charge les fonctionnalités GLSL avancées. – Luca

+0

Omettre #version par défaut à GLSL 1.1 – Luca