diff options
Diffstat (limited to 'indra/llrender')
29 files changed, 509 insertions, 113 deletions
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index ccff7c7a8c..d48b508ddc 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -108,3 +108,4 @@ target_link_libraries(llrender OpenGL::GLU ) +include(LibraryInstall) diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 26e4aaad52..53691bafe2 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -214,7 +214,9 @@ void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& ra enableTexture(0); bind(); mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +#if GL_VERSION_3_2 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#endif glGenerateMipmap(GL_TEXTURE_CUBE_MAP); gGL.getTexUnit(0)->disable(); disable(); diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 4f5e13765a..fb35e002df 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -105,16 +105,48 @@ LLCubeMapArray::LLCubeMapArray() } +LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTextureStage(0) +{ + mWidth = width; + mCount = count; + + // Allocate a new cubemap array with the same criteria as the incoming cubemap array + allocate(mWidth, lhs.mImage->getComponents(), count, lhs.mImage->getUseMipMaps(), lhs.mHDR); + + // Copy each cubemap from the incoming array to the new array + U32 min_count = std::min(count, lhs.mCount); + for (U32 i = 0; i < min_count * 6; ++i) + { + U32 src_resolution = lhs.mWidth; + U32 dst_resolution = mWidth; + { + GLint components = GL_RGB; + if (mImage->getComponents() == 4) + components = GL_RGBA; + GLint format = GL_RGB; + + // Handle different resolutions by scaling the image + LLPointer<LLImageRaw> src_image = new LLImageRaw(lhs.mWidth, lhs.mWidth, lhs.mImage->getComponents()); + glGetTexImage(GL_TEXTURE_CUBE_MAP_ARRAY, 0, components, GL_UNSIGNED_BYTE, src_image->getData()); + + LLPointer<LLImageRaw> scaled_image = src_image->scaled(mWidth, mWidth); + glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i, mWidth, mWidth, 1, components, GL_UNSIGNED_BYTE, scaled_image->getData()); + } + } +} + LLCubeMapArray::~LLCubeMapArray() { } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr) { U32 texname = 0; mWidth = resolution; mCount = count; + mHDR = hdr; + LLImageGL::generateTextures(1, &texname); mImage = new LLImageGL(resolution, resolution, components, use_mips); @@ -127,13 +159,19 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us bind(0); free_cur_tex_image(); - U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F; + U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F; + if (!hdr) + { + format = components == 4 ? GL_RGBA8 : GL_RGB8; + } U32 mip = 0; U32 mip_resolution = resolution; while (mip_resolution >= 1) { +#if GL_VERSION_4_0 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, format, mip_resolution, mip_resolution, count * 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); +#endif if (!use_mips) { diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index 675aaaf07c..6b4288cb23 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -36,6 +36,7 @@ class LLCubeMapArray : public LLRefCount { public: LLCubeMapArray(); + LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count); static GLenum sTargets[6]; @@ -52,7 +53,7 @@ public: // components - number of components per pixel // count - number of cube maps in the array // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used - void allocate(U32 res, U32 components, U32 count, bool use_mips = true); + void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true); void bind(S32 stage); void unbind(); @@ -73,4 +74,5 @@ protected: U32 mWidth = 0; U32 mCount = 0; S32 mTextureStage; + bool mHDR; }; diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp index ee9cfd0719..6a3af1e608 100644 --- a/indra/llrender/llfontbitmapcache.cpp +++ b/indra/llrender/llfontbitmapcache.cpp @@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp mBitmapHeight = image_height; S32 num_components = getNumComponents(bitmap_type); - mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); + mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components)); bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1; LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num); @@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp } // Make corresponding GL image. - mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false)); + mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false)); LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num); // Start at beginning of the new image. @@ -141,6 +141,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp bitmap_num = getNumBitmaps(bitmap_type) - 1; mCurrentOffsetX[bitmap_idx] += width + 1; + mGeneration++; return true; } @@ -168,6 +169,7 @@ void LLFontBitmapCache::reset() mBitmapWidth = 0; mBitmapHeight = 0; + mGeneration++; } //static diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index f2dfd87877..0ae4e6bed0 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -63,6 +63,7 @@ public: U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? static_cast<U32>(mImageRawVec[static_cast<U32>(bitmapType)].size()) : 0U; } S32 getBitmapWidth() const { return mBitmapWidth; } S32 getBitmapHeight() const { return mBitmapHeight; } + S32 getCacheGeneration() const { return mGeneration; } protected: static U32 getNumComponents(EFontGlyphType bitmap_type); @@ -74,6 +75,7 @@ private: S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 }; S32 mMaxCharWidth = 0; S32 mMaxCharHeight = 0; + S32 mGeneration = 0; std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)]; std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)]; }; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 6128e03fa7..2d8b8a0fee 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -52,7 +52,9 @@ #include "llfontbitmapcache.h" #include "llgl.h" -#define ENABLE_OT_SVG_SUPPORT +#if !defined(LL_NO_OTSVG) + #define ENABLE_OT_SVG_SUPPORT +#endif FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; @@ -87,7 +89,7 @@ LLFontManager::LLFontManager() FT_Done_FreeType(gFTLibrary); } -#ifdef ENABLE_OT_SVG_SUPPORT +#if defined(ENABLE_OT_SVG_SUPPORT) SVG_RendererHooks hooks = { LLFontFreeTypeSvgRenderer::OnInit, LLFontFreeTypeSvgRenderer::OnFree, @@ -146,7 +148,6 @@ LLFontFreetype::LLFontFreetype() mIsFallback(false), mFTFace(NULL), mRenderGlyphCount(0), - mAddGlyphCount(0), mStyle(0), mPointSize(0) { @@ -483,8 +484,8 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type continue; } glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch); - if (glyph_index) - { + if (glyph_index) + { return addGlyphFromFont(pair.first, wch, glyph_index, glyph_type); } @@ -552,7 +553,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l return NULL; llassert(!mIsFallback); - fontp->renderGlyph(requested_glyph_type, glyph_index); + fontp->renderGlyph(requested_glyph_type, glyph_index, wch); EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified; switch (fontp->mFTFace->glyph->bitmap.pixel_mode) @@ -574,7 +575,6 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l S32 pos_x, pos_y; U32 bitmap_num; mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num); - mAddGlyphCount++; LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type); gi->mXBitmapOffset = pos_x; @@ -697,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const } } -void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const +void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const { if (mFTFace == NULL) return; @@ -712,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags); if (FT_Err_Ok != error) { + if (error == FT_Err_Out_Of_Memory) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL; + } + std::string message = llformat( - "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", - error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); + "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d", + error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags); LL_WARNS_ONCE() << message << LL_ENDL; error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); + if (FT_Err_Invalid_Outline == error + || FT_Err_Invalid_Composite == error + || (FT_Err_Ok != error && LLStringOps::isEmoji(wch))) + { + // value~0 always corresponds to the 'missing glyph' + error = FT_Load_Glyph(mFTFace, 0, FT_LOAD_FORCE_AUTOHINT); + if (FT_Err_Ok != error) + { + LL_ERRS() << "Loading fallback for char '" << (U32)wch << "', glyph " << glyph_index << " failed with error : " << (S32)error << LL_ENDL; + } + } llassert_always_msg(FT_Err_Ok == error, message.c_str()); } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index eba89f5def..783bf4a4b3 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -156,7 +156,7 @@ private: bool hasGlyph(llwchar wch) const; // Has a glyph for this character LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) - void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const; + void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const; void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; std::string mName; @@ -187,7 +187,6 @@ private: mutable LLFontBitmapCache* mFontBitmapCachep; mutable S32 mRenderGlyphCount; - mutable S32 mAddGlyphCount; }; #endif // LL_FONTFREETYPE_H diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp index 71f751329e..04825ae8a3 100644 --- a/indra/llrender/llfontfreetypesvg.cpp +++ b/indra/llrender/llfontfreetypesvg.cpp @@ -34,9 +34,17 @@ #endif #define NANOSVG_IMPLEMENTATION +#if __FreeBSD__ +#include <nanosvg.h> +#else #include <nanosvg/nanosvg.h> +#endif #define NANOSVGRAST_IMPLEMENTATION +#if __FreeBSD__ +#include <nanosvgrast.h> +#else #include <nanosvg/nanosvgrast.h> +#endif #if LL_WINDOWS #pragma warning (pop) @@ -80,6 +88,7 @@ void LLFontFreeTypeSvgRenderer::OnDataFinalizer(void* objectp) //static FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer*) { +#ifndef LL_NO_OTSVG FT_SVG_Document document = static_cast<FT_SVG_Document>(glyph_slot->other); llassert(!glyph_slot->generic.data || !cache || glyph_slot->glyph_index == ((LLSvgRenderData*)glyph_slot->generic.data)->GlyphIndex); @@ -166,6 +175,9 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, } return FT_Err_Ok; +#else + return FT_Err_Unimplemented_Feature; +#endif } // static diff --git a/indra/llrender/llfontfreetypesvg.h b/indra/llrender/llfontfreetypesvg.h index 4170cab273..94b83d5fff 100644 --- a/indra/llrender/llfontfreetypesvg.h +++ b/indra/llrender/llfontfreetypesvg.h @@ -29,7 +29,11 @@ #include <ft2build.h> #include FT_TYPES_H #include FT_MODULE_H -#include FT_OTSVG_H +#ifdef FT_OTSVG_H + #include FT_OTSVG_H +#else + #define LL_NO_OTSVG +#endif // See https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html class LLFontFreeTypeSvgRenderer diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 4c9a062246..16eec1fdd2 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -58,6 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f; F32 LLFontGL::sHorizDPI = 96.f; F32 LLFontGL::sScaleX = 1.f; F32 LLFontGL::sScaleY = 1.f; +S32 LLFontGL::sResolutionGeneration = 0; bool LLFontGL::sDisplayFont = true ; std::string LLFontGL::sAppDir; @@ -109,6 +110,12 @@ S32 LLFontGL::getNumFaces(const std::string& filename) return mFontFreetype->getNumFaces(filename); } +S32 LLFontGL::getCacheGeneration() const +{ + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + return font_bitmap_cache->getCacheGeneration(); +} + S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const { @@ -249,6 +256,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + // This looks wrong, value is dynamic. + // LLFontBitmapCache::nextOpenPos can alter these values when + // new characters get added to cache, which affects whole string. + // Todo: Perhaps value should update after symbols were added? F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth(); F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); @@ -270,6 +281,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontGlyphInfo* next_glyph = NULL; + // string can have more than one glyph per char (ex: bold or shadow), + // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol. + // See drawGlyph. + // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars. static constexpr S32 GLYPH_BATCH_SIZE = 30; static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6]; static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; @@ -282,6 +297,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1); S32 glyph_count = 0; + llwchar last_char = wstr[begin_offset]; for (i = begin_offset; i < begin_offset + length; i++) { llwchar wch = wstr[i]; @@ -299,7 +315,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } // Per-glyph bitmap texture. std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry; - if (next_bitmap_entry != bitmap_entry) + if (next_bitmap_entry != bitmap_entry || last_char != wch) { // Actually draw the queued glyphs before switching their texture; // otherwise the queued glyphs will be taken from wrong textures. @@ -316,6 +332,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons bitmap_entry = next_bitmap_entry; LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second); gGL.getTexUnit(0)->bind(font_image); + + // For some reason it's not enough to compare by bitmap_entry. + // Issue hits emojis, japenese and chinese glyphs, only on first run. + // Todo: figure it out, there might be a bug with raw image data. + last_char = wch; } if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 4bb6c55c65..1c8e036f58 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -90,6 +90,7 @@ public: bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n); S32 getNumFaces(const std::string& filename); + S32 getCacheGeneration() const; S32 render(const LLWString &text, S32 begin_offset, const LLRect& rect, @@ -224,6 +225,7 @@ public: static F32 sHorizDPI; static F32 sScaleX; static F32 sScaleY; + static S32 sResolutionGeneration; static bool sDisplayFont ; static std::string sAppDir; // For loading fonts diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index 5bd1ca5eed..a223509d30 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -146,7 +146,9 @@ S32 LLFontVertexBuffer::render( || mLastScaleY != LLFontGL::sScaleY || mLastVertDPI != LLFontGL::sVertDPI || mLastHorizDPI != LLFontGL::sHorizDPI - || mLastOrigin != LLFontGL::sCurOrigin) + || mLastOrigin != LLFontGL::sCurOrigin + || mLastResGeneration != LLFontGL::sResolutionGeneration + || mLastFontCacheGen != fontp->getCacheGeneration()) { genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); @@ -178,6 +180,9 @@ void LLFontVertexBuffer::genBuffers( { // todo: add a debug build assert if this triggers too often for to long? mBufferList.clear(); + // Save before rendreing, it can change mid-render, + // so will need to rerender previous characters + mLastFontCacheGen = fontp->getCacheGeneration(); gGL.beginList(&mBufferList); mChars = fontp->render(text, begin_offset, x, y, color, halign, valign, @@ -201,6 +206,7 @@ void LLFontVertexBuffer::genBuffers( mLastVertDPI = LLFontGL::sVertDPI; mLastHorizDPI = LLFontGL::sHorizDPI; mLastOrigin = LLFontGL::sCurOrigin; + mLastResGeneration = LLFontGL::sResolutionGeneration; if (right_x) { diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index af195dfff9..a9e1e2337c 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -117,8 +117,13 @@ private: F32 mLastScaleY = 1.f; F32 mLastVertDPI = 0.f; F32 mLastHorizDPI = 0.f; + S32 mLastResGeneration = 0; LLCoordGL mLastOrigin; + // Adding new characters to bitmap cache can alter value from getBitmapWidth(); + // which alters whole string. So rerender when new characters were added to cache. + S32 mLastFontCacheGen = 0; + static bool sEnableBufferCollection; }; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 1bc5e79835..3b506d6965 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -76,7 +76,7 @@ static const std::string HEADLESS_VERSION_STRING("1.0"); llofstream gFailLog; -#if GL_ARB_debug_output +#if GL_ARB_debug_output || GL_KHR_debug #ifndef APIENTRY #define APIENTRY @@ -99,9 +99,9 @@ void APIENTRY gl_debug_callback(GLenum source, }*/ if (gGLManager.mIsDisabled && - severity == GL_DEBUG_SEVERITY_HIGH_ARB && - source == GL_DEBUG_SOURCE_API_ARB && - type == GL_DEBUG_TYPE_ERROR_ARB && + severity == GL_DEBUG_SEVERITY_HIGH && + source == GL_DEBUG_SOURCE_API && + type == GL_DEBUG_TYPE_ERROR && id == GL_INVALID_VALUE) { // Suppress messages about deleting already deleted objects called from LLViewerWindow::stopGL() @@ -161,7 +161,11 @@ void APIENTRY gl_debug_callback(GLenum source, if (ubo != 0) { glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_SIZE, &ubo_size); +#if GL_EXT_buffer_storage + glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE_EXT, &ubo_immutable); +#else glGetBufferParameteriv(GL_UNIFORM_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE, &ubo_immutable); +#endif } // No needs to halt when is called from LLViewerWindow::stopGL() @@ -215,8 +219,6 @@ LLMatrix4 gGLObliqueProjectionInverse; std::list<LLGLUpdate*> LLGLUpdate::sGLQ; -#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS - #if LL_WINDOWS // WGL_ARB_create_context PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; @@ -236,7 +238,7 @@ PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = n PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr; -#endif +/* // GL_VERSION_1_2 //PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr; @@ -982,6 +984,7 @@ PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glMultiDrawArraysIndirectCount = nullpt PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glMultiDrawElementsIndirectCount = nullptr; PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp = nullptr; +*/ #endif LLGLManager gGLManager; @@ -1136,6 +1139,7 @@ bool LLGLManager::initGL() #endif } +#if GL_VERSION_1_3 if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures) { //use texture compression glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST); @@ -1144,6 +1148,7 @@ bool LLGLManager::initGL() { //GL version is < 3.0, always disable texture compression LLImageGL::sCompressTextures = false; } +#endif // Trailing space necessary to keep "nVidia Corpor_ati_on" cards // from being recognized as ATI. @@ -1160,7 +1165,7 @@ bool LLGLManager::initGL() mIsNVIDIA = true; } else if (mGLVendor.find("INTEL") != std::string::npos -#if LL_LINUX +#if LL_LINUX || __FreeBSD__ // The Mesa-based drivers put this in the Renderer string, // not the Vendor string. || mGLRenderer.find("INTEL") != std::string::npos @@ -1254,10 +1259,12 @@ bool LLGLManager::initGL() } glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits); +#if GL_VERSION_3_2 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); +#endif glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); glGetIntegerv(GL_MAX_VARYING_VECTORS, &mMaxVaryingVectors); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &mMaxUniformBlockSize); @@ -1266,9 +1273,9 @@ bool LLGLManager::initGL() // there's some implementation that reports a crazy value mMaxUniformBlockSize = llmin(mMaxUniformBlockSize, 65536); - if (mGLVersion >= 4.59f) + if (mHasAnisotropic) { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mMaxAnisotropy); } initGLStates(); @@ -1408,6 +1415,9 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { +#if LL_LINUX + glh_init_extensions(""); +#endif #if LL_DARWIN GLint num_extensions = 0; std::string all_extensions{""}; @@ -1430,6 +1440,11 @@ void LLGLManager::initExtensions() mHasCubeMapArray = mGLVersion >= 3.99f; mHasTransformFeedback = mGLVersion >= 3.99f; mHasDebugOutput = mGLVersion >= 4.29f; + mHasAnisotropic = mGLVersion >= 4.59f; + if(!mHasAnisotropic && gGLHExts.mSysExts) + { + mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); + } // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); @@ -1438,10 +1453,10 @@ void LLGLManager::initExtensions() mInited = true; -#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS +/* +#if LL_WINDOWS LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL; -#if LL_WINDOWS // WGL_AMD_gpu_association wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD"); wglGetGPUInfoAMD = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD"); @@ -1459,8 +1474,6 @@ void LLGLManager::initExtensions() // WGL_ARB_create_context wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB"); -#endif - // Load entire OpenGL API through GetProcAddress, leaving sections beyond mGLVersion unloaded @@ -2278,6 +2291,7 @@ void LLGLManager::initExtensions() glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)GLH_EXT_GET_PROC_ADDRESS("glPolygonOffsetClamp"); #endif +*/ } void rotate_quat(LLQuaternion& rotation) @@ -2304,12 +2318,14 @@ void log_glerror() error = glGetError(); while (LL_UNLIKELY(error)) { +#if GLU_VERSION_1_1 GLubyte const * gl_error_msg = gluErrorString(error); if (NULL != gl_error_msg) { LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ; } else +#endif // GLU_VERSION_1_1 { // gluErrorString returns NULL for some extensions' error codes. // you'll probably have to grep for the number in glext.h. @@ -2328,6 +2344,7 @@ void do_assert_glerror() if (LL_UNLIKELY(error)) { quit = true; +#if GLU_VERSION_1_1 GLubyte const * gl_error_msg = gluErrorString(error); if (NULL != gl_error_msg) { @@ -2340,6 +2357,7 @@ void do_assert_glerror() } } else +#endif // GLU_VERSION_1_1 { // gluErrorString returns NULL for some extensions' error codes. // you'll probably have to grep for the number in glext.h. @@ -2414,8 +2432,10 @@ void LLGLState::initClass() // sStateMap[GL_TEXTURE_2D] = GL_TRUE; //make sure multisample defaults to disabled +#if GL_EXT_multisample || GL_EXT_multisampled_compatibility sStateMap[GL_MULTISAMPLE] = GL_FALSE; glDisable(GL_MULTISAMPLE); +#endif } //static @@ -2430,6 +2450,7 @@ void LLGLState::restoreGL() void LLGLState::resetTextureStates() { gGL.flush(); +#if GL_VERSION_1_3 GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); @@ -2439,6 +2460,7 @@ void LLGLState::resetTextureStates() glClientActiveTexture(GL_TEXTURE0+j); j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable(); } +#endif } void LLGLState::dumpStates() @@ -2458,12 +2480,15 @@ void LLGLState::checkStates(GLboolean writeAlpha) return; } - GLint src; - GLint dst; - glGetIntegerv(GL_BLEND_SRC, &src); - glGetIntegerv(GL_BLEND_DST, &dst); - llassert_always(src == GL_SRC_ALPHA); - llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA); + GLint srcRGB, dstRGB, srcAlpha, dstAlpha; + glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB); + glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcAlpha); + glGetIntegerv(GL_BLEND_DST_ALPHA, &dstAlpha); + llassert_always(srcRGB == GL_SRC_ALPHA); + llassert_always(srcAlpha == GL_SRC_ALPHA); + llassert_always(dstRGB == GL_ONE_MINUS_SRC_ALPHA); + llassert_always(dstAlpha == GL_ONE_MINUS_SRC_ALPHA); // disable for now until usage is consistent //GLboolean colorMask[4]; @@ -2588,6 +2613,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor { return; } + LL_INFOS() << "GL: " << version << LL_ENDL; version_string->assign(version); @@ -2963,5 +2989,3 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif - - diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 24ba4d6deb..bf8368a7b3 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -160,18 +160,17 @@ void assert_glerror(); void clear_glerror(); +#if !LL_RELEASE_FOR_DOWNLOAD # define stop_glerror() assert_glerror() # define llglassertok() assert_glerror() - -// stop_glerror is still needed on OS X but has performance implications -// use macro below to conditionally add stop_glerror to non-release builds -// on OS X -#if LL_DARWIN && !LL_RELEASE_FOR_DOWNLOAD -#define STOP_GLERROR stop_glerror() +# define STOP_GLERROR stop_glerror() #else -#define STOP_GLERROR +# define stop_glerror() +# define llglassertok() +# define STOP_GLERROR #endif + #define llglassertok_always() assert_glerror() //////////////////////// diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 3d4dc5e698..a2685376cd 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -27,7 +27,7 @@ #ifndef LL_LLGLHEADERS_H #define LL_LLGLHEADERS_H -#if LL_MESA +#if LL_MESA || LL_LINUX || __FreeBSD__ //---------------------------------------------------------------------------- // MESA headers // quotes so we get libraries/.../GL/ version @@ -41,6 +41,22 @@ # include "GL/glh_extensions.h" # undef __APPLE__ +#elif LL_LINUX +#define GL_GLEXT_PROTOTYPES +#define GLX_GLEXT_PROTOTYPES + +#include "GL/gl.h" +#include "GL/glext.h" +#include "GL/glu.h" + +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + +# include "GL/glx.h" +# include "GL/glxext.h" + #elif LL_WINDOWS //---------------------------------------------------------------------------- // LL_WINDOWS @@ -823,10 +839,14 @@ extern PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp; #define GL_EXT_separate_specular_color 1 #define GL_GLEXT_PROTOTYPES -#include "GL/glext.h" +#include <OpenGL/glext.h> + +#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED +#include <OpenGL/gl3.h> #include "GL/glh_extensions.h" +#if 0 // These symbols don't exist on 10.3.9, so they have to be declared weak. Redeclaring them here fixes the problem. // Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension. #include <AvailabilityMacros.h> @@ -1028,6 +1048,26 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif #include <OpenGL/gl.h> +#endif // 0 + +#elif LL_LINUX + +#define GL_GLEXT_PROTOTYPES +#define GLX_GLEXT_PROTOTYPES + +#include "GL/gl.h" +#include "GL/glu.h" +#include "GL/glext.h" +#include "GL/glx.h" + +// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly +# define __APPLE__ +# include "GL/glh_extensions.h" +# undef __APPLE__ + +// #include <X11/Xlib.h> +// #include <X11/Xutil.h> +#include "GL/glh_extensions.h" #endif // LL_MESA / LL_WINDOWS / LL_DARWIN diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index b3f32fdc83..3d7bf500f1 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -255,12 +255,18 @@ void LLGLSLShader::placeProfileQuery(bool for_runtime) glGenQueries(1, &mPrimitivesQuery); } - glBeginQuery(GL_TIME_ELAPSED, mTimerQuery); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glBeginQuery(GL_TIME_ELAPSED_EXT, mTimerQuery); +#endif if (!for_runtime) { +#if GL_VERSION_1_5 glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery); +#endif +#if GL_VERSION_3_0 glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery); +#endif } } } @@ -271,19 +277,30 @@ bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read) { if (!mProfilePending) { - glEndQuery(GL_TIME_ELAPSED); +#if GL_EXT_timer_query || GL_EXT_disjoint_timer_query + glEndQuery(GL_TIME_ELAPSED_EXT); +#endif if (!for_runtime) { +#if GL_VERSION_1_5 glEndQuery(GL_SAMPLES_PASSED); +#endif +#if GL_VERSION_3_0 glEndQuery(GL_PRIMITIVES_GENERATED); +#endif } mProfilePending = for_runtime; } if (mProfilePending && for_runtime && !force_read) { +#if GL_ARB_timer_query GLuint64 result = 0; glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#else + GLuint result = 0; + glGetQueryObjectuiv(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); +#endif if (result != GL_TRUE) { @@ -291,22 +308,34 @@ bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read) } } +#if GL_ARB_timer_query GLuint64 time_elapsed = 0; glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#else + GLuint time_elapsed = 0; + glGetQueryObjectuiv(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); +#endif mTimeElapsed += time_elapsed; mProfilePending = false; if (!for_runtime) { +#if GL_ARB_timer_query GLuint64 samples_passed = 0; glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); GLuint64 primitives_generated = 0; glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated); +#else + GLuint primitives_generated = 0; + glGetQueryObjectuiv(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated); +#endif sTotalTimeElapsed += time_elapsed; +#if GL_VERSION_1_5 sTotalSamplesDrawn += samples_passed; mSamplesDrawn += samples_passed; +#endif U32 tri_count = (U32)primitives_generated / 3; @@ -721,10 +750,14 @@ void LLGLSLShader::mapUniform(GLint index) case GL_FLOAT_VEC2: size *= 2; break; case GL_FLOAT_VEC3: size *= 3; break; case GL_FLOAT_VEC4: size *= 4; break; +#if GL_VERSION_1_1 case GL_DOUBLE: size *= 2; break; +#if GL_VERSION_4_0 case GL_DOUBLE_VEC2: size *= 2; break; case GL_DOUBLE_VEC3: size *= 6; break; case GL_DOUBLE_VEC4: size *= 8; break; +#endif // GL_VERSION_4_0 +#endif // GL_VERSION_1_1 case GL_INT_VEC2: size *= 2; break; case GL_INT_VEC3: size *= 3; break; case GL_INT_VEC4: size *= 4; break; @@ -743,6 +776,7 @@ void LLGLSLShader::mapUniform(GLint index) case GL_FLOAT_MAT3x4: size *= 12; break; case GL_FLOAT_MAT4x2: size *= 8; break; case GL_FLOAT_MAT4x3: size *= 12; break; +#if GL_VERSION_4_0 case GL_DOUBLE_MAT2: size *= 8; break; case GL_DOUBLE_MAT3: size *= 18; break; case GL_DOUBLE_MAT4: size *= 32; break; @@ -752,6 +786,7 @@ void LLGLSLShader::mapUniform(GLint index) case GL_DOUBLE_MAT3x4: size *= 24; break; case GL_DOUBLE_MAT4x2: size *= 16; break; case GL_DOUBLE_MAT4x3: size *= 24; break; +#endif // GL_VERSION_4_0 } mTotalUniformSize += size; } @@ -815,7 +850,10 @@ GLint LLGLSLShader::mapUniformTextureChannel(GLint location, GLenum type, GLint { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; - if ((type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) || + if ( +#if GL_VERSION_2_0 + (type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_RECT_SHADOW) || +#endif type == GL_SAMPLER_2D_MULTISAMPLE || type == GL_SAMPLER_CUBE_MAP_ARRAY) { //this here is a texture diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 58c456f134..873ab0cff5 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -59,6 +59,7 @@ public: bool attachNothing = false; bool hasHeroProbes = false; bool isPBRTerrain = false; + bool hasTonemap = false; }; // ============= Structure for caching shader uniforms =============== diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h index 9bb980d7ad..68d4df8e90 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -166,6 +166,7 @@ public: //---------------------------------------------------------------------------- +#if GL_VERSION_1_1 class LLGLSSpecular { public: @@ -190,6 +191,7 @@ public: } } }; +#endif //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 3858811a50..0146ed3119 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -301,40 +301,61 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) { switch (dataformat) { +#if GL_VERSION_3_0 case GL_COMPRESSED_RED: return 8; case GL_COMPRESSED_RG: return 16; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_RGB: return 24; +#endif +#if GL_VERSION_2_1 case GL_COMPRESSED_SRGB: return 32; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_RGBA: return 32; +#endif +#if GL_VERSION_2_1 case GL_COMPRESSED_SRGB_ALPHA: return 32; +#endif +#if GL_VERSION_1_3 case GL_COMPRESSED_LUMINANCE: return 8; case GL_COMPRESSED_LUMINANCE_ALPHA: return 16; case GL_COMPRESSED_ALPHA: return 8; +#endif +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8; +#endif +#if GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8; case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8; +#endif case GL_LUMINANCE: return 8; - case GL_LUMINANCE8: return 8; case GL_ALPHA: return 8; - case GL_ALPHA8: return 8; case GL_RED: return 8; case GL_R8: return 8; +#if GL_VERSION_1_1 + case GL_LUMINANCE8: return 8; + case GL_ALPHA8: return 8; case GL_COLOR_INDEX: return 8; - case GL_LUMINANCE_ALPHA: return 16; case GL_LUMINANCE8_ALPHA8: return 16; +#endif + case GL_LUMINANCE_ALPHA: return 16; case GL_RG: return 16; case GL_RG8: return 16; case GL_RGB: return 24; case GL_SRGB: return 24; case GL_RGB8: return 24; + case GL_R11F_G11F_B10F: return 32; case GL_RGBA: return 32; case GL_RGBA8: return 32; case GL_RGB10_A2: return 32; +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac +#endif case GL_DEPTH_COMPONENT: return 24; case GL_DEPTH_COMPONENT24: return 24; case GL_R16F: return 16; @@ -356,6 +377,8 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height) { switch (dataformat) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 \ + || GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: @@ -365,6 +388,7 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height) if (width < 4) width = 4; if (height < 4) height = 4; break; +#endif default: break; } @@ -378,23 +402,31 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) { switch (dataformat) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3; case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4; - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4; +#endif +#if GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4; case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4; +#endif case GL_LUMINANCE: return 1; case GL_ALPHA: return 1; case GL_RED: return 1; +#if GL_VERSION_1_1 case GL_COLOR_INDEX: return 1; +#endif case GL_LUMINANCE_ALPHA: return 2; case GL_RG: return 2; case GL_RGB: return 3; case GL_SRGB: return 3; case GL_RGBA: return 4; +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: return 4; case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac +#endif default: LL_ERRS() << "LLImageGL::Unknown format: " << std::hex << dataformat << std::dec << LL_ENDL; return 0; @@ -408,6 +440,8 @@ void LLImageGL::updateStats(F32 current_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sLastFrameTime = current_time; + sBindCount = 0; + sUniqueCount = 0; } //---------------------------------------------------------------------------- @@ -794,11 +828,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } else { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression); if (gl_level == 0) @@ -807,11 +843,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } updatePickMask(w, h, data_in); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif stop_glerror(); } @@ -824,11 +862,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 { stop_glerror(); { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif S32 w = getWidth(mCurrentDiscardLevel); S32 h = getHeight(mCurrentDiscardLevel); @@ -838,10 +878,12 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 //use legacy mipmap generation mode (note: making this condional can cause rendering issues) // -- but making it not conditional triggers deprecation warnings when core profile is enabled // (some rendering issues while core profile is enabled are acceptable at this point in time) +#if GL_VERSION_1_4 if (!LLRender::sGLCoreProfile) { glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); } +#endif LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, @@ -852,11 +894,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 updatePickMask(w, h, data_in); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif if (LLRender::sGLCoreProfile) { @@ -941,11 +985,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 llassert(w > 0 && h > 0 && cur_mip_data); (void)cur_mip_data; { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression); if (m == 0) @@ -958,11 +1004,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 updatePickMask(w, h, cur_mip_data); } +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif } if (prev_mip_data && prev_mip_data != data_in) { @@ -997,11 +1045,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } else { +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h, mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression); @@ -1011,11 +1061,13 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif } } @@ -1031,7 +1083,9 @@ U32 type_width_from_pixtype(U32 pixtype) { case GL_UNSIGNED_BYTE: case GL_BYTE: +#if GL_VERSION_1_2 case GL_UNSIGNED_INT_8_8_8_8_REV: +#endif type_width = 1; break; case GL_UNSIGNED_SHORT: @@ -1178,11 +1232,13 @@ bool LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width); stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); stop_glerror(); } +#endif const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture @@ -1206,11 +1262,13 @@ bool LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 gGL.getTexUnit(0)->disable(); stop_glerror(); +#if GL_VERSION_1_1 if(mFormatSwapBytes) { glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); stop_glerror(); } +#endif glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); stop_glerror(); @@ -1315,24 +1373,30 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { if (pixformat == GL_ALPHA) { //GL_ALPHA is deprecated, convert to RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RED; intformat = GL_R8; } if (pixformat == GL_LUMINANCE) { //GL_LUMINANCE is deprecated, convert to GL_RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RED; intformat = GL_R8; } if (pixformat == GL_LUMINANCE_ALPHA) { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA +#if GL_VERSION_3_3 const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); +#endif pixformat = GL_RG; intformat = GL_RG8; } @@ -1409,39 +1473,63 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { case GL_RED: case GL_R8: +#if GL_VERSION_3_0 intformat = GL_COMPRESSED_RED; +#endif break; case GL_RG: case GL_RG8: +#if GL_VERSION_3_0 intformat = GL_COMPRESSED_RG; +#endif break; case GL_RGB: case GL_RGB8: +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_RGB; +#endif break; case GL_SRGB: case GL_SRGB8: +#if GL_VERSION_2_1 intformat = GL_COMPRESSED_SRGB; +#endif break; case GL_RGBA: case GL_RGBA8: +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_RGBA; +#endif break; - case GL_SRGB_ALPHA: case GL_SRGB8_ALPHA8: +#if GL_VERSION_2_1 + case GL_SRGB_ALPHA: intformat = GL_COMPRESSED_SRGB_ALPHA; +#endif break; case GL_LUMINANCE: +#if GL_VERSION_1_1 case GL_LUMINANCE8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_LUMINANCE; +#endif break; case GL_LUMINANCE_ALPHA: +#if GL_VERSION_1_1 case GL_LUMINANCE8_ALPHA8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_LUMINANCE_ALPHA; +#endif break; case GL_ALPHA: +#if GL_VERSION_1_1 case GL_ALPHA8: +#endif +#if GL_VERSION_1_3 intformat = GL_COMPRESSED_ALPHA; +#endif break; default: LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; @@ -1575,13 +1663,21 @@ bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S { case 1: // Use luminance alpha (for fonts) +#if GL_VERSION_1_1 mFormatInternal = GL_LUMINANCE8; +#else + mFormatInternal = GL_LUMINANCE; +#endif mFormatPrimary = GL_LUMINANCE; mFormatType = GL_UNSIGNED_BYTE; break; case 2: // Use luminance alpha (for fonts) +#if GL_VERSION_1_1 mFormatInternal = GL_LUMINANCE8_ALPHA8; +#else + mFormatInternal = GL_LUMINANCE_ALPHA; +#endif mFormatPrimary = GL_LUMINANCE_ALPHA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1773,7 +1869,7 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) ref(); LL::WorkQueue::postMaybe( mMainQueue, - [=]() + [=, this]() { LL_PROFILE_ZONE_NAMED("cglt - delete callback"); syncTexName(new_tex_name); @@ -1863,6 +1959,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre LLImageDataLock lock(imageraw); +#if GL_VERSION_1_3 if (is_compressed) { LLGLint glbytes; @@ -1889,6 +1986,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData())); //stop_glerror(); } +#endif // GL_VERSION_1_3 //----------------------------------------------------------------------------------------------- if((error = glGetError()) != GL_NO_ERROR) @@ -1977,11 +2075,13 @@ bool LLImageGL::getIsResident(bool test_now) { if (test_now) { +#if GL_VERSION_1_1 if (mTexName != 0) { glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident); } else +#endif { mIsResident = false; } @@ -2111,12 +2211,16 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() mIsMask = false; return; //no alpha channel. case GL_RGBA: +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: +#endif mAlphaStride = 4; break; +#if GL_EXT_bgra case GL_BGRA_EXT: mAlphaStride = 4; break; +#endif default: break; } @@ -2126,6 +2230,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() { mAlphaOffset = mAlphaStride - 1 ; } +#if GL_VERSION_1_2 else if(is_little_endian()) { if (mFormatType == GL_UNSIGNED_INT_8_8_8_8) @@ -2148,10 +2253,15 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() mAlphaOffset = 0 ; } } +#endif // GL_VERSION_1_2 if( mAlphaStride < 1 || //unsupported format - mAlphaOffset < 0 || //unsupported type - (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation + mAlphaOffset < 0 //unsupported type +#if GL_EXT_bgra + || + (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE) //unknown situation +#endif + ) { LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL; @@ -2299,6 +2409,8 @@ bool LLImageGL::isCompressed() bool is_compressed = false; switch (mFormatPrimary) { +#if GL_EXT_texture_compression_s3tc || GL_EXT_texture_compression_dxt1 \ + || GL_EXT_texture_sRGB || GL_EXT_texture_compression_s3tc_srgb case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: @@ -2307,6 +2419,7 @@ bool LLImageGL::isCompressed() case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: is_compressed = true; break; +#endif default: break; } @@ -2323,7 +2436,10 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) if (mFormatType != GL_UNSIGNED_BYTE || ((mFormatPrimary != GL_RGBA) - && (mFormatPrimary != GL_SRGB_ALPHA))) +#if GL_VERSION_2_1 + && (mFormatPrimary != GL_SRGB_ALPHA) +#endif + )) { //cannot generate a pick mask for this texture freePickMask(); @@ -2503,7 +2619,9 @@ bool LLImageGL::scaleDown(S32 desired_discard) sScratchPBOSize = (U32)size; } +#if GL_VERSION_1_3 glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); +#endif free_tex_image(mTexName); diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index eef7193c92..2e70c6953d 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -296,8 +296,10 @@ void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLuint & prog) void LLPostProcess::doEffects(void) { /// Save GL State +#if GL_VERSION_1_1 glPushAttrib(GL_ALL_ATTRIB_BITS); glPushClientAttrib(GL_ALL_ATTRIB_BITS); +#endif /// Copy the screen buffer to the render texture { @@ -322,15 +324,19 @@ void LLPostProcess::doEffects(void) viewPerspective(); /// Reset GL State +#if GL_VERSION_1_1 glPopClientAttrib(); glPopAttrib(); +#endif checkError(); } void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) { gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture); +#if GL_VERSION_3_1 glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0); +#endif } void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) @@ -371,8 +377,10 @@ void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int wi if(texture->createGLTexture()) { gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); +#if GL_VERSION_3_1 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); +#endif gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } @@ -406,18 +414,22 @@ bool LLPostProcess::checkError(void) while (glErr != GL_NO_ERROR) { // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; +#if GLU_VERSION_1_1 char const * err_str_raw = (const char *) gluErrorString(glErr); if(err_str_raw == NULL) { +#endif std::ostringstream err_builder; err_builder << "unknown error number " << glErr; mShaderErrorString = err_builder.str(); +#if GLU_VERSION_1_1 } else { mShaderErrorString = err_str_raw; } +#endif retCode = true; glErr = glGetError(); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 1d53850f74..cbb178b6f8 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -84,10 +84,16 @@ static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr; static const GLenum sGLTextureType[] = { GL_TEXTURE_2D, +#if GL_VERSION_3_1 GL_TEXTURE_RECTANGLE, +#endif GL_TEXTURE_CUBE_MAP, +#if GL_VERSION_4_0 GL_TEXTURE_CUBE_MAP_ARRAY, +#endif +#if GL_VERSION_3_2 GL_TEXTURE_2D_MULTISAMPLE, +#endif GL_TEXTURE_3D }; @@ -511,21 +517,22 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } - if (gGLManager.mGLVersion >= 4.59f) + if (gGLManager.mHasAnisotropic) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); } } } GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) { +#if GL_VERSION_1_3 switch(src) { // All four cases should return the same value. @@ -540,8 +547,10 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) case TBS_TEX_ALPHA: case TBS_ONE_MINUS_TEX_COLOR: case TBS_ONE_MINUS_TEX_ALPHA: +#endif return GL_TEXTURE; +#if GL_VERSION_1_3 // All four cases should return the same value. case TBS_VERT_COLOR: case TBS_VERT_ALPHA: @@ -560,6 +569,7 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL; return GL_PRIMARY_COLOR; } +#endif } GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) @@ -606,7 +616,9 @@ void LLTexUnit::setColorScale(S32 scale) { mCurrColorScale = scale; gGL.flush(); +#if GL_VERSION_1_1 glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); +#endif } } @@ -616,7 +628,9 @@ void LLTexUnit::setAlphaScale(S32 scale) { mCurrAlphaScale = scale; gGL.flush(); +#if GL_VERSION_1_1 glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); +#endif } } @@ -737,9 +751,8 @@ void LLLightState::setPosition(const LLVector4& position) ++gGL.mLightHash; mPosition = position; //transform position by current modelview matrix - glm::vec4 pos(glm::make_vec4(position.mV)); - const glm::mat4& mat = gGL.getModelviewMatrix(); - pos = mat * pos; + glm::vec4 pos(position); + pos = gGL.getModelviewMatrix() * pos; mPosition.set(glm::value_ptr(pos)); } @@ -794,7 +807,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction) ++gGL.mLightHash; //transform direction by current modelview matrix - glm::vec3 dir(glm::make_vec3(direction.mV)); + glm::vec3 dir(direction); const glm::mat3 mat(gGL.getModelviewMatrix()); dir = mat * dir; @@ -868,7 +881,9 @@ bool LLRender::init(bool needs_vertex_buffer) glCullFace(GL_BACK); // necessary for reflection maps +#if GL_VERSION_3_2 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#endif #if LL_WINDOWS if (glGenVertexArrays == nullptr) @@ -2021,9 +2036,11 @@ void LLRender::debugTexUnits(void) case LLTexUnit::TT_TEXTURE: LL_CONT << "Texture 2D"; break; +#if GL_VERSION_3_1 case LLTexUnit::TT_RECT_TEXTURE: LL_CONT << "Texture Rectangle"; break; +#endif case LLTexUnit::TT_CUBE_MAP: LL_CONT << "Cube Map"; break; @@ -2088,12 +2105,14 @@ void set_last_projection(const glm::mat4& mat) glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec) { - //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; - //return glm::vec3( - // (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, - // (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, - // (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w - //); +#if 1 // SIMD path results in strange crashes. Fall back to scalar for now. + const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; + return glm::vec3( + (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w, + (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w, + (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w + ); +#else LLVector4a x, y, z, s, t, p, q; x.splat(vec.x); @@ -2123,4 +2142,5 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec) res.setAdd(x, z); res.div(q); return glm::make_vec3(res.getF32ptr()); +#endif } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7b6bd4198b..97c47bcae9 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -34,6 +34,7 @@ //#include "linden_common.h" +#include <array> #include "v2math.h" #include "v3math.h" #include "v4coloru.h" @@ -68,10 +69,16 @@ public: typedef enum { TT_TEXTURE = 0, // Standard 2D Texture +#if GL_VERSION_3_1 TT_RECT_TEXTURE, // Non power of 2 texture +#endif TT_CUBE_MAP, // 6-sided cube map texture +#if GL_VERSION_4_0 TT_CUBE_MAP_ARRAY, // Array of cube maps +#endif +#if GL_VERSION_3_2 TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample +#endif TT_TEXTURE_3D, // standard 3D Texture TT_NONE, // No texture type is currently enabled } eTextureType; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 5b08c29d64..9144ce6d62 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -1802,10 +1802,12 @@ void LLRender2D::setLineWidth(F32 width) // If outside the allowed range, glLineWidth fails with "invalid value". // On Darwin, the range is [1, 1]. static GLfloat range[2]{0.0}; +#if GL_VERSION_1_2 if (range[1] == 0) { glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range); } +#endif width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f); glLineWidth(llclamp(width, range[0], range[1])); } diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 38bc5ff331..0e4aa2ee7a 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -255,12 +255,14 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) stop_glerror(); } +#if GL_VERSION_3_1 if (mUsage != LLTexUnit::TT_RECT_TEXTURE) { gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); stop_glerror(); } else +#endif { // ATI doesn't support mirrored repeat for rectangular textures. gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); @@ -429,7 +431,8 @@ void LLRenderTarget::bindTarget() if (mTex.empty()) { //no color buffer to draw to - glDrawBuffer(GL_NONE); + GLenum buffers[] = {GL_NONE}; + glDrawBuffers(0, buffers); glReadBuffer(GL_NONE); } else @@ -499,7 +502,9 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt { case GL_SRGB: case GL_SRGB8: +#if GL_VERSION_2_1 case GL_SRGB_ALPHA: +#endif case GL_SRGB8_ALPHA8: isSRGB = true; break; @@ -542,7 +547,8 @@ void LLRenderTarget::flush() sCurResX = gGLViewport[2]; sCurResY = gGLViewport[3]; glReadBuffer(GL_BACK); - glDrawBuffer(GL_BACK); + GLenum drawbuffers[] = {GL_BACK}; + glDrawBuffers(1, drawbuffers); } } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0885740934..4807c12226 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } + if (features->hasTonemap) + { + if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl")) + { + return false; + } + } + // NOTE order of shader object attaching is VERY IMPORTANT!!! if (features->hasAtmospherics) { @@ -466,6 +474,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev if (filename.empty()) { + LL_WARNS("ShaderLoading") << "tried loading empty filename" << LL_ENDL; return 0; } @@ -923,6 +932,8 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL; } + + LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL; return ret; } @@ -1389,6 +1400,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("screenTex"); mReservedUniforms.push_back("screenDepth"); mReservedUniforms.push_back("refTex"); + mReservedUniforms.push_back("exclusionTex"); mReservedUniforms.push_back("eyeVec"); mReservedUniforms.push_back("time"); mReservedUniforms.push_back("waveDir1"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 34bd73a42e..46788841a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -36,6 +36,8 @@ public: LLShaderMgr(); virtual ~LLShaderMgr(); + // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this. + // Always document what the actual shader uniform is next to the shader uniform in this struct. // clang-format off typedef enum { // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms() @@ -234,6 +236,7 @@ public: WATER_SCREENTEX, // "screenTex" WATER_SCREENDEPTH, // "screenDepth" WATER_REFTEX, // "refTex" + WATER_EXCLUSIONTEX, // "exclusionTex" WATER_EYEVEC, // "eyeVec" WATER_TIME, // "time" WATER_WAVE_DIR1, // "waveDir1" diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1f0c424188..ac6db0b34f 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1707,55 +1707,58 @@ void LLVertexBuffer::setupVertexBuffer() STOP_GLERROR; U8* base = nullptr; + AttributeType loc; + void* ptr = nullptr; + U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; if (data_mask & MAP_NORMAL) { - AttributeType loc = TYPE_NORMAL; - void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + loc = TYPE_NORMAL; + ptr = (void*)(base + mOffsets[TYPE_NORMAL]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } if (data_mask & MAP_TEXCOORD3) { - AttributeType loc = TYPE_TEXCOORD3; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + loc = TYPE_TEXCOORD3; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } if (data_mask & MAP_TEXCOORD2) { - AttributeType loc = TYPE_TEXCOORD2; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + loc = TYPE_TEXCOORD2; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } if (data_mask & MAP_TEXCOORD1) { - AttributeType loc = TYPE_TEXCOORD1; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + loc = TYPE_TEXCOORD1; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } if (data_mask & MAP_TANGENT) { - AttributeType loc = TYPE_TANGENT; - void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); + loc = TYPE_TANGENT; + ptr = (void*)(base + mOffsets[TYPE_TANGENT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); } if (data_mask & MAP_TEXCOORD0) { - AttributeType loc = TYPE_TEXCOORD0; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + loc = TYPE_TEXCOORD0; + ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } if (data_mask & MAP_COLOR) { - AttributeType loc = TYPE_COLOR; + loc = TYPE_COLOR; //bind emissive instead of color pointer if emissive is present - void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); + ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } if (data_mask & MAP_EMISSIVE) { - AttributeType loc = TYPE_EMISSIVE; - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + loc = TYPE_EMISSIVE; + ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); if (!(data_mask & MAP_COLOR)) @@ -1766,38 +1769,38 @@ void LLVertexBuffer::setupVertexBuffer() } if (data_mask & MAP_WEIGHT) { - AttributeType loc = TYPE_WEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + loc = TYPE_WEIGHT; + ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } if (data_mask & MAP_WEIGHT4) { - AttributeType loc = TYPE_WEIGHT4; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); + loc = TYPE_WEIGHT4; + ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } if (data_mask & MAP_JOINT) { - AttributeType loc = TYPE_JOINT; - void* ptr = (void*)(base + mOffsets[TYPE_JOINT]); + loc = TYPE_JOINT; + ptr = (void*)(base + mOffsets[TYPE_JOINT]); glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr); } if (data_mask & MAP_CLOTHWEIGHT) { - AttributeType loc = TYPE_CLOTHWEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + loc = TYPE_CLOTHWEIGHT; + ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } if (data_mask & MAP_TEXTURE_INDEX) { - AttributeType loc = TYPE_TEXTURE_INDEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); + loc = TYPE_TEXTURE_INDEX; + ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } if (data_mask & MAP_VERTEX) { - AttributeType loc = TYPE_VERTEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + loc = TYPE_VERTEX; + ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } STOP_GLERROR; @@ -1914,7 +1917,3 @@ void LLVertexBuffer::setIndexData(const U32* data, U32 offset, U32 count) } flush_vbo(GL_ELEMENT_ARRAY_BUFFER, offset * sizeof(U32), (offset + count) * sizeof(U32) - 1, (U8*)data, mMappedIndexData); } - - - - |