diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/llrender/llcubemap.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llcubemaparray.cpp | 5 | ||||
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 12 | ||||
-rw-r--r-- | indra/llrender/llfontfreetypesvg.cpp | 12 | ||||
-rw-r--r-- | indra/llrender/llfontfreetypesvg.h | 6 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 64 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 22 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 44 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 44 | ||||
-rw-r--r-- | indra/llrender/llglstates.h | 2 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 148 | ||||
-rw-r--r-- | indra/llrender/llpostprocess.cpp | 12 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 95 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 10 | ||||
-rw-r--r-- | indra/llrender/llrender2dutils.cpp | 5 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 186 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.h | 11 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 16 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.h | 14 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 140 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 4 |
22 files changed, 703 insertions, 152 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 998b57217d..e0a8782c33 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -114,6 +114,8 @@ LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTex allocate(mWidth, lhs.mImage->getComponents(), count, lhs.mImage->getUseMipMaps(), lhs.mHDR); // Copy each cubemap from the incoming array to the new array + // The call to glTexSubImage3D causes an INVALID OPERATION OpenGL error. For now we comment this.. + /* U32 min_count = std::min(count, lhs.mCount); for (U32 i = 0; i < min_count * 6; ++i) { @@ -133,6 +135,7 @@ LLCubeMapArray::LLCubeMapArray(LLCubeMapArray& lhs, U32 width, U32 count) : mTex glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, i, mWidth, mWidth, 1, components, GL_UNSIGNED_BYTE, scaled_image->getData()); } } + */ } LLCubeMapArray::~LLCubeMapArray() @@ -168,8 +171,10 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us 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/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 5f04664267..e93c98970b 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -32,7 +32,7 @@ // Freetype stuff #include <ft2build.h> #ifdef LL_WINDOWS -#include <freetype2\freetype\ftsystem.h> +#include <freetype/ftsystem.h> #endif #include "llfontfreetypesvg.h" @@ -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, @@ -482,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); } 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/llgl.cpp b/indra/llrender/llgl.cpp index 0be27b8975..cc619e2086 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,8 +238,6 @@ PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC wglBlitContextFramebufferAMD = n PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = nullptr; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = nullptr; -#endif - // GL_VERSION_1_2 //PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = nullptr; //PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr; @@ -1136,6 +1136,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 +1145,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 +1162,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 @@ -1235,10 +1237,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); @@ -1247,9 +1251,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(); @@ -1389,6 +1393,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{""}; @@ -1411,6 +1418,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); @@ -1419,10 +1431,9 @@ 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"); @@ -1440,8 +1451,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 @@ -2270,33 +2279,36 @@ void rotate_quat(LLQuaternion& rotation) void flush_glerror() { + if(!gDebugGL) return; glGetError(); } -//this function outputs gl error to the log file, does not crash the code. -void log_glerror() +void log_glerror(std::string comment) { + if(!gDebugGL) return; + if (LL_UNLIKELY(!gGLManager.mInited)) { return ; } - // Create or update texture to be used with this data + GLenum error; error = glGetError(); - while (LL_UNLIKELY(error)) + if (error != GL_NO_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 ; + LL_WARNS() << "GL Error (" << comment << ")" << error << ": " << 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. LL_WARNS() << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL; } - error = glGetError(); } } @@ -2309,6 +2321,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) { @@ -2321,6 +2334,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. @@ -2372,6 +2386,7 @@ void assert_glerror() void clear_glerror() { + if(!gDebugGL) return; glGetError(); glGetError(); } @@ -2395,8 +2410,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 @@ -2411,6 +2428,7 @@ void LLGLState::restoreGL() void LLGLState::resetTextureStates() { gGL.flush(); +#if GL_VERSION_1_3 GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); @@ -2420,6 +2438,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() @@ -2572,6 +2591,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); @@ -2947,5 +2967,3 @@ extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif - - diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 24ba4d6deb..130b06f9df 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -154,24 +154,26 @@ void rotate_quat(LLQuaternion& rotation); void flush_glerror(); // Flush GL errors when we know we're handling them correctly. -void log_glerror(); +void log_glerror(std::string comment); void assert_glerror(); void clear_glerror(); -# 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() +//#if !LL_RELEASE_FOR_DOWNLOAD +#if 1 +# define LOG_GLERROR(COMMENT) log_glerror(COMMENT) +# define stop_glerror() log_glerror("stop") +# define llglassertok() log_glerror("ASSERTOK") +# define STOP_GLERROR log_glerror("STOP") #else -#define STOP_GLERROR +# define LOG_GLERROR(COMMENT) +# 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 3735a99109..aac5e3abc8 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/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 1db36d91f9..9ff483b92b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -301,30 +301,48 @@ 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; @@ -334,10 +352,15 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) 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_COMPONENT16: return 16; case GL_DEPTH_COMPONENT24: return 24; + case GL_DEPTH_COMPONENT32: return 32; + case GL_RGBA16: return 64; case GL_R16F: return 16; case GL_RG16F: return 32; case GL_RGB16F: return 48; @@ -357,6 +380,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: @@ -366,6 +391,7 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height) if (width < 4) width = 4; if (height < 4) height = 4; break; +#endif default: break; } @@ -379,23 +405,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; @@ -409,6 +443,8 @@ void LLImageGL::updateStats(F32 current_time) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sLastFrameTime = current_time; + sBindCount = 0; + sUniqueCount = 0; } //---------------------------------------------------------------------------- @@ -795,11 +831,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) @@ -808,11 +846,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(); } @@ -825,11 +865,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); @@ -839,10 +881,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, @@ -853,11 +897,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) { @@ -942,11 +988,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) @@ -959,11 +1007,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) { @@ -998,11 +1048,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); @@ -1012,11 +1064,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 } } @@ -1032,7 +1086,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: @@ -1179,11 +1235,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 @@ -1207,11 +1265,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(); @@ -1233,7 +1293,7 @@ bool LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; - stop_glerror(); + LOG_GLERROR("LLImageGL::setSubImageFromFrameBuffer()"); return true; } else @@ -1316,24 +1376,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; } @@ -1410,39 +1476,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; @@ -1576,13 +1666,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; @@ -1864,6 +1962,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre LLImageDataLock lock(imageraw); +#if GL_VERSION_1_3 if (is_compressed) { LLGLint glbytes; @@ -1909,6 +2008,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) @@ -1997,11 +2097,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; } @@ -2131,12 +2233,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; } @@ -2146,6 +2252,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) @@ -2168,10 +2275,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; @@ -2319,6 +2431,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: @@ -2327,6 +2441,7 @@ bool LLImageGL::isCompressed() case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: is_compressed = true; break; +#endif default: break; } @@ -2343,7 +2458,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(); @@ -2468,6 +2586,8 @@ bool LLImageGL::scaleDown(S32 desired_discard) return false; } + //LL_WARNS() << "scaleDown" << LL_ENDL; + S32 mip = desired_discard - mCurrentDiscardLevel; S32 desired_width = getWidth(desired_discard); @@ -2485,6 +2605,7 @@ bool LLImageGL::scaleDown(S32 desired_discard) free_tex_image(mTexName); glTexImage2D(mTarget, 0, mFormatInternal, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr); glCopyTexSubImage2D(mTarget, 0, 0, 0, 0, 0, desired_width, desired_height); + LOG_GLERROR("LLImageGL::scaleDown() - glCopyTexSubImage2D"); alloc_tex_image(desired_width, desired_height, mFormatInternal, 1); mTexOptionsDirty = true; @@ -2494,6 +2615,7 @@ bool LLImageGL::scaleDown(S32 desired_discard) LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); gGL.getTexUnit(0)->bind(this); glGenerateMipmap(mTarget); + LOG_GLERROR("LLImageGL::scaleDown() - glGenerateMipmap"); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } } @@ -2523,7 +2645,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 1dc87a66ce..332d15f76c 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 }; @@ -197,6 +203,7 @@ void LLTexUnit::bindFast(LLTexture* texture) glActiveTexture(GL_TEXTURE0 + mIndex); gGL.mCurrTextureUnitIndex = mIndex; mCurrTexture = gl_tex->getTexName(); + mCurrTexType = gl_tex->getTarget(); if (!mCurrTexture) { LL_PROFILE_ZONE_NAMED("MISSING TEXTURE"); @@ -473,59 +480,70 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio { if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return; + GLenum target = sGLTextureType[mCurrTexType]; + + if (mCurrTexType == LLTexUnit::TT_NONE) + { + LL_WARNS() << "setTextureFilteringOption() Error: mCurrTexType==TT_NONE texture: " << mCurrTexture << LL_ENDL; + gGL.debugTexUnits(); + } + gGL.flush(); if (option == TFO_POINT) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (option >= TFO_TRILINEAR && mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else if (option >= TFO_BILINEAR) { if (mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } else { if (mHasMipMaps) { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); } else { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } } - if (gGLManager.mGLVersion >= 4.59f) + if (gGLManager.mHasAnisotropic) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + //glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gGLManager.mMaxAnisotropy); + //We plan to add a setting. For now we stick to a low value. + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); + glTexParameterf(target, 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 +558,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 +580,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 +627,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 +639,9 @@ void LLTexUnit::setAlphaScale(S32 scale) { mCurrAlphaScale = scale; gGL.flush(); +#if GL_VERSION_1_1 glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); +#endif } } @@ -867,7 +892,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) @@ -892,13 +919,12 @@ bool LLRender::init(bool needs_vertex_buffer) void LLRender::initVertexBuffer() { llassert_always(mBuffer.isNull()); - stop_glerror(); mBuffer = new LLVertexBuffer(immediate_mask); - mBuffer->allocateBuffer(4096, 0); + mBuffer->allocateBuffer(16384, 0); mBuffer->getVertexStrider(mVerticesp); mBuffer->getTexCoord0Strider(mTexcoordsp); mBuffer->getColorStrider(mColorsp); - stop_glerror(); + LOG_GLERROR("LLRender::initVertexBuffer()"); } void LLRender::resetVertexBuffer() @@ -984,7 +1010,6 @@ void LLRender::syncLightState() void LLRender::syncMatrices() { - STOP_GLERROR; LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; static const U32 name[] = @@ -1129,7 +1154,7 @@ void LLRender::syncMatrices() syncLightState(); } } - STOP_GLERROR; + LOG_GLERROR("LLRender::syncMatrices()"); } void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) @@ -1539,7 +1564,7 @@ void LLRender::begin(const GLuint& mode) mMode == LLRender::TRIANGLES || mMode == LLRender::POINTS) { - flush(); + flush("LLRender::begin"); } else if (mCount != 0) { @@ -1550,7 +1575,7 @@ void LLRender::begin(const GLuint& mode) } } -void LLRender::end() +void LLRender::end(std::string comment_) { if (mCount == 0) { @@ -1563,13 +1588,12 @@ void LLRender::end() mMode != LLRender::POINTS) || mCount > 2048) { - flush(); + flush("from end " + comment_); } } -void LLRender::flush() +void LLRender::flush(std::string comment_) { - STOP_GLERROR; if (mCount > 0) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -1638,9 +1662,16 @@ void LLRender::flush() } resetStriders(count); + + LOG_GLERROR("LLRender::flush() end " + comment_); } } +void LLRender::flush() +{ + flush(""); +} + LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count) { LLVertexBuffer *vb = nullptr; @@ -1735,9 +1766,11 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count) vb->setColorData(mColorsp.get()); } -#if LL_DARWIN + if(gGLManager.mIsApple && LLVertexBuffer::getVertexBufferMode() == 0) + { vb->unmapBuffer(); -#endif + } + vb->unbind(); return vb; @@ -2010,7 +2043,8 @@ void LLRender::debugTexUnits(void) std::string active_enabled = "false"; for (U32 i = 0; i < mTexUnits.size(); i++) { - if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE) + //if (getTexUnit(i)->mCurrTexType != LLTexUnit::TT_NONE) + if(1) { if (i == mCurrTextureUnitIndex) active_enabled = "true"; LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL; @@ -2020,14 +2054,27 @@ 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; + case LLTexUnit::TT_CUBE_MAP_ARRAY: + LL_CONT << "Cube Map Array"; + break; + + case LLTexUnit::TT_MULTISAMPLE_TEXTURE: + LL_CONT << "Multisample Texture"; + break; + + case LLTexUnit::TT_TEXTURE_3D: + LL_CONT << "Texture 3D"; + break; default: - LL_CONT << "ARGH!!! NONE!"; + LL_CONT << "ARGH!!! NONE! -> type = " << getTexUnit(i)->mCurrTexType; break; } LL_CONT << ", Texture Bound: " << getTexUnit(i)->mCurrTexture << LL_ENDL; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 7b6bd4198b..a755ddd2b1 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; @@ -414,6 +421,7 @@ public: LLVector3 getUITranslation(); LLVector3 getUIScale(); + void flush(std::string comment_); void flush(); // if list is set, will store buffers in list for later use, if list isn't set, will use cache @@ -421,7 +429,7 @@ public: void endList(); void begin(const GLuint& mode); - void end(); + void end(std::string comment_ = ""); U8 getMode() const { return mMode; } diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 5b08c29d64..714df863cd 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -833,8 +833,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c { gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]); - gGL.flush(); - glLineWidth(2.5f); + LLRender2D::setLineWidth(2.5f); gGL.begin(LLRender::LINES); { @@ -1802,10 +1801,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..e898e03feb 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -158,6 +158,8 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name) llassert(mTex.empty()); // mTex must be empty with this mode (binding target should be done via LLImageGL) llassert(!isBoundInStack()); + U32 target = getTarget(); + if (mFBO == 0) { glGenFramebuffers(1, (GLuint*)&mFBO); @@ -174,14 +176,14 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name) mTex.push_back(use_name); - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + glBindFramebuffer(target, mFBO); + glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), use_name, 0); stop_glerror(); check_framebuffer_status(); - glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); + glBindFramebuffer(target, sCurFBO); } void LLRenderTarget::releaseColorAttachment() @@ -194,6 +196,7 @@ void LLRenderTarget::releaseColorAttachment() glBindFramebuffer(GL_FRAMEBUFFER, mFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), 0, 0); glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); + LOG_GLERROR(mName + " releaseColorAttachment()"); mTex.clear(); } @@ -208,6 +211,8 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) return true; } + U32 target = getTarget(); + U32 offset = static_cast<U32>(mTex.size()); if( offset >= 4 ) @@ -226,12 +231,76 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) LLImageGL::generateTextures(1, &tex); gGL.getTexUnit(0)->bindManual(mUsage, tex); - stop_glerror(); - + U32 miplevel = mMipLevels; + U32 intformat = color_fmt; + U32 pixformat = GL_RGBA; + U32 pixtype = GL_UNSIGNED_BYTE; { - clear_glerror(); - LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false); + //clear_glerror(); + + if(color_fmt == GL_RGB10_A2) + { + pixformat = GL_RGBA; + pixtype = GL_UNSIGNED_BYTE; + } + else if(color_fmt == GL_R11F_G11F_B10F) + { + pixformat = GL_RGB; + pixtype = GL_HALF_FLOAT; + } + else if(color_fmt == GL_R8) + { + pixformat = GL_RED; + pixtype = GL_UNSIGNED_BYTE; + } + else if(color_fmt == GL_R16F) + { + pixformat = GL_RED; + pixtype = GL_HALF_FLOAT; + } + else if(color_fmt == GL_RG16F) + { + pixformat = GL_RG; + pixtype = GL_HALF_FLOAT; + } + else if(color_fmt == GL_RGBA16F) + { + pixformat = GL_RGBA; + pixtype = GL_HALF_FLOAT; + } + else if(color_fmt == GL_RGB16F) + { + pixformat = GL_RGB; + pixtype = GL_HALF_FLOAT; + } + else if(color_fmt == GL_RGB8) + { + pixformat = GL_RGB; + pixtype = GL_UNSIGNED_BYTE; + } + else if(color_fmt == GL_RGB) + { + pixformat = GL_RGB; + pixtype = GL_UNSIGNED_BYTE; + } + else if(color_fmt == GL_RGBA) + { + pixformat = GL_RGBA; + pixtype = GL_UNSIGNED_BYTE; + } + else if(color_fmt == GL_RGBA8) + { + pixformat = GL_RGBA; + pixtype = GL_UNSIGNED_BYTE; + } + else + { + pixformat = GL_RGBA; + pixtype = GL_UNSIGNED_BYTE; + } + + LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, pixformat, pixtype, NULL, false); if (glGetError() != GL_NO_ERROR) { LL_WARNS() << "Could not allocate color buffer for render target." << LL_ENDL; @@ -241,30 +310,29 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) sBytesAllocated += mResX*mResY*4; - stop_glerror(); - - if (offset == 0) { //use bilinear filtering on single texture render targets that aren't multisampled gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - stop_glerror(); + LOG_GLERROR(mName + " setting filtering to TFO_BILINEAR"); } else { //don't filter data attachments gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - stop_glerror(); + LOG_GLERROR(mName + " setting filtering to TFO_POINT"); } +#if GL_VERSION_3_1 if (mUsage != LLTexUnit::TT_RECT_TEXTURE) { gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR); - stop_glerror(); + LOG_GLERROR(mName + " setting address mode to TAM_MIRROR"); } else +#endif { // ATI doesn't support mirrored repeat for rectangular textures. gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - stop_glerror(); + LOG_GLERROR(mName + " setting address mode to TAM_CLAMP"); } if (mFBO) @@ -283,7 +351,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) if (gDebugGL) { //bind and unbind to validate target - bindTarget(); + bindTarget(mName, mMode); flush(); } @@ -298,8 +366,6 @@ bool LLRenderTarget::allocateDepth() gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); - stop_glerror(); - clear_glerror(); LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); @@ -307,7 +373,7 @@ bool LLRenderTarget::allocateDepth() if (glGetError() != GL_NO_ERROR) { - LL_WARNS() << "Unable to allocate depth buffer for render target." << LL_ENDL; + LL_WARNS() << "Unable to allocate depth buffer for render target " << mName << LL_ENDL; return false; } @@ -343,6 +409,8 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); + LOG_GLERROR(mName + " shareDepthBuffer()"); + target.mUseDepth = true; } } @@ -406,19 +474,32 @@ void LLRenderTarget::release() LLImageGL::deleteTextures(1, &mTex[0]); } + LOG_GLERROR(mName + " release()"); + mTex.clear(); mInternalFormat.clear(); mResX = mResY = 0; } -void LLRenderTarget::bindTarget() +void LLRenderTarget::bindTarget(std::string name_, U32 mode_) { LL_PROFILE_GPU_ZONE("bindTarget"); llassert(mFBO); llassert(!isBoundInStack()); - glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + //mode_ = 0; + + mMode = mode_; + mName = name_; + + U32 target = getTarget(); + + glBindFramebuffer(target, mFBO); + LOG_GLERROR(mName+" bindTarget()"); + + //attach(); + sCurFBO = mFBO; //setup multiple render targets @@ -429,15 +510,33 @@ void LLRenderTarget::bindTarget() if (mTex.empty()) { //no color buffer to draw to - glDrawBuffer(GL_NONE); + if(!mUseDepth) LL_WARNS() << mName << " HAS NO COLOR BUFFER AND NO DEPTH!!" << LL_ENDL; + GLenum buffers[] = {GL_NONE}; + glDrawBuffers(0, buffers); glReadBuffer(GL_NONE); } - else + else if(mMode == 0) { glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers); glReadBuffer(GL_COLOR_ATTACHMENT0); + LOG_GLERROR(mName+" read and write buffers"); + } + else if(mMode == 1) + { + glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers); + glReadBuffer(GL_NONE); + LOG_GLERROR(mName+" draw buffer"); } + else if(mMode == 2) + { + GLenum buffers[] = {GL_NONE}; + glDrawBuffers(0, buffers); + glReadBuffer(GL_COLOR_ATTACHMENT0); + LOG_GLERROR(mName+" read buffer"); + } + check_framebuffer_status(); + LOG_GLERROR(mName+" checked status"); glViewport(0, 0, mResX, mResY); sCurResX = mResX; @@ -451,7 +550,9 @@ void LLRenderTarget::clear(U32 mask_in) { LL_PROFILE_GPU_ZONE("clear"); llassert(mFBO); - U32 mask = GL_COLOR_BUFFER_BIT; + U32 mask = 0; + + if(!mTex.empty()) mask |= GL_COLOR_BUFFER_BIT; if (mUseDepth) { mask |= GL_DEPTH_BUFFER_BIT; @@ -460,15 +561,14 @@ void LLRenderTarget::clear(U32 mask_in) if (mFBO) { check_framebuffer_status(); - stop_glerror(); glClear(mask & mask_in); - stop_glerror(); + LOG_GLERROR(mName + "clear()"); } else { LLGLEnable scissor(GL_SCISSOR_TEST); glScissor(0, 0, mResX, mResY); - stop_glerror(); + LOG_GLERROR(""); glClear(mask & mask_in); } } @@ -499,7 +599,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; @@ -509,29 +611,43 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt } gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options); + + LOG_GLERROR(mName + " bindTexture()"); } void LLRenderTarget::flush() { LL_PROFILE_GPU_ZONE("rt flush"); + + LOG_GLERROR(mName+" rt flush() A"); + gGL.flush(); llassert(mFBO); llassert(sCurFBO == mFBO); llassert(sBoundTarget == this); - if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) + if (mGenerateMipMaps == LLTexUnit::TMG_AUTO && mMode != 2) { LL_PROFILE_GPU_ZONE("rt generate mipmaps"); - bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR); + //bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR); + bindTexture(0, 0, LLTexUnit::TFO_ANISOTROPIC); glGenerateMipmap(GL_TEXTURE_2D); + LOG_GLERROR(mName + " glGenerateMipmap()"); } + LOG_GLERROR(mName + " rt flush() B"); + + unbind(); +} + +void LLRenderTarget::unbind() +{ if (mPreviousRT) { // a bit hacky -- pop the RT stack back two frames and push // the previous frame back on to play nice with the GL state machine sBoundTarget = mPreviousRT->mPreviousRT; - mPreviousRT->bindTarget(); + mPreviousRT->bindTarget(mPreviousRT->mName, mPreviousRT->mMode); } else { @@ -544,6 +660,8 @@ void LLRenderTarget::flush() glReadBuffer(GL_BACK); glDrawBuffer(GL_BACK); } + + LOG_GLERROR(mName + " rt unbind()"); } bool LLRenderTarget::isComplete() const @@ -598,3 +716,13 @@ void LLRenderTarget::swapFBORefs(LLRenderTarget& other) std::swap(mFBO, other.mFBO); std::swap(mTex, other.mTex); } + +U32 LLRenderTarget::getTarget() +{ + U32 target = GL_FRAMEBUFFER; + + if(mMode == 1) target = GL_DRAW_FRAMEBUFFER; + else if(mMode == 2) target = GL_READ_FRAMEBUFFER; + + return target; +} diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index cd3290cf66..ce3025f280 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -126,7 +126,7 @@ public: // If an LLRenderTarget is currently bound, stores a reference to that LLRenderTarget // and restores previous binding on flush() (maintains a stack of Render Targets) // Asserts that this target is not currently bound in the stack - void bindTarget(); + void bindTarget(std::string name_ = "nd", U32 mode_ = 0); //clear render targer, clears depth buffer if present, //uses scissor rect if in copy-to-texture mode @@ -158,6 +158,7 @@ public: // If an LLRenderTarget was bound when bindTarget was called, binds that RenderTarget for rendering (maintains RT stack) // asserts that this target is currently bound void flush(); + void unbind(); //Returns TRUE if target is ready to be rendered into. //That is, if the target has been allocated with at least @@ -174,11 +175,15 @@ public: static LLRenderTarget* sBoundTarget; + U32 mMode; + std::string mName; + protected: U32 mResX; U32 mResY; std::vector<U32> mTex; std::vector<U32> mInternalFormat; + std::vector<U32> mPixFormat; U32 mFBO; LLRenderTarget* mPreviousRT = nullptr; @@ -188,6 +193,10 @@ protected: U32 mMipLevels; LLTexUnit::eTextureType mUsage; + +private: + U32 getTarget(); + }; #endif diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 4807c12226..81d45bc431 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -571,7 +571,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev } else { - shader_code_text[shader_code_count++] = strdup("#version 400\n"); + shader_code_text[shader_code_count++] = strdup("#version 410\n"); } } else if (major_version == 3) @@ -1501,6 +1501,20 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("searchTex"); mReservedUniforms.push_back("blendTex"); + mReservedUniforms.push_back("bloomEMap"); + mReservedUniforms.push_back("bloomBlurredMap"); + mReservedUniforms.push_back("bloomHorizontal"); + mReservedUniforms.push_back("bloomBlurRadius"); + mReservedUniforms.push_back("bloomExtractBrightness"); + mReservedUniforms.push_back("bloomStrength"); + mReservedUniforms.push_back("bloomExtractEmissive"); + mReservedUniforms.push_back("bloomExtractEmissive2"); + mReservedUniforms.push_back("bloomExtractORM"); + mReservedUniforms.push_back("bloomExtractMetal"); + mReservedUniforms.push_back("bloomExtractNonMetal"); + mReservedUniforms.push_back("bloomClampValue"); + mReservedUniforms.push_back("mpHDRBoost"); + llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS); std::set<std::string> dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 46788841a5..19416066a5 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -341,6 +341,20 @@ public: SMAA_SEARCH_TEX, // "searchTex" SMAA_BLEND_TEX, // "blendTex" + BLOOM_EMAP, // "bloomEMap" + BLOOM_BMAP, // "bloomBlurredMap" + BLOOM_BLURH, // "bloomHorizontal" + BLOOM_BLUR_RADIUS, // "bloomRadius" + BLOOM_EXTRACT_BRIGHTNESS, // "bloomExtractBrightness" + BLOOM_STRENGTH, // "bloomStrength" + BLOOM_EXTRACT_EMISSIVE, // "bloomExtractEmissive" + BLOOM_EXTRACT_EMISSIVE2, // "bloomExtractEmissive2" + BLOOM_EXTRACT_ORM, // "bloomExtractORM" + BLOOM_EXTRACT_METAL, // "bloomExtractMetal" + BLOOM_EXTRACT_NONMETAL, // "bloomExtractNonMetal" + BLOOM_CLAMP, // "bloomClampValue" + MP_HDR_BOOST, // "mpHDRBoost" + END_RESERVED_UNIFORMS } eGLSLReservedUniforms; // clang-format on diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1f0c424188..1bd7a57cd9 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -29,7 +29,6 @@ #include "llfasttimer.h" #include "llsys.h" #include "llvertexbuffer.h" -// #include "llrender.h" #include "llglheaders.h" #include "llrender.h" #include "llvector4a.h" @@ -272,13 +271,13 @@ static GLuint gen_buffer() { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("gen buffer"); sIndex = pool_size; -#if !LL_DARWIN +//#if !LL_DARWIN if (!gGLManager.mIsAMD) { glGenBuffers(pool_size, sNamePool); } else -#endif +//#endif { // work around for AMD driver bug for (U32 i = 0; i < pool_size; ++i) { @@ -345,7 +344,7 @@ public: void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - STOP_GLERROR; + llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); llassert(name == 0); // non zero name indicates a gl name that wasn't freed llassert(data == nullptr); // non null data indicates a buffer that wasn't freed @@ -355,10 +354,18 @@ public: { //allocate a new buffer LL_PROFILE_GPU_ZONE("vbo alloc"); - // ON OS X, we don't allocate a VBO until the last possible moment - // in unmapBuffer data = (U8*) ll_aligned_malloc_16(size); - STOP_GLERROR; + + if (type == GL_ARRAY_BUFFER) + { + glGenBuffers(1, &name); + LLVertexBuffer::sGLRenderBuffer = name; + } + else + { + glGenBuffers(1, &name); + LLVertexBuffer::sGLRenderIndices = name; + } } } @@ -374,12 +381,11 @@ public: } mAllocated -= size; - STOP_GLERROR; if (name) { delete_buffers(1, &name); } - STOP_GLERROR; + //LOG_GLERROR("LLAppleVBOPool::free()"); } }; @@ -606,6 +612,8 @@ public: static LLVBOPool* sVBOPool = nullptr; +static U32 sMPVertexBufferMode = 0; + void LLVertexBufferData::drawWithMatrix() { if (!mVB) @@ -783,7 +791,6 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - STOP_GLERROR; gGL.syncMatrices(); @@ -909,10 +916,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi llassert(mGLBuffer == sGLRenderBuffer); llassert(mGLIndices == sGLRenderIndices); gGL.syncMatrices(); - STOP_GLERROR; glDrawRangeElements(sGLMode[mode], start, end, count, mIndicesType, (GLvoid*) (indices_offset * (size_t) mIndicesStride)); - STOP_GLERROR; } void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const @@ -935,17 +940,18 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const llassert(mGLIndices == sGLRenderIndices); gGL.syncMatrices(); - STOP_GLERROR; glDrawArrays(sGLMode[mode], first, count); - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::drawArrays()"); } //static -void LLVertexBuffer::initClass(LLWindow* window) +void LLVertexBuffer::initClass(LLWindow* window, U32 mode_) { llassert(sVBOPool == nullptr); - if (gGLManager.mIsApple) + sMPVertexBufferMode = mode_; + + if (mode_ == 0 && gGLManager.mIsApple) { LL_INFOS() << "VBO Pooling Disabled" << LL_ENDL; sVBOPool = new LLAppleVBOPool(); @@ -968,12 +974,16 @@ void LLVertexBuffer::initClass(LLWindow* window) } //static +U32 LLVertexBuffer::getVertexBufferMode() +{ + return sMPVertexBufferMode; +} + +//static void LLVertexBuffer::unbind() { - STOP_GLERROR; glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - STOP_GLERROR; sGLRenderBuffer = 0; sGLRenderIndices = 0; } @@ -1288,7 +1298,7 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde count = mNumVerts - index; } - if (!gGLManager.mIsApple) + if (!gGLManager.mIsApple || sMPVertexBufferMode == 1) { U32 start = mOffsets[type] + sTypeSize[type] * index; U32 end = start + sTypeSize[type] * count-1; @@ -1325,7 +1335,7 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) count = mNumIndices-index; } - if (!gGLManager.mIsApple) + if (!gGLManager.mIsApple || sMPVertexBufferMode == 1) { U32 start = sizeof(U16) * index; U32 end = start + sizeof(U16) * count-1; @@ -1362,13 +1372,35 @@ void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8 { if (gGLManager.mIsApple) { + if(sMPVertexBufferMode == 1) + { + //LL_WARNS() << "flush_vbo mode 1" << LL_ENDL; + + U32 MapBits = GL_MAP_WRITE_BIT; + //U32 MapBits = GL_MAP_READ_BIT; + U32 buffer_size = end-start+1; + + U8 * mptr = NULL; + mptr = (U8*) glMapBufferRange( target, start, end-start+1, MapBits); + + if (mptr) + { + std::memcpy(mptr, (U8*) data, buffer_size); + if(!glUnmapBuffer(target)) LL_WARNS() << "glUnmapBuffer() failed" << LL_ENDL; + } + else LL_WARNS() << "glMapBufferRange() returned NULL" << LL_ENDL; + + } + else + { + //LL_WARNS() << "flush_vbo mode 0" << LL_ENDL; // on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call // _mapBuffer to tag the buffer for flushing to GL _mapBuffer(); LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); - STOP_GLERROR; // copy into mapped buffer memcpy(dst+start, data, end-start+1); + } } else { @@ -1412,7 +1444,6 @@ void LLVertexBuffer::_mapBuffer() void LLVertexBuffer::_unmapBuffer() { - STOP_GLERROR; if (!mMapped) { return; @@ -1426,16 +1457,16 @@ void LLVertexBuffer::_unmapBuffer() } }; - if (gGLManager.mIsApple) + if (gGLManager.mIsApple && sMPVertexBufferMode == 0) { - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 1"); if (mMappedData) { - if (mGLBuffer) + if(mGLBuffer == 0) { - delete_buffers(1, &mGLBuffer); + LL_WARNS() << "mGLBuffer is ZERO in unmapbuffer" << LL_ENDL; + glGenBuffers(1, &mGLBuffer); } - mGLBuffer = gen_buffer(); glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW); @@ -1445,16 +1476,16 @@ void LLVertexBuffer::_unmapBuffer() glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; } - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 2"); if (mMappedIndexData) { - if (mGLIndices) + if (mGLIndices == 0) { - delete_buffers(1, &mGLIndices); + LL_WARNS() << "mGLIndices is ZERO in unmapbuffer" << LL_ENDL; + glGenBuffers(1, &mGLIndices); } - mGLIndices = gen_buffer(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); sGLRenderIndices = mGLIndices; @@ -1465,7 +1496,7 @@ void LLVertexBuffer::_unmapBuffer() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); sGLRenderIndices = mGLIndices; } - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::_unmapBuffer() - apple 3"); } else { @@ -1656,11 +1687,10 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, U32 in // Set for rendering void LLVertexBuffer::setBuffer() { - STOP_GLERROR; if (mMapped) { - LL_WARNS_ONCE() << "Missing call to unmapBuffer or flushBuffers" << LL_ENDL; + LL_WARNS() << "Missing call to unmapBuffer or flushBuffers" << LL_ENDL; _unmapBuffer(); } @@ -1680,6 +1710,11 @@ void LLVertexBuffer::setBuffer() if (sGLRenderBuffer != mGLBuffer) { + if(mGLBuffer == 0) + { + LL_WARNS() << "mGLBuffer is ZERO: sGLRenderBuffer=" << sGLRenderBuffer << LL_ENDL; + } + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; @@ -1697,14 +1732,14 @@ void LLVertexBuffer::setBuffer() sGLRenderIndices = mGLIndices; } - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::setBuffer()"); } // virtual (default) void LLVertexBuffer::setupVertexBuffer() { - STOP_GLERROR; + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer()"); U8* base = nullptr; U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; @@ -1714,36 +1749,49 @@ void LLVertexBuffer::setupVertexBuffer() AttributeType loc = TYPE_NORMAL; void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_NORMAL"); } if (data_mask & MAP_TEXCOORD3) { AttributeType loc = TYPE_TEXCOORD3; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD3"); } if (data_mask & MAP_TEXCOORD2) { AttributeType loc = TYPE_TEXCOORD2; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD2"); } if (data_mask & MAP_TEXCOORD1) { AttributeType loc = TYPE_TEXCOORD1; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD1"); } if (data_mask & MAP_TANGENT) { AttributeType loc = TYPE_TANGENT; void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TANGENT"); } if (data_mask & MAP_TEXCOORD0) { AttributeType loc = TYPE_TEXCOORD0; + //glEnableVertexAttribArray(loc); void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXCOORD0"); } if (data_mask & MAP_COLOR) { @@ -1751,6 +1799,8 @@ void LLVertexBuffer::setupVertexBuffer() //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]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_COLOR"); } if (data_mask & MAP_EMISSIVE) { @@ -1758,10 +1808,14 @@ void LLVertexBuffer::setupVertexBuffer() void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_EMISSIVE"); + if (!(data_mask & MAP_COLOR)) { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps loc = TYPE_COLOR; glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_COLOR"); } } if (data_mask & MAP_WEIGHT) @@ -1769,38 +1823,50 @@ void LLVertexBuffer::setupVertexBuffer() AttributeType loc = TYPE_WEIGHT; void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_WEIGHT"); } if (data_mask & MAP_WEIGHT4) { AttributeType loc = TYPE_WEIGHT4; void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_WEIGHT4"); } if (data_mask & MAP_JOINT) { AttributeType loc = TYPE_JOINT; void* ptr = (void*)(base + mOffsets[TYPE_JOINT]); glVertexAttribIPointer(loc, 4, GL_UNSIGNED_SHORT, LLVertexBuffer::sTypeSize[TYPE_JOINT], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_JOINT"); } if (data_mask & MAP_CLOTHWEIGHT) { AttributeType loc = TYPE_CLOTHWEIGHT; void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_CLOTHWEIGHT"); } + if (data_mask & MAP_TEXTURE_INDEX) { AttributeType loc = TYPE_TEXTURE_INDEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_TEXTURE_INDEX"); } if (data_mask & MAP_VERTEX) { AttributeType loc = TYPE_VERTEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + + LOG_GLERROR("LLVertexBuffer::setupVertexBuffer TYPE_VERTEX"); } - STOP_GLERROR; } void LLVertexBuffer::setPositionData(const LLVector4a* data) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 375ad76fb8..bf5f2b5ab6 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -109,7 +109,7 @@ public: return *this; } - static void initClass(LLWindow* window); + static void initClass(LLWindow* window, U32 mode_ = 0); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void drawArrays(U32 mode, const std::vector<LLVector3>& pos); @@ -128,6 +128,8 @@ public: // flush any pending mapped buffers static void flushBuffers(); + static U32 getVertexBufferMode(); + //WARNING -- when updating these enums you MUST // 1 - update LLVertexBuffer::sTypeSize // 2 - update LLVertexBuffer::vb_type_name |