2011-07-01 14 views
14

Como las tarjetas de hoy parecen tener una lista de comandos de renderización y solo para una llamada a glFlush o glFinish, ¿el doble buffer realmente es necesario? Un juego OpenGL que estoy desarrollando en Linux (tarjeta radeon ATI Mobility) con SDL/OpenGL realmente parpadea menos cuando SDL_GL_swapbuffers() se reemplaza por glFinish() y con SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,0) en el código init. ¿Es este un caso particular de mi tarjeta o hay tales cosas en todas las tarjetas?¿Se necesita más memoria intermedia?

EDIT: Descubrí que la causa de esto es KWin. Parece que, como dijo el hombre lobo, la causa fue la composición sin sincronización. Cuando apagué la composición de KWin, el juego funciona bien sin CUALQUIER parche de código fuente

Respuesta

19

El doble almacenamiento en memoria intermedia y glFinish son dos cosas muy diferentes.

glFinish bloquea el programa, hasta que se completen todas las operaciones de dibujo.

El doble almacenamiento en memoria intermedia se utiliza para ocultar el proceso de representación del usuario. Sin doble almacenamiento en búfer, todas y cada una de las operaciones de dibujo se verían inmediatamente, suponiendo que la frecuencia de actualización de la pantalla es infinitamente alta. En la práctica, obtendrá algunos artefactos de visualización, como partes de la escena visibles en un estado, el resto no visible o en otro estado, la imagen podría estar incompleta, etc. El doble almacenamiento en memoria intermedia evita esto al renderizar primero en un buffer posterior, y solo después de que el renderizado haya finalizado, se intercambia esto con el buffer frontal, que se envía al dispositivo de visualización.

Hoy en día, la gestión de ventanas de composición se hace prevalente: Windows tiene Aero, MacOS X Quartz Extreme y en Linux al menos Unity y la shell GNOME3 utilizan la composición si está disponible. El punto es: Compositing crea técnicamente doble buffer: Windows dibuja búferes fuera de la pantalla y de estos se compone la pantalla final. Entonces, si está ejecutando en una máquina con composición, entonces el doble buffer es algo redundante si se realiza en su programa, y ​​todo lo que tomaría sería algún tipo de mecanismo de sincronización, para decirle al compositor cuándo está listo el siguiente fotograma. MacOS X tiene esto. X11 todavía carece de un esquema de sincronización adecuada, ver este post en la lista de correo: http://lists.freedesktop.org/archives/xorg/2004-May/000607.html

TL; DR: Doblebuffering y glFinish son cosas diferentes, y lo que necesita el doble buffer (de algún tipo) de hacer las cosas se ven bien.

+0

La publicación mencionada tiene más de 6 años. ¿X11 todavía carece de un esquema de sincronización? ¿Y qué hay de Windows? –

+3

Además de la explicación de datenwolf, debe tener en cuenta que, por lo general, _no_ querrá llamar a 'glFlush' o' glFinish', excepto quizás en algunos casos especiales muy muy raros. 'glFinish' no hace nada de que' (wgl | glx) SwapBuffers' no lo haga (se presume que vsync está habilitado), y 'glFlush' solo vacía los comandos en cola y le indica al servidor que comience a procesarlos, lo cual no hace nada en el mejor caso (pero es una llamada inútil y el cambio de contexto), y resulta en un peor rendimiento en el peor de los casos (debido a la programación sub-óptima de los recursos de la GPU). – Damon

+1

Idealmente, querrás lanzar tantos comandos en el GL como puedas, con dependencias repartidas lo más que puedas (es decir, si usas una textura, primero envía los comandos para definir la imagen de la textura, establece el estado de la textura, etc. luego envíe algunos comandos que hagan otra cosa, y solo entonces dibuje algo que use esta textura).Esto asegura que a) los comandos en la secuencia de comandos tienen menos probabilidades de bloquearse debido a dependencias yb) el controlador puede programar algunos otros comandos para utilizar la GPU (¿OpenCL u otro programa?) Si los comandos en su cola se pararan. – Damon

2

Supongo que tiene más que ver con lo que estás renderizando o con tu hardware que con cualquier cosa que se pueda generalizar a algo que no esté en tu máquina . Entonces no: no intentes hacer esto.

Ah, y no olvides multisampling. Muchas implementaciones solo multimuestran el buffer posterior; el búfer frontal no tiene múltiples muestreos. Al hacer un intercambio, se reducirá la resolución del búfer de muestreo múltiple.

Cuestiones relacionadas