2011-04-06 14 views
5

Tengo un problema difícil en ciertas tarjetas ATI (Radeon X1650, X1550 + y otras).Error al llamar a glGetTexImage (atioglxx.dll)

El mensaje es: "El acceso a la dirección violación 6959DD46 en el módulo 'atioglxx.dll' Read de dirección 00000000"

Sucede en esta línea:

glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_FLOAT,P); 

Nota:

  • Se instalaron los últimos controladores de gráficos.
  • Funciona perfectamente en otras tarjetas.

Esto es lo que he probado hasta ahora (con las afirmaciones en el código):

  • que el puntero P es válido y asignada suficiente memoria para contener la imagen
  • texturización está habilitado: glIsEnabled (GL_TEXTURE_2D)
  • prueba de que la textura en ese momento ligado es el que yo esperaba: glGetIntegerv (GL_TEXTURE_2D_BINDING)
  • prueba de que la textura en ese momento ligado tiene las dimensiones que cabe esperar: glGetTexLevelParameteriv (GL_TEXTURE_WI DTH/altura)
  • prueba de que no hay errores se han reportado: glGetError

Pasa a todos aquellos prueba y entonces todavía falla con el mensaje.

Siento que lo he intentado todo y no tengo más ideas. ¡Realmente espero que algún GL gurú aquí pueda ayudar!

EDIT:

Después llegó a la conclusión que es probablemente un error de controlador que he publicado sobre ello aquí también: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=295137#Post295137

También probé GL_PACK_ALIGNMENT y no sirvió de nada.

Investigando un poco más encontré que solo ocurría en las texturas que he llenado previamente con píxeles usando una llamada a glCopyTexSubImage2D. Así que podría producir una solución alternativa reemplazando la llamada glCopyTexSubImage2d con llamadas a glReadPixels y luego glTexImage2D en su lugar.

Aquí está mi código actualizado:

{ 
    glCopyTexSubImage2D cannot be used here because the combination of calling 
    glCopyTexSubImage2D and then later glGetTexImage on the same texture causes 
    a crash in atioglxx.dll on ATI Radeon X1650 and X1550. 
    Instead we copy to the main memory first and then update. 
} 
// glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, PixelWidth, PixelHeight); //** 
GetMem(P, PixelWidth * PixelHeight * 4); 
glReadPixels(0, 0, PixelWidth, PixelHeight, GL_RGBA, GL_UNSIGNED_BYTE, P); 
SetMemory(P,GL_RGBA,GL_UNSIGNED_BYTE); 
+2

Suena como un error del controlador. Los controladores OpenGL de ATI tienen una mala reputación en términos de estabilidad. Las características no utilizadas por muchos programas pueden romperse. Recuperar una imagen de textura es una característica que rara vez se usa. Sice que ya descartó todas las causas posibles para el fracaso, le sugiero que informe esto como un error a AMD/ATI. – datenwolf

+0

Ok, gracias, publicaré en el foro de controladores de opengl.org. Parece que un par de ingenieros de AMD están activos allí. –

+1

+1 para probar todas las cosas correctas y enumerarlas en su pregunta. Estoy de acuerdo con que suena como un error del controlador. Asegúrese de actualizar esta pregunta si escucha algo de un desarrollador de ATI :) – luke

Respuesta

1

Es posible que tome el cuidado de la GL_PACK_ALIGNEMENT. Este parámetro te indicó el conteo de bytes más cercano para empacar la textura. Es decir, si tiene una imagen de 645 píxeles:

  • Con GL_PACK_ALIGNEMENT en 4 (valor predeterminado), tendrá 648 píxeles.
  • Con GL_PACK_ALIGNEMENT en 1, tendrá 645 píxeles.

Así que asegúrese de que el valor paquete está bien haciendo:

glPixelStorei(GL_PACK_ALIGNMENT, 1) 

Antes de que su glGetTexImage(), o alinear la textura de su memoria en el GL_PACK_ALIGNEMENT.

0

Esto es muy probablemente un error del controlador. Después de haber escrito apis en 3D, es incluso fácil de ver cómo. Está haciendo algo que es realmente extraño y raro que esté cubierto por la prueba: convierta datos flotantes a 8 bits durante la carga. Nadie va a optimizar ese camino. Deberías reconsiderar lo que estás haciendo en primer lugar. La función de conversión de CPU genérica de conversión probablemente entra en acción allí y alguien arruinó una tabla que maneja la asignación de búferes temporales para eso. Realmente debería reconsiderar el uso de un formato flotante externo con un formato interno de 8 bits. Conversiones como esa en la API api generalmente apuntan a errores de programación. Si sus datos son flotantes y desea mantenerlos como tales, debería usar una textura flotante y no RGBA. Si quieres 8 bits, ¿por qué está flotando tu entrada?

+0

Estoy de acuerdo con usted en general, pero dado que glGetTexImage toma un parámetro de tipo, debería ser fácil de cubrir con pruebas unitarias de esa función. También probé para mantener el formato constante (GL_FLOAT hasta el final) pero el error permaneció. Fue la combinación específica de glCopyTexSubImage2D seguida de glGetTexImage la que causó el error. –

+0

En realidad, leí mal la publicación original y no vi la opción Obtener en glGetTexImage. Esa función casi se considera depuración solamente. En principio tienes razón sobre las pruebas unitarias, pero la gl api es tan grande que no es realmente factible. 20 formatos internos, 20 externos, 20 estados. Cargar, copiar, descargar, mapear. Es solo para muchas combinaciones. Y tanto copiar como obtener son características adicionales. – starmole

Cuestiones relacionadas