Commit d2c542a2 authored by Burlen Loring's avatar Burlen Loring Committed by Code Review
Browse files

Merge topic 'opengl-error-hunt' into master

4d5cbfb6 OpenGL driver version detection and OS Mesa features
parents c343d16a 4d5cbfb6
......@@ -56,25 +56,25 @@ bool vtkOpenGL2ContextDevice2D::IsSupported(vtkViewport *viewport)
vtkOpenGLRenderer *gl = vtkOpenGLRenderer::SafeDownCast(viewport);
if (gl)
{
vtkOpenGLRenderWindow *win =
vtkOpenGLRenderWindow::SafeDownCast(gl->GetRenderWindow());
vtkOpenGLExtensionManager *man = win->GetExtensionManager();
if (man->ExtensionSupported("GL_VERSION_2_0"))
{
supported = true;
}
}
vtkOpenGLRenderWindow *context =
vtkOpenGLRenderWindow::SafeDownCast(gl->GetRenderWindow());
if (supported)
{
// Workaround for a bug in mesa - support for non-power of two textures is
// poor at best. Disable, and use power of two textures for mesa rendering.
const char *gl_version =
reinterpret_cast<const char *>(glGetString(GL_VERSION));
const char *mesa_version = strstr(gl_version, "Mesa");
if (mesa_version != 0)
vtkOpenGLExtensionManager *extensions
= context->GetExtensionManager();
bool ogl_support
= extensions->ExtensionSupported("GL_VERSION_2_0")==1;
// NPOT textures work in OS Mesa > 8.0.0
// Mesa's other renderer's need to be validated individually
bool driver_support
= (!extensions->DriverIsMesa()
|| (extensions->DriverGLRendererIsOSMesa()
&& extensions->DriverVersionAtLeast(8)));
if ( ogl_support && driver_support )
{
supported = false;
supported = true;
}
}
......
......@@ -1379,12 +1379,10 @@ bool vtkOpenGLContextDevice2D::LoadExtensions(vtkOpenGLExtensionManager *m)
this->Storage->GLSL = false;
}
// Workaround for a bug in mesa - support for non-power of two textures is
// poor at best. Disable, and use power of two textures for mesa rendering.
const char *gl_version =
reinterpret_cast<const char *>(glGetString(GL_VERSION));
const char *mesa_version = strstr(gl_version, "Mesa");
if (mesa_version != 0)
// disable NPOT textures for Mesa
// NPOT textures work in OS Mesa >= 8.0.0
if ( m->DriverIsMesa()
&& !(m->DriverGLRendererIsOSMesa() && m->DriverVersionAtLeast(8)))
{
this->Storage->PowerOfTwoTextures = true;
this->TextRenderer->SetScaleToPowerOfTwo(true);
......
......@@ -438,6 +438,19 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/vtkOpenGLError.h.in
${CMAKE_CURRENT_BINARY_DIR}/vtkOpenGLError.h)
# For testing new driver releases
set(VTK_IGNORE_GLDRIVER_BUGS
OFF CACHE BOOL
"Enable buggy OpenGL drivers for testing.")
mark_as_advanced(VTK_IGNORE_GLDRIVER_BUGS)
if (VTK_IGNORE_GLDRIVER_BUGS)
set_property(SOURCE
vtkOpenGLExtensionManager.cxx
APPEND PROPERTY
COMPILE_DEFINITIONS
VTK_IGNORE_GLDRIVER_BUGS)
endif()
vtk_module_library(vtkRenderingOpenGL ${Module_SRCS})
target_link_libraries(vtkRenderingOpenGL ${OPENGL_LIBRARIES} ${extra_libs})
if(VTK_USE_X)
......
......@@ -123,6 +123,25 @@ int LoadOpenGLExtension(int argc, char *argv[])
cout << "GL_VERSION: " << (gl_version ? gl_version : "(null)") << endl;
cout << "GL_RENDERER: " << (gl_renderer ? gl_renderer : "(null)") << endl;
extensions->Update();
cout
<< endl
<< "DriverGLVersion = " << extensions->GetDriverGLVersion() << endl
<< "DriverGLVendor = " << extensions->GetDriverGLVendor() << endl
<< "DriverGLRenderer = " << extensions->GetDriverGLRenderer() << endl
<< "DriverGLVersionMajor = " << extensions->GetDriverGLVersionMajor() << endl
<< "DriverGLVersionMinor = " << extensions->GetDriverGLVersionMinor() << endl
<< "DriverGLVersionPatch = " << extensions->GetDriverGLVersionPatch() << endl
<< "DriverVersionMajor = " << extensions->GetDriverVersionMajor() << endl
<< "DriverVersionMinor = " << extensions->GetDriverVersionMinor() << endl
<< "DriverVersionPatch = " << extensions->GetDriverVersionPatch() << endl
<< "DriverIsATI = " << extensions->DriverIsATI() << endl
<< "DriverIsNvidia = " << extensions->DriverIsNvidia() << endl
<< "DriverIsIntel = " << extensions->DriverIsIntel() << endl
<< "DriverIsMesa = " << extensions->DriverIsMesa() << endl
<< "DriverGLRendererIsOSMesa = " << extensions->DriverGLRendererIsOSMesa() << endl
<< "DriverIsMicrosoft = " << extensions->DriverIsMicrosoft() << endl;
cout << endl;
renwin->Print(cout);
......
......@@ -52,7 +52,7 @@
// Make sure to have a valid OpenGL context current on the calling thread
// before calling it. Defined in TestGenericVertexAttributesGLSLAlphaBlending.
bool MesaHasVTKBug8135();
bool MesaHasVTKBug8135(vtkRenderWindow *);
int TestGaussianBlurPass(int argc, char* argv[])
{
......@@ -176,7 +176,7 @@ int TestGaussianBlurPass(int argc, char* argv[])
renWin->Render();
int retVal;
if(MesaHasVTKBug8135())
if(MesaHasVTKBug8135(renWin))
{
// Mesa will crash if version<7.3
cout<<"This version of Mesa would crash. Skip the test."<<endl;
......
......@@ -34,7 +34,7 @@
// Make sure to have a valid OpenGL context current on the calling thread
// before calling it. Defined in TestTranslucentLUTDepthPeelingPass.cxx.
bool MesaHasVTKBug8135();
bool MesaHasVTKBug8135(vtkRenderWindow *);
int TestGenericVertexAttributesGLSLAlphaBlending(int argc, char *argv[])
{
......@@ -94,7 +94,7 @@ int TestGenericVertexAttributesGLSLAlphaBlending(int argc, char *argv[])
renWin->Render();
int retVal;
if(MesaHasVTKBug8135())
if(MesaHasVTKBug8135(renWin))
{
// Mesa will crash if version<7.3
cout<<"This version of Mesa would crash. Skip the test."<<endl;
......
......@@ -46,7 +46,7 @@
// Make sure to have a valid OpenGL context current on the calling thread
// before calling it. Defined in TestGenericVertexAttributesGLSLAlphaBlending.
bool MesaHasVTKBug8135();
bool MesaHasVTKBug8135(vtkRenderWindow *);
int TestGenericVertexAttributesGLSLDepthPeelingPass(int argc, char *argv[])
{
......@@ -149,7 +149,7 @@ int TestGenericVertexAttributesGLSLDepthPeelingPass(int argc, char *argv[])
renWin->Render();
int retVal;
if(MesaHasVTKBug8135())
if(MesaHasVTKBug8135(renWin))
{
// Mesa will crash if version<7.3
cout<<"This version of Mesa would crash. Skip the test."<<endl;
......
......@@ -26,6 +26,8 @@
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkActor.h"
#include "vtkImageSinusoidSource.h"
......@@ -50,29 +52,15 @@
// Make sure to have a valid OpenGL context current on the calling thread
// before calling it.
bool MesaHasVTKBug8135()
bool MesaHasVTKBug8135(vtkRenderWindow *renwin)
{
// GL_VENDOR cannot be used because it can be "Brian Paul" or "Mesa project"
// GL_RENDERER cannot be used because it can be "Software Rasterizer" or
// "Mesa X11"
// GL_VERSION is more robust. It has things like "2.0 Mesa 7.0.4" or
// "2.1 Mesa 7.2" or "2.1 Mesa 7.3-devel"
bool result=false;
const char *gl_version=
reinterpret_cast<const char *>(glGetString(GL_VERSION));
const char *mesa_version=strstr(gl_version,"Mesa");
if(mesa_version!=0)
{
int mesa_major=0;
int mesa_minor=0;
if(sscanf(mesa_version,"Mesa %d.%d",&mesa_major, &mesa_minor)>=2)
{
result=mesa_major<7 || (mesa_major==7 && mesa_minor<3);
}
}
return result;
vtkOpenGLRenderWindow *context
= vtkOpenGLRenderWindow::SafeDownCast(renwin);
vtkOpenGLExtensionManager *extmgr
= context->GetExtensionManager();
return (extmgr->DriverIsMesa() && !extmgr->DriverVersionAtLeast(7,3));
}
int TestTranslucentLUTDepthPeelingPass(int argc, char* argv[])
......@@ -170,7 +158,7 @@ int TestTranslucentLUTDepthPeelingPass(int argc, char* argv[])
renWin->Render();
int retVal;
if(MesaHasVTKBug8135())
if(MesaHasVTKBug8135(renWin))
{
// Mesa will crash if version<7.3
cout<<"This version of Mesa would crash. Skip the test."<<endl;
......
......@@ -352,7 +352,7 @@ void vtkDepthPeelingPass::Render(const vtkRenderState *s)
if(l>1) // some higher layer, we allocated some tex unit in RenderPeel()
{
vtkOpenGLRenderWindow *context
= dynamic_cast<vtkOpenGLRenderWindow*>(this->Prog->GetContext());
= vtkOpenGLRenderWindow::SafeDownCast(this->Prog->GetContext());
vtkTextureUnitManager *m=context->GetTextureUnitManager();
m->Free(this->ShadowTexUnit);
m->Free(this->OpaqueShadowTexUnit);
......@@ -552,6 +552,15 @@ void vtkDepthPeelingPass::CheckSupport(vtkOpenGLRenderWindow *w)
glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
bool supportsAtLeast8AlphaBits=alphaBits>=8;
// force alpha blending
// Mesa does not support true linking of shaders (VTK bug 8135)
// and Mesa 7.2 just crashes during the try-compile.
// os mesa 9.1.4 some tests fail
// TODO verify that this is still an issue on newer ATI devices
int driver_support
= (!extensions->DriverIsATI() && !extensions->DriverIsMesa())
|| extensions->GetIgnoreDriverBugs("ATI and Mesa depth peeling bugs");
this->IsSupported =
supports_depth_texture &&
supports_shadow &&
......@@ -564,7 +573,8 @@ void vtkDepthPeelingPass::CheckSupport(vtkOpenGLRenderWindow *w)
supports_multitexture &&
supports_GL_ARB_texture_rectangle &&
supports_edge_clamp &&
supportsAtLeast8AlphaBits;
supportsAtLeast8AlphaBits &&
driver_support;
if(this->IsSupported)
{
......@@ -656,25 +666,9 @@ void vtkDepthPeelingPass::CheckSupport(vtkOpenGLRenderWindow *w)
{
vtkDebugMacro(<<"at least 8 alpha bits is not supported");
}
}
if(this->IsSupported)
{
// Some OpenGL implementations are buggy so depth peeling does not
// work:
// - ATI
// - Mesa git does not support true linking of shaders (VTK bug 8135)
// and Mesa 7.2 just crashes during the try-compile.
// Do alpha blending always.
const char* gl_renderer =
reinterpret_cast<const char *>(glGetString(GL_RENDERER));
int isATI = strstr(gl_renderer, "ATI") != 0;
bool isMesa=strstr(gl_renderer, "Mesa") != 0;
if(isMesa || isATI)
if (!driver_support)
{
this->IsSupported = false;
vtkDebugMacro(<<"buggy driver (Mesa or ATI)");
}
}
......@@ -779,7 +773,7 @@ int vtkDepthPeelingPass::RenderPeel(const vtkRenderState *s,
{
// allocate texture units.
vtkOpenGLRenderWindow *context
= dynamic_cast<vtkOpenGLRenderWindow*>(this->Prog->GetContext());
= vtkOpenGLRenderWindow::SafeDownCast(this->Prog->GetContext());
vtkTextureUnitManager *m = context->GetTextureUnitManager();
......
......@@ -101,7 +101,14 @@ bool vtkFrameBufferObject::IsSupported(vtkRenderWindow *win)
bool fbo = mgr->ExtensionSupported("GL_EXT_framebuffer_object")==1;
bool fboBlit = mgr->ExtensionSupported("GL_EXT_framebuffer_blit")==1;
return tex3D && depthTex && drawBufs && fbo && fboBlit;
// On 1.4 Mesa 8.0.4 with Mesa DRI Intel(R) 945GME
// shader fails to compile "gl_FragData[1] = ..."
// 0:46(15): error: array index must be < 1
bool driver
= !(mgr->DriverIsMesa()
&& mgr->DriverGLVersionIs(1,4));
return tex3D && depthTex && drawBufs && fbo && fboBlit && driver;
}
return false;
}
......@@ -110,7 +117,7 @@ bool vtkFrameBufferObject::IsSupported(vtkRenderWindow *win)
bool vtkFrameBufferObject::LoadRequiredExtensions(vtkRenderWindow *win)
{
vtkOpenGLRenderWindow *oglRenWin
= dynamic_cast<vtkOpenGLRenderWindow*>(win);
= vtkOpenGLRenderWindow::SafeDownCast(win);
vtkOpenGLExtensionManager *mgr = oglRenWin->GetExtensionManager();
......@@ -196,7 +203,7 @@ void vtkFrameBufferObject::SetContext(vtkRenderWindow *renWin)
}
// check for support
vtkOpenGLRenderWindow *context
= dynamic_cast<vtkOpenGLRenderWindow*>(renWin);
= vtkOpenGLRenderWindow::SafeDownCast(renWin);
if ( !context
|| !this->LoadRequiredExtensions(renWin))
{
......
......@@ -124,6 +124,7 @@
#include "vtkObject.h"
#include "vtkWeakPointer.h" // needed for vtkWeakPointer.
#include <string> // needed for std::string
class vtkRenderWindow;
......@@ -261,17 +262,120 @@ public:
// Similar to LoadCorePromotedExtension().
// It loads an EXT extension into the pointers of its ARB equivalent.
virtual void LoadAsARBExtension(const char *name);
// Description:
// Return the driver's version parts. This may be used for
// fine grained feature testing.
virtual int GetDriverVersionMajor(){ return this->DriverVersionMajor; }
virtual int GetDriverVersionMinor(){ return this->DriverVersionMinor; }
virtual int GetDriverVersionPatch(){ return this->DriverVersionPatch; }
// Description:
// Get GL API version that the driver provides. This is
// often different than the GL version that VTK recognizes
// so only use this for identifying a specific driver.
virtual int GetDriverGLVersionMajor(){ return this->DriverGLVersionMajor; }
virtual int GetDriverGLVersionMinor(){ return this->DriverGLVersionMinor; }
virtual int GetDriverGLVersionPatch(){ return this->DriverGLVersionPatch; }
// Description:
// Test's for common implementors of rendering drivers. This may be used for
// fine grained feature testing. Note: DriverIsMesa succeeds for OS Mesa,
// use DriverGLRendererIsOSMessa to differentiate.
virtual bool DriverIsATI();
virtual bool DriverIsNvidia();
virtual bool DriverIsIntel();
virtual bool DriverIsMesa();
virtual bool DriverIsMicrosoft();
// Description:
// Test for a specific driver version.
virtual bool DriverVersionIs(int major);
virtual bool DriverVersionIs(int major, int minor);
virtual bool DriverVersionIs(int major, int minor, int patch);
// Description:
// Test for driver version greater than or equal
// to the named version.
virtual bool DriverVersionAtLeast(int major);
virtual bool DriverVersionAtLeast(int major, int minor);
virtual bool DriverVersionAtLeast(int major, int minor, int patch);
// Description:
// Test for the driver's GL version as reported in
// its GL_VERSION string. This is intended for driver
// identification only, use ExtensionSuppported
// to test for VTK support of a specific GL version.
virtual bool DriverGLVersionIs(int major, int minor, int patch);
virtual bool DriverGLVersionIs(int major, int minor);
// Description:
// Test for a specific renderer. This could be used
// in some cases to identify the graphics card or
// specific driver. Use HasToken to prevent false
// matches eg. avoid GeForce4 matching GeForce400
virtual bool DriverGLRendererIs(const char *str);
virtual bool DriverGLRendererHas(const char *str);
virtual bool DriverGLRendererHasToken(const char *str);
// Description:
// Test for Mesa's offscreen renderer.
virtual bool DriverGLRendererIsOSMesa();
// Description:
// Get the OpenGL version, vendor and renderer strings. These can
// be used to idnetify a specific driver.
virtual const char *GetDriverGLVendor(){ return this->DriverGLVendor.c_str(); }
virtual const char *GetDriverGLVersion(){ return this->DriverGLVersion.c_str(); }
virtual const char *GetDriverGLRenderer(){ return this->DriverGLRenderer.c_str(); }
// Description:
// When set known driver bugs are ignored during driver feature
// detection. This is used to evaluate the status of a new driver
// release to see if the bugs have been fixed. The function takes
// a description argument which, is sent to VTK's warning stream
// when the ignore flag is set. This makes the test output searchable
// for tests which have problems with certain drivers. The CMakeLists
// variable VTK_IGNORE_GLDRIVER_BUGS can be used to set this at
// build time. Default OFF.
bool GetIgnoreDriverBugs(const char *description);
vtkSetMacro(IgnoreDriverBugs, bool);
vtkBooleanMacro(IgnoreDriverBugs, bool);
//BTX
protected:
vtkOpenGLExtensionManager();
virtual ~vtkOpenGLExtensionManager();
int OwnRenderWindow;
char *ExtensionsString;
vtkTimeStamp BuildTime;
// driver specific info
std::string DriverGLVersion;
int DriverGLVersionMajor;
int DriverGLVersionMinor;
int DriverGLVersionPatch;
std::string DriverGLVendor;
std::string DriverGLRenderer;
int DriverVersionMajor;
int DriverVersionMinor;
int DriverVersionPatch;
enum DriverGLVendorIdType
{
DRIVER_VENDOR_UNKNOWN=0,
DRIVER_VENDOR_ATI,
DRIVER_VENDOR_NVIDIA,
DRIVER_VENDOR_INTEL,
DRIVER_VENDOR_MESA,
DRIVER_VENDOR_MICROSOFT
};
DriverGLVendorIdType DriverGLVendorId;
bool IgnoreDriverBugs;
virtual void InitializeDriverInformation();
virtual void ReadOpenGLExtensions();
// Description:
......
......@@ -188,8 +188,9 @@ bool vtkOpenGLProperty::RenderShaders(vtkActor* vtkNotUsed(anActor), vtkRenderer
vtkErrorMacro("the vtkOpenGLProperty need a vtkOpenGLRenderer to render.");
return false;
}
vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast(
ren->GetRenderWindow());
vtkOpenGLRenderWindow *context
= vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow());
vtkShaderProgram2* prog = oRenderer->GetShaderProgram();
if (prog)
{
......@@ -198,7 +199,6 @@ bool vtkOpenGLProperty::RenderShaders(vtkActor* vtkNotUsed(anActor), vtkRenderer
vtkOpenGLClearErrorMacro();
bool useShaders = false;
vtkShaderProgram2 *propProg;
if (this->Shading)
{
......@@ -208,18 +208,25 @@ bool vtkOpenGLProperty::RenderShaders(vtkActor* vtkNotUsed(anActor), vtkRenderer
{
propProg = 0;
}
bool useShaders = false;
if (prog || propProg)
{
useShaders = vtkShaderProgram2::IsSupported(context);
if (useShaders)
bool shader_support = vtkShaderProgram2::IsSupported(context);
// mesa doesn't support separate compilation units
// os mesa:
// 9.1.4 some tests failing
vtkOpenGLExtensionManager *extensions = context->GetExtensionManager();
bool driver_support
= !extensions->DriverIsMesa()
|| extensions->GetIgnoreDriverBugs(
"Mesa support for separate compilation units");
if (shader_support && driver_support)
{
const char *gl_renderer =
reinterpret_cast<const char *>(glGetString(GL_RENDERER));
if (strstr(gl_renderer, "Mesa") != 0)
{
useShaders = false;
vtkErrorMacro(<<"Mesa does not support separate compilation units.");
}
useShaders = true;
}
else
{
......
......@@ -1607,13 +1607,15 @@ int vtkOpenGLRenderWindow::CreateHardwareOffScreenWindow(int width, int height)
int supports_GL_EXT_framebuffer_object=
extensions->ExtensionSupported("GL_EXT_framebuffer_object");
// TODO Mesa 6.5.1 is from 2006 verify that this is still an issue
// with newer releases
// We skip it if you use Mesa. Even if the VTK offscreen test passes (OSCone)
// with Mesa, all the Paraview batch test are failing (Mesa 6.5.1 or CVS)
// After too much time spent to investigate this case, we just skip it.
const GLubyte *openglRenderer=glGetString(GL_RENDERER);
const char *substring=strstr(reinterpret_cast<const char *>(openglRenderer),
"Mesa");
int isMesa=substring!=0;
int isMesa
= extensions->DriverGLRendererHas("Mesa")
&& !extensions->GetIgnoreDriverBugs("Mesa 6.5.1 pvbatch offscreen bug");
int supports_texture_non_power_of_two=
extensions->ExtensionSupported("GL_VERSION_2_0") ||
extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two");
......
......@@ -377,6 +377,12 @@ void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
int supportsAtLeast8AlphaBits=alphaBits>=8;
// TODO verify that newer ATI devices still have the issue
int driver_support
= (!extensions->DriverIsATI()
&& (!extensions->DriverIsMesa() || extensions->DriverVersionAtLeast(6,5,3)))
|| extensions->GetIgnoreDriverBugs("ATI depth peeling bug." );
this->DepthPeelingIsSupported =
supports_depth_texture &&
supports_shadow &&
......@@ -389,7 +395,8 @@ void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
supports_multitexture &&
supports_GL_ARB_texture_rectangle &&
supports_edge_clamp &&
supportsAtLeast8AlphaBits;
supportsAtLeast8AlphaBits &&
driver_support;
if(this->DepthPeelingIsSupported)
{
......@@ -481,6 +488,10 @@ void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
{
vtkDebugMacro(<<"at least 8 alpha bits is not supported");
}
if (!driver_support)
{
vtkDebugMacro(<<"buggy driver (Mesa < 6.5.3 or ATI)");
}
}
extensions->Delete();
......@@ -508,44 +519,6 @@ void vtkOpenGLRenderer::DeviceRenderTranslucentPolygonalGeometry()
"GL_ARB_texture_rectangle in GLSL code");
}
}
if(this->DepthPeelingIsSupported)
{
// Some OpenGL implementations are buggy so depth peeling does not work:
// - ATI
// - Mesa 6.5.2 and lower
// Do alpha blending always.
const char* gl_renderer =
reinterpret_cast<const char *>(glGetString(GL_RENDERER));
int isATI = strstr(gl_renderer, "ATI") != 0;
const char* gl_version =
reinterpret_cast<const char *>(glGetString(GL_VERSION));
if(const char* mesa_version = strstr(gl_version, "Mesa"))
{
// Mesa versions 6.5.3 and higher work. Versions much lower
// than 6.5.2 do not report support for the extensions to
// get this far. Therefore if parsing of the version fails
// just assume it is a higher version that changed the
// format of the version string.
int mesa_major = 0;
int mesa_minor = 0;
int mesa_patch = 0;
if(sscanf(mesa_version, "Mesa %d.%d.%d",
&mesa_major, &mesa_minor, &mesa_patch) >= 2)
{
if(mesa_major < 6 ||
(mesa_major == 6 && mesa_major < 5) ||
(mesa_major == 6 && mesa_minor == 5 && mesa_patch < 3))
{
this->DepthPeelingIsSupported = 0;
}