diff --git a/src/Graphic3d/Graphic3d_TypeOfLimit.hxx b/src/Graphic3d/Graphic3d_TypeOfLimit.hxx index 6770049ea5..6c9f208dc2 100644 --- a/src/Graphic3d/Graphic3d_TypeOfLimit.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfLimit.hxx @@ -21,6 +21,8 @@ enum Graphic3d_TypeOfLimit Graphic3d_TypeOfLimit_MaxNbClipPlanes, //!< maximum number of active clipping planes Graphic3d_TypeOfLimit_MaxNbViews, //!< maximum number of views Graphic3d_TypeOfLimit_MaxTextureSize, //!< maximum size of texture + Graphic3d_TypeOfLimit_MaxViewDumpSizeX, //!< maximum width for image dump + Graphic3d_TypeOfLimit_MaxViewDumpSizeY, //!< maximum height for image dump Graphic3d_TypeOfLimit_MaxCombinedTextureUnits, //!< maximum number of combined texture units for multitexturing Graphic3d_TypeOfLimit_MaxMsaa, //!< maximum number of MSAA samples Graphic3d_TypeOfLimit_HasRayTracing, //!< indicates whether ray tracing is supported @@ -29,6 +31,7 @@ enum Graphic3d_TypeOfLimit Graphic3d_TypeOfLimit_HasBlendedOit, //!< indicates whether necessary GL extensions for Weighted, Blended OIT available (without MSAA). Graphic3d_TypeOfLimit_HasBlendedOitMsaa, //!< indicates whether necessary GL extensions for Weighted, Blended OIT available (with MSAA). Graphic3d_TypeOfLimit_HasFlatShading, //!< indicates whether Flat shading (Graphic3d_TOSM_FACET) is supported + Graphic3d_TypeOfLimit_IsWorkaroundFBO, //!< indicates whether workaround for Intel driver problem with empty FBO for images with big width is applyed. Graphic3d_TypeOfLimit_NB //!< number of elements in this enumeration }; diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 3498381c7f..125102fe75 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -158,6 +158,8 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) myTexClamp (GL_CLAMP_TO_EDGE), myMaxTexDim (1024), myMaxTexCombined (1), + myMaxDumpSizeX (1024), + myMaxDumpSizeY (1024), myMaxClipPlanes (6), myMaxMsaaSamples(0), myMaxDrawBuffers (1), @@ -1192,6 +1194,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) myMaxColorAttachments = 1; ReadGlVersion (myGlVerMajor, myGlVerMinor); myVendor = (const char* )::glGetString (GL_VENDOR); + myVendor.LowerCase(); if (!caps->ffpEnable && !IsGlGreaterEqual (2, 0)) { @@ -1212,7 +1215,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) const bool isCoreProfile = false; #else - if (myVendor.Search ("NVIDIA") != -1) + if (myVendor.Search ("nvidia") != -1) { // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW) // will use VIDEO memory as the source for buffer object operations. @@ -1415,7 +1418,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) ? OpenGl_FeatureInExtensions : OpenGl_FeatureNotAvailable); if (!IsGlGreaterEqual (3, 1) - && myVendor.Search("Qualcomm") != -1) + && myVendor.Search("qualcomm") != -1) { // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1 hasFlatShading = OpenGl_FeatureNotAvailable; @@ -1472,6 +1475,16 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined); } + GLint aMaxVPortSize[2] = {0, 0}; + glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize); + myMaxDumpSizeX = Min (aMaxVPortSize[0], myMaxTexDim); + myMaxDumpSizeY = Min (aMaxVPortSize[1], myMaxTexDim); + if (myVendor == "intel") + { + // Intel drivers have known bug with empty dump for images with width>=5462 + myMaxDumpSizeX = Min (myMaxDumpSizeX, 4096); + } + if (extAnis) { glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax); @@ -2838,6 +2851,7 @@ void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0) { addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim)); + addInfo (theDict, "Max FBO dump size", TCollection_AsciiString() + myMaxDumpSizeX + "x" + myMaxDumpSizeY); addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined)); addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples)); } diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 5f9b050230..064873eb3c 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -476,6 +476,12 @@ public: //! @return value for GL_MAX_SAMPLES Standard_Integer MaxMsaaSamples() const { return myMaxMsaaSamples; } + //! @return maximum FBO width for image dump + Standard_Integer MaxDumpSizeX() const { return myMaxDumpSizeX; } + + //! @return maximum FBO height for image dump + Standard_Integer MaxDumpSizeY() const { return myMaxDumpSizeY; } + //! @return value for GL_MAX_DRAW_BUFFERS Standard_Integer MaxDrawBuffers() const { return myMaxDrawBuffers; } @@ -905,6 +911,8 @@ private: // context info Standard_Integer myTexClamp; //!< either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1) Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE Standard_Integer myMaxTexCombined; //!< value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS + Standard_Integer myMaxDumpSizeX; //!< maximum FBO width for image dump + Standard_Integer myMaxDumpSizeY; //!< maximum FBO height for image dump Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES Standard_Integer myMaxMsaaSamples; //!< value for GL_MAX_SAMPLES Standard_Integer myMaxDrawBuffers; //!< value for GL_MAX_DRAW_BUFFERS diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index c6fbdc2860..23cba938f5 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -417,6 +417,10 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit return !aCtx.IsNull() ? aCtx->MaxCombinedTextureUnits() : 1; case Graphic3d_TypeOfLimit_MaxMsaa: return !aCtx.IsNull() ? aCtx->MaxMsaaSamples() : 0; + case Graphic3d_TypeOfLimit_MaxViewDumpSizeX: + return !aCtx.IsNull() ? aCtx->MaxDumpSizeX() : 1024; + case Graphic3d_TypeOfLimit_MaxViewDumpSizeY: + return !aCtx.IsNull() ? aCtx->MaxDumpSizeY() : 1024; case Graphic3d_TypeOfLimit_HasRayTracing: return (!aCtx.IsNull() && aCtx->HasRayTracing()) ? 1 : 0; case Graphic3d_TypeOfLimit_HasRayTracingTextures: @@ -433,6 +437,8 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit && (InquireLimit (Graphic3d_TypeOfLimit_HasBlendedOit) == 1)) ? 1 : 0; case Graphic3d_TypeOfLimit_HasFlatShading: return !aCtx.IsNull() && aCtx->hasFlatShading != OpenGl_FeatureNotAvailable ? 1 : 0; + case Graphic3d_TypeOfLimit_IsWorkaroundFBO: + return !aCtx.IsNull() && aCtx->MaxTextureSize() != aCtx->MaxDumpSizeX() ? 1 : 0; case Graphic3d_TypeOfLimit_NB: return 0; } diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index d89e2018e2..ac229f0e7c 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -2077,7 +2077,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha "Warning: flat shading requires OpenGL ES 3.0+ or GL_OES_standard_derivatives extension."); } else if (isFlatNormal - && myContext->Vendor().Search("Qualcomm") != -1) + && myContext->Vendor().Search("qualcomm") != -1) { // workaround Adreno driver bug computing reversed normal using dFdx/dFdy aDFdxSignReversion = "-"; diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 85faa0ecb2..3f3edbbe47 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -2753,19 +2753,27 @@ Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage, if (aFBOPtr.IsNull()) { - Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize); - if (theParams.TileSize > aMaxTexSize) + Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX); + Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY); + if (theParams.TileSize > aMaxTexSizeX + || theParams.TileSize > aMaxTexSizeY) { Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (") - + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail); + + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Fail); return Standard_False; } - if (aFBOVPSize.x() > aMaxTexSize - || aFBOVPSize.y() > aMaxTexSize) + if (aFBOVPSize.x() > aMaxTexSizeX + || aFBOVPSize.y() > aMaxTexSizeY) { - aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize); - aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize); + if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO)) + { + Message::DefaultMessenger ()->Send (TCollection_AsciiString ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applyed."), Message_Warning); + } + Message::DefaultMessenger()->Send (TCollection_AsciiString ("Info, tiling image dump is used, image size (") + + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Info); + aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX); + aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY); isTiling = true; } diff --git a/tests/bugs/vis/bug29020 b/tests/bugs/vis/bug29020 new file mode 100644 index 0000000000..c17ba2bf1d --- /dev/null +++ b/tests/bugs/vis/bug29020 @@ -0,0 +1,20 @@ +puts "========" +puts "0029020: Visualization, V3d_View - workaround image dump issue on Intel OpenGL driver" +puts "========" +puts "" + +pload MODELING VISUALIZATION +box b 1 1 1 +vclear +vinit View1 +vdisplay -dispMode 1 b +vtop +vfit + +#Get max size of dumped image +set anExpression {Max texture size: (\d+)} +regexp $anExpression [vglinfo] _ match + +vdump $imagedir/${casename}_max_width.png -width $match -height 100 + +vdump $imagedir/${casename}_max_height.png -width 100 -height $match