2012-02-02 23 views
47

Mi código se acerca a la administración de sombreadores GLSL, que crea cada sombreador y el programa asociado y elimina cada sombreador y programa. Hace poco leí http://www.opengl.org/wiki/GLSL_Object y no se hace constar que:Forma correcta de eliminar el sombreador GLSL?

El objeto de sombreado, debido a que se adjunta al objeto de programa, se seguir existiendo, incluso si elimina el objeto de sombreado. Solo el sistema borrará cuando ya no esté adjunto a ningún objeto del programa (y cuando el usuario haya pedido eliminarlo, por supuesto).

Cómo llego esto correctamente, si llamo glDeleteShader() en el objeto de sombreado después de enlazar con el programa, sólo necesito para seguir el programa? ¿Es seguro asumir que esto es siempre cierto?

Respuesta

56

Sí, de hecho, es muy conveniente separar y eliminar los objetos del sombreador lo antes posible. De esta forma, el controlador puede liberar toda la memoria que está utilizando para guardar una copia de la fuente de sombreado y el código de objeto no vinculado, que puede ser bastante importante. Las medidas que he hecho indican que NO borrar los objetos de sombreado aumenta el uso de memoria incremental por shader por 5-10x

+1

Incluso si es, por supuesto, la misma recomendación ya dada, +1 para el argumento de la memoria práctica y las mediciones. –

+14

Aunque lo que diga es correcto de acuerdo con [la documentación] (http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml) ("Después del funcionamiento del enlace, las aplicaciones pueden modificar libremente el sombreador adjunto objetos, compilar objetos de sombreado adjuntos, separar objetos de sombreado, eliminar objetos de sombreado y adjuntar objetos de sombreado adicionales."), Me he encontrado con algunos controladores de mal comportamiento que no les gusta cuando sueltas shaders, particularmente en plataformas móviles. Como un problema relacionado con esto me dejó frustrado durante varios días, te recomiendo que NO separe los shaders después de un enlace (eliminar está bien). –

+4

El problema es que simplemente borrar el sombreador sin separarlo podría no liberar la memoria, podría disminuir un conteo de referencia que no irá a 0 hasta que separe el sombreador. el sombreador aún está conectado, el usuario puede volver a llamar al enlace para volver a vincular el programa, por lo que el controlador necesita mantener suficiente información para hacerlo. Por lo tanto, debe sacrificar el uso de memoria con posibles problemas en los controladores rotos ... –

6

Sí. Puede eliminar el sombreador de forma segura a continuación. De hecho, esta es la forma preferida, porque tiene menos mantenimiento. No necesita realizar un seguimiento de qué eliminar y no puede olvidarse de hacerlo. Y, todavía funcionará.

"Eliminación" shader, al igual que con todos los objetos OpenGL, simplemente establece un indicador que dice que no lo necesita más. OpenGL lo mantendrá durante todo el tiempo que lo necesite y realizará la eliminación real en cualquier momento posterior (lo más probable, aunque no necesariamente, una vez que se haya eliminado el programa).

+1

De hecho, incluso puede separar los sombreadores después de la vinculación (en realidad, solo contienen código que luego entra completamente en el programa) para que se eliminen inmediatamente. –

13

En general, la forma en que funciona la gestión de objetos de sombreado es simple. Los objetos Shader realmente no hacen , por lo que no tiene sentido rastrearlos en absoluto. Los objetos Shader deberían existir por el tiempo suficiente para vincular con éxito un objeto de programa. Después de ese tiempo, los sombreadores deberían separarse del programa y eliminarse.

Lo anterior supone que no está intentando utilizar el objeto de sombreado para vincularlo con un programa diferente, por supuesto. Eso es ciertamente posible. En ese caso, debe eliminar sus objetos de sombreado después de haber vinculado todos sus programas.

3

En resumen: después glLinkProgram() llamada glDeleteShader() para cada shader, esto los marca para su eliminación y cuando el programa ya no es necesario llame al glDeleteProgram() - esta llamada no solo borra el programa sino que también desconecta todos los sombreadores conectados y los elimina (si no los utiliza ningún otro programa).

Por lo tanto, normalmente no tiene que llamar al glDetachShader(). Lea los documentos para glDeleteProgram().

Cuestiones relacionadas