コード例 #1
0
ファイル: VertexArrayState.cpp プロジェクト: marchelbling/osg
    virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
    {
        GLExtensions* ext = state.get<GLExtensions>();

        ext->glEnableVertexAttribArray( unit );
        callVertexAttribPointer(ext, new_array, new_array->getDataPointer());
    }
コード例 #2
0
ファイル: VertexArrayState.cpp プロジェクト: marchelbling/osg
    virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array, const osg::GLBufferObject* vbo)
    {
        GLExtensions* ext = state.get<GLExtensions>();

        ext->glEnableVertexAttribArray( unit );
        callVertexAttribPointer(ext, new_array, (const GLvoid *)(vbo->getOffset(new_array->getBufferIndex())));
    }
コード例 #3
0
ファイル: PrimitiveSet.cpp プロジェクト: omega-hub/osg
void MultiDrawArrays::draw(osg::State& state, bool) const
{
    // OSG_NOTICE<<"osg::MultiDrawArrays::draw"<<std::endl;

    GLExtensions* ext = state.get<GLExtensions>();
    if (ext->glMultiDrawArrays)
    {
        GLsizei primcount = std::min(_firsts.size(), _counts.size());

        ext->glMultiDrawArrays(_mode, &_firsts.front(), &_counts.front(), primcount);
    }
}
コード例 #4
0
		virtual bool Initialise(Uint32 uiWidth, Uint32 uiHeight, const char* c_pszWindowTitle)
			{
			DebugLog("----- Initialising Application -----");
			m_bReadyToLoadRes = false;

			m_pGraphicsSys = new GraphicsSystemImpl();
			m_pResMan	   = new ResourceManagerImpl();
			m_pAudioEng	   = new AudioEngineImpl();

			Float32 fVWidth = 1024.0f;
			Float32 fVHeight = 768.0f;
			OnInitialise(fVWidth, fVHeight);		// Callback to initialise.

			DebugLog("Creating window");
			bool bResult = m_pGraphicsSys->Initialise(uiWidth, uiHeight, fVWidth, fVHeight, false, c_pszWindowTitle);
			if(!bResult)
				{
				delete m_pGraphicsSys;
				m_pGraphicsSys = NULL;
				return false;
				}

			DebugLog("Launching background loading thread.");
			// Create a thread to load background resources
			THREADID id;
			Thread::Create(&id, ThreadFunc, this);

			// Wait until the secondary context has been created
			while(m_rcSecContext == 0) Thread::Sleep(1);

			// Share this context and make it current
			((GraphicsSystemImpl*)m_pGraphicsSys)->ShareOGLContext(m_rcSecContext);
			((GraphicsSystemImpl*)m_pGraphicsSys)->MakeCurrent();

			DebugLog("Loading GL extenstions");
			// Load GL extensions
			extern GLExtensions ext;
			ext.Load();
			
			// We can now load resources.
			m_bReadyToLoadRes = true;
			m_eState = enumSTATE_ResourceLoading;

			// Notify that OpenGL has initialised.
			OnViewInitialised();		// OpenGL initialised.
			DebugLog("View Initialised.");
	
			// Get the current tick count
			QueryPerformanceCounter((LARGE_INTEGER*)&m_n64TimeStart);

			return bResult;
			}
コード例 #5
0
ファイル: gpu_features.cpp プロジェクト: AmesianX/ppsspp
int GLExtensions::GLSLVersion() {
	// Used for shader translation and core contexts (Apple drives fail without an exact match.)
	if (gl_extensions.VersionGEThan(3, 3)) {
		return gl_extensions.ver[0] * 100 + gl_extensions.ver[1] * 10;
	} else if (gl_extensions.VersionGEThan(3, 2)) {
		return 150;
	} else if (gl_extensions.VersionGEThan(3, 1)) {
		return 140;
	} else if (gl_extensions.VersionGEThan(3, 0)) {
		return 130;
	} else if (gl_extensions.VersionGEThan(2, 1)) {
		return 120;
	} else {
		return 110;
	}
}
コード例 #6
0
ファイル: BufferObject.cpp プロジェクト: marchelbling/osg
//--------------------------------------------------------------------------------
void PixelDataBufferObject::unbindBuffer(unsigned int contextID) const
{
    GLExtensions* extensions = GLExtensions::Get(contextID, true);

    switch(_mode[contextID])
    {
        case READ:
            extensions->glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
            break;
        case WRITE:
            extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB,0);
            break;
        default:
            extensions->glBindBuffer(_profile._target,0);
            break;
    }

    _mode[contextID] = NONE;
}
コード例 #7
0
ファイル: GraphicsContext.cpp プロジェクト: 4ker/osg
void SyncSwapBuffersCallback::swapBuffersImplementation(osg::GraphicsContext* gc)
{
    // OSG_NOTICE<<"Before swap - place to do swap ready sync"<<std::endl;
    gc->swapBuffersImplementation();
    //glFinish();

    GLExtensions* ext = gc->getState()->get<GLExtensions>();

    if (ext->glClientWaitSync)
    {
        if (_previousSync)
        {
            unsigned int num_seconds = 1;
            GLuint64 timeout = num_seconds * ((GLuint64)1000 * 1000 * 1000);
            ext->glClientWaitSync(_previousSync, 0, timeout);
            ext->glDeleteSync(_previousSync);
        }

        _previousSync = ext->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    }
    //gc->getState()->checkGLErrors("after glWaitSync");

    //OSG_NOTICE<<"After swap"<<std::endl;
}
コード例 #8
0
ファイル: gpu_features.cpp プロジェクト: AmesianX/ppsspp
std::string ApplyGLSLPrelude(const std::string &source, uint32_t stage) {
#if !PPSSPP_PLATFORM(UWP)
	std::string temp;
	std::string version = "";
	if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) {
		// We need to add a corresponding #version.  Apple drivers fail without an exact match.
		version = StringFromFormat("#version %d\n", gl_extensions.GLSLVersion());
	}
	if (stage == GL_FRAGMENT_SHADER) {
		temp = version + glsl_fragment_prelude + source;
	} else if (stage == GL_VERTEX_SHADER) {
		temp = version + source;
	}
	return temp;
#else
	return source;
#endif
}
コード例 #9
0
GLfloat GLAPIENTRY glGetPathLengthNV(GLuint path,GLsizei startSegment, GLsizei numSegments)
{
  uint funcIndex = s_manualExtensions[EWF_GL_GET_PATH_LENGTH_NV].m_index;

#ifdef OS_ARCH_x86
  glDriver.LogFunctionPre (funcIndex,FunctionArgs((char*)&path));
#elif defined(OS_ARCH_x64)
  FunctionParamStore localParamStore = FunctionParamStore(path, startSegment, numSegments);
  glDriver.LogFunctionPre (funcIndex, FunctionArgs((char *)&localParamStore.m_paramStore[0]));
#else
  #error Unknown platform
#endif

  // Call the real method
  GLfloat retValue = GLEXT.glGetPathLengthNV(path, startSegment, numSegments);

  glDriver.LogFunctionPost(funcIndex,FunctionRetValue((void*)0,retValue));

  return retValue;
}
コード例 #10
0
GLuint64 GLAPIENTRY glGetImageHandleNV(GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format)
{
  uint funcIndex = s_manualExtensions[EWF_GL_GET_IMAGE_HANDLE_NV].m_index;

#ifdef OS_ARCH_x86
  glDriver.LogFunctionPre (funcIndex,FunctionArgs((char*)&texture));
#elif defined(OS_ARCH_x64)
  FunctionParamStore localParamStore = FunctionParamStore(texture, level, layered, layer, format);
  glDriver.LogFunctionPre (funcIndex, FunctionArgs((char *)&localParamStore.m_paramStore[0]));
#else
  #error Unknown platform
#endif

  // Call the real method
  GLuint64 retValue = GLEXT.glGetImageHandleNV(texture, level, layered, layer, format);

  glDriver.LogFunctionPost(funcIndex,FunctionRetValue(retValue));

  return retValue;
}
コード例 #11
0
GLuint64 GLAPIENTRY glGetTextureSamplerHandleNV(GLuint texture, GLuint sampler)
{
  uint funcIndex = s_manualExtensions[EWF_GL_GET_TEXTURE_SAMPLER_HANDLE_NV].m_index;

#ifdef OS_ARCH_x86
  glDriver.LogFunctionPre (funcIndex,FunctionArgs((char*)&texture));
#elif defined(OS_ARCH_x64)
  FunctionParamStore localParamStore = FunctionParamStore(texture, sampler);
  glDriver.LogFunctionPre (funcIndex, FunctionArgs((char *)&localParamStore.m_paramStore[0]));
#else
  #error Unknown platform
#endif

  // Call the real method
  GLuint64 retValue = GLEXT.glGetTextureSamplerHandleNV(texture, sampler);

  glDriver.LogFunctionPost(funcIndex,FunctionRetValue(retValue));

  return retValue;
}
コード例 #12
0
ファイル: FrameBufferObject.cpp プロジェクト: yueying/osg
void FrameBufferObject::apply(State &state, BindTarget target) const
{
    unsigned int contextID = state.getContextID();

    if (_unsupported[contextID])
        return;


    GLExtensions* ext = state.get<GLExtensions>();
    if (!ext->isFrameBufferObjectSupported)
    {
        _unsupported[contextID] = 1;
        OSG_WARN << "Warning: EXT_framebuffer_object is not supported" << std::endl;
        return;
    }

    if (_attachments.empty())
    {
        ext->glBindFramebuffer(target, 0);
        return;
    }

    int &dirtyAttachmentList = _dirtyAttachmentList[contextID];

    GLuint &fboID = _fboID[contextID];
    if (fboID == 0)
    {
        ext->glGenFramebuffers(1, &fboID);
        if (fboID == 0)
        {
            OSG_WARN << "Warning: FrameBufferObject: could not create the FBO" << std::endl;
            return;
        }

        dirtyAttachmentList = 1;

    }

    if (dirtyAttachmentList)
    {
        // the set of of attachments appears to be thread sensitive, it shouldn't be because
        // OpenGL FBO handles osg::FrameBufferObject has are multi-buffered...
        // so as a temporary fix will stick in a mutex to ensure that only one thread passes through here
        // at one time.
        static OpenThreads::Mutex s_mutex;
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex);

        // create textures and mipmaps before we bind the frame buffer object
        for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
        {
            const FrameBufferAttachment &fa = i->second;
            fa.createRequiredTexturesAndApplyGenerateMipMap(state, ext);
        }

    }


    ext->glBindFramebuffer(target, fboID);

    // enable drawing buffers to render the result to fbo
    if ( (target == READ_DRAW_FRAMEBUFFER) || (target == DRAW_FRAMEBUFFER) )
    {
        if (_drawBuffers.size() > 0)
        {
            GLExtensions *gl2e = state.get<GLExtensions>();
            if (gl2e && gl2e->glDrawBuffers)
            {
                gl2e->glDrawBuffers(_drawBuffers.size(), &(_drawBuffers[0]));
            }
            else
            {
                OSG_WARN <<"Warning: FrameBufferObject: could not set draw buffers, glDrawBuffers is not supported!" << std::endl;
            }
        }
    }

    if (dirtyAttachmentList)
    {
        for (AttachmentMap::const_iterator i=_attachments.begin(); i!=_attachments.end(); ++i)
        {
            const FrameBufferAttachment &fa = i->second;
            switch(i->first)
            {
                case(Camera::PACKED_DEPTH_STENCIL_BUFFER):
                    if (ext->isPackedDepthStencilSupported)
                    {
                        fa.attach(state, target, GL_DEPTH_ATTACHMENT_EXT, ext);
                        fa.attach(state, target, GL_STENCIL_ATTACHMENT_EXT, ext);
                    }
                    else
                    {
                        OSG_WARN <<
                            "Warning: FrameBufferObject: could not attach PACKED_DEPTH_STENCIL_BUFFER, "
                            "EXT_packed_depth_stencil is not supported!" << std::endl;
                    }
                    break;

                default:
                    fa.attach(state, target, convertBufferComponentToGLenum(i->first), ext);
                    break;
            }
        }
        dirtyAttachmentList = 0;
    }

}
コード例 #13
0
ファイル: VertexArrayState.cpp プロジェクト: marchelbling/osg
 virtual void disable(osg::State& state)
 {
     GLExtensions* ext = state.get<GLExtensions>();
     ext->glDisableVertexAttribArray( unit );
 }
コード例 #14
0
ファイル: gpu_features.cpp プロジェクト: FTPiano/ppsspp
void CheckGLExtensions() {

#if !PPSSPP_PLATFORM(UWP)

	// Make sure to only do this once. It's okay to call CheckGLExtensions from wherever.
	if (extensionsDone)
		return;
	extensionsDone = true;
	memset(&gl_extensions, 0, sizeof(gl_extensions));
	gl_extensions.IsCoreContext = useCoreContext;

#ifdef USING_GLES2
	gl_extensions.IsGLES = true;
#endif

	const char *renderer = (const char *)glGetString(GL_RENDERER);
	const char *versionStr = (const char *)glGetString(GL_VERSION);
	const char *glslVersionStr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);

	// Check vendor string to try and guess GPU
	const char *cvendor = (char *)glGetString(GL_VENDOR);
	// TODO: move this stuff to gpu_features.cpp
	if (cvendor) {
		const std::string vendor = StripSpaces(std::string(cvendor));
		if (vendor == "NVIDIA Corporation"
			|| vendor == "Nouveau"
			|| vendor == "nouveau") {
			gl_extensions.gpuVendor = GPU_VENDOR_NVIDIA;
		} else if (vendor == "Advanced Micro Devices, Inc."
			|| vendor == "ATI Technologies Inc.") {
			gl_extensions.gpuVendor = GPU_VENDOR_AMD;
		} else if (vendor == "Intel"
			|| vendor == "Intel Inc."
			|| vendor == "Intel Corporation"
			|| vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel
			gl_extensions.gpuVendor = GPU_VENDOR_INTEL;
		} else if (vendor == "ARM") {
			gl_extensions.gpuVendor = GPU_VENDOR_ARM;
		} else if (vendor == "Imagination Technologies") {
			gl_extensions.gpuVendor = GPU_VENDOR_POWERVR;
		} else if (vendor == "Qualcomm") {
			gl_extensions.gpuVendor = GPU_VENDOR_ADRENO;
		} else if (vendor == "Broadcom") {
			gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM;
			// Just for reference: Galaxy Y has renderer == "VideoCore IV HW"
		} else {
			gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN;
		}
	} else {
		gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN;
	}

	ILOG("GPU Vendor : %s ; renderer: %s version str: %s ; GLSL version str: %s", cvendor, renderer ? renderer : "N/A", versionStr ? versionStr : "N/A", glslVersionStr ? glslVersionStr : "N/A");

	if (renderer) {
		strncpy(gl_extensions.model, renderer, sizeof(gl_extensions.model));
		gl_extensions.model[sizeof(gl_extensions.model) - 1] = 0;
	}

	if (!gl_extensions.IsGLES) {
		// For desktop GL, grab the version and attempt to parse.
		char buffer[64] = { 0 };
		if (versionStr) {
			strncpy(buffer, versionStr, 63);
		}
		const char *lastNumStart = buffer;
		int numVer = 0;
		int len = (int)strlen(buffer);
		for (int i = 0; i < len && numVer < 3; i++) {
			if (buffer[i] == '.') {
				buffer[i] = 0;
				gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10);
				i++;
				lastNumStart = buffer + i;
			}
		}
		if (numVer < 3)
			gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10);

		// If the GL version >= 4.3, we know it's a true superset of OpenGL ES 3.0 and can thus enable
		// all the same modern paths.
		// Most of it could be enabled on lower GPUs as well, but let's start this way.
		if (gl_extensions.VersionGEThan(4, 3, 0)) {
			gl_extensions.GLES3 = true;
		}
	} else {
		// Start by assuming we're at 2.0.
		gl_extensions.ver[0] = 2;

#ifdef USING_GLES2
#ifdef GL_MAJOR_VERSION
		// Before grabbing the values, reset the error.
		glGetError();
		glGetIntegerv(GL_MAJOR_VERSION, &gl_extensions.ver[0]);
		glGetIntegerv(GL_MINOR_VERSION, &gl_extensions.ver[1]);
		// We check error here to detect if these properties were supported.
		if (glGetError() != GL_NO_ERROR) {
			// They weren't, reset to GLES 2.0.
			gl_extensions.ver[0] = 2;
			gl_extensions.ver[1] = 0;
		}
#endif

		// If the above didn't give us a version, or gave us a crazy version, fallback.
		if (gl_extensions.ver[0] < 3 || gl_extensions.ver[0] > 5) {
			// Try to load GLES 3.0 only if "3.0" found in version
			// This simple heuristic avoids issues on older devices where you can only call eglGetProcAddress a limited
			// number of times. Make sure to check for 3.0 in the shader version too to avoid false positives, see #5584.
			bool gl_3_0_in_string = strstr(versionStr, "3.0") && strstr(glslVersionStr, "3.0");
			bool gl_3_1_in_string = strstr(versionStr, "3.1") && strstr(glslVersionStr, "3.1");  // intentionally left out .1
			if ((gl_3_0_in_string || gl_3_1_in_string) && gl3stubInit()) {
				gl_extensions.ver[0] = 3;
				if (gl_3_1_in_string) {
					gl_extensions.ver[1] = 1;
				}
				gl_extensions.GLES3 = true;
				// Though, let's ban Mali from the GLES 3 path for now, see #4078
				if (strstr(renderer, "Mali") != 0) {
					gl_extensions.GLES3 = false;
				}
			} else {
				// Just to be safe.
				gl_extensions.ver[0] = 2;
				gl_extensions.ver[1] = 0;
			}
		} else {
			// Otherwise, let's trust GL_MAJOR_VERSION.  Note that Mali is intentionally not banned here.
			if (gl_extensions.ver[0] >= 3) {
				gl_extensions.GLES3 = gl3stubInit();
			}
		}
#endif

		if (gl_extensions.GLES3) {
			if (gl_extensions.ver[1] >= 1) {
				ILOG("OpenGL ES 3.1 support detected!\n");
			} else {
				ILOG("OpenGL ES 3.0 support detected!\n");
			}
		}
	}

	const char *extString = nullptr;
	if (gl_extensions.ver[0] >= 3) {
		// Let's use the new way for OpenGL 3.x+, required in the core profile.
		GLint numExtensions = 0;
		glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
		g_all_gl_extensions = "";
		for (GLint i = 0; i < numExtensions; ++i) {
			g_all_gl_extensions += (const char *)glGetStringi(GL_EXTENSIONS, i);
			g_all_gl_extensions += " ";
		}
		extString = g_all_gl_extensions.c_str();
	} else {
		extString = (const char *)glGetString(GL_EXTENSIONS);
		if (extString) {
			g_all_gl_extensions = extString;
		} else {
			g_all_gl_extensions = "";
			extString = "";
		}
	}

#ifdef WIN32
	const char *wglString = 0;
	if (wglGetExtensionsStringEXT)
		wglString = wglGetExtensionsStringEXT();
	if (wglString) {
		gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0;
		g_all_egl_extensions = wglString;
	} else {
		g_all_egl_extensions = "";
	}
#elif !defined(USING_GLES2)
	// const char *glXString = glXQueryExtensionString();
	// gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0;
#endif

	// Check the desktop extension instead of the OES one. They are very similar.
	// Also explicitly check those ATI devices that claims to support npot
	gl_extensions.OES_texture_npot = strstr(extString, "GL_ARB_texture_non_power_of_two") != 0
		&& !(((strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0)));

	gl_extensions.ARB_blend_func_extended = strstr(extString, "GL_ARB_blend_func_extended") != 0;
	gl_extensions.EXT_blend_func_extended = strstr(extString, "GL_EXT_blend_func_extended") != 0;
	gl_extensions.ARB_conservative_depth = strstr(extString, "GL_ARB_conservative_depth") != 0;
	gl_extensions.ARB_shader_image_load_store = (strstr(extString, "GL_ARB_shader_image_load_store") != 0) || (strstr(extString, "GL_EXT_shader_image_load_store") != 0);
	gl_extensions.EXT_bgra = strstr(extString, "GL_EXT_bgra") != 0;
	gl_extensions.EXT_gpu_shader4 = strstr(extString, "GL_EXT_gpu_shader4") != 0;
	gl_extensions.NV_framebuffer_blit = strstr(extString, "GL_NV_framebuffer_blit") != 0;
	gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0;
	gl_extensions.OES_copy_image = strstr(extString, "GL_OES_copy_image") != 0;
	gl_extensions.EXT_copy_image = strstr(extString, "GL_EXT_copy_image") != 0;
	gl_extensions.ARB_copy_image = strstr(extString, "GL_ARB_copy_image") != 0;
	gl_extensions.ARB_vertex_array_object = strstr(extString, "GL_ARB_vertex_array_object") != 0;
	gl_extensions.ARB_texture_float = strstr(extString, "GL_ARB_texture_float") != 0;

	if (gl_extensions.IsGLES) {
		gl_extensions.OES_texture_npot = strstr(extString, "GL_OES_texture_npot") != 0;
		gl_extensions.OES_packed_depth_stencil = (strstr(extString, "GL_OES_packed_depth_stencil") != 0) || gl_extensions.GLES3;
		gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0;
		gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0;
		gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0;
		gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0;
		gl_extensions.EXT_unpack_subimage = strstr(extString, "GL_EXT_unpack_subimage") != 0;
		gl_extensions.EXT_shader_framebuffer_fetch = strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0;
		gl_extensions.NV_shader_framebuffer_fetch = strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0;
		gl_extensions.ARM_shader_framebuffer_fetch = strstr(extString, "GL_ARM_shader_framebuffer_fetch") != 0;
		gl_extensions.OES_texture_float = strstr(extString, "GL_OES_texture_float") != 0;
		gl_extensions.OES_texture_half_float = strstr(extString, "GL_OES_texture_half_float") != 0;

#if defined(__ANDROID__)
		// On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though.
		// https://twitter.com/ID_AA_Carmack/status/387383037794603008
#ifdef _DEBUG
		void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1");
		void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2");
		DLOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2);
#endif

		// These are all the same.  Let's alias.
		if (!gl_extensions.OES_copy_image) {
			if (gl_extensions.NV_copy_image) {
				glCopyImageSubDataOES = (decltype(glCopyImageSubDataOES))eglGetProcAddress("glCopyImageSubDataNV");
			} else if (gl_extensions.EXT_copy_image) {
				glCopyImageSubDataOES = (decltype(glCopyImageSubDataOES))eglGetProcAddress("glCopyImageSubDataEXT");
			}
		}

		if (gl_extensions.NV_framebuffer_blit) {
			glBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC)eglGetProcAddress("glBlitFramebufferNV");
		}

		gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0;
		if (gl_extensions.OES_vertex_array_object) {
			glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
			glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
			glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES");
			glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
		}

		// Hm, this should be available on iOS too.
		gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0;
		if (gl_extensions.EXT_discard_framebuffer) {
			glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT");
		}
#else
		gl_extensions.OES_vertex_array_object = false;
		gl_extensions.EXT_discard_framebuffer = false;
#endif
	} else {
		// Desktops support minmax and subimage unpack (GL_UNPACK_ROW_LENGTH etc)
		gl_extensions.EXT_blend_minmax = true;
		gl_extensions.EXT_unpack_subimage = true;
	}

	// GLES 3 subsumes many ES2 extensions.
	if (gl_extensions.GLES3) {
		gl_extensions.EXT_unpack_subimage = true;
	}

#if defined(__ANDROID__)
	if (gl_extensions.OES_mapbuffer) {
		glMapBuffer = (PFNGLMAPBUFFERPROC)eglGetProcAddress("glMapBufferOES");
	}

	// Look for EGL extensions
	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

	const char *eglString = eglQueryString(display, EGL_EXTENSIONS);
	if (eglString) {
		g_all_egl_extensions = eglString;

		gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0;
		gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0;

		if (gl_extensions.EGL_NV_system_time) {
			eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC)eglGetProcAddress("eglGetSystemTimeNV");
			eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC)eglGetProcAddress("eglGetSystemTimeFrequencyNV");
		}
	} else {
		g_all_egl_extensions = "";
	}
#endif

	// This is probably a waste of time, implementations lie.
	if (gl_extensions.IsGLES || strstr(extString, "GL_ARB_ES2_compatibility")) {
		const GLint precisions[6] = {
			GL_LOW_FLOAT, GL_MEDIUM_FLOAT, GL_HIGH_FLOAT,
			GL_LOW_INT, GL_MEDIUM_INT, GL_HIGH_INT
		};
		GLint shaderTypes[2] = {
			GL_VERTEX_SHADER, GL_FRAGMENT_SHADER
		};
		for (int st = 0; st < 2; st++) {
			for (int p = 0; p < 6; p++) {
				glGetShaderPrecisionFormat(shaderTypes[st], precisions[p], gl_extensions.range[st][p], &gl_extensions.precision[st][p]);
			}
		}
	}

	gl_extensions.ARB_framebuffer_object = strstr(extString, "GL_ARB_framebuffer_object") != 0;
	gl_extensions.EXT_framebuffer_object = strstr(extString, "GL_EXT_framebuffer_object") != 0;
	gl_extensions.ARB_pixel_buffer_object = strstr(extString, "GL_ARB_pixel_buffer_object") != 0;
	gl_extensions.NV_pixel_buffer_object = strstr(extString, "GL_NV_pixel_buffer_object") != 0;

	if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) {
		// These are required, and don't need to be specified by the driver (they aren't on Apple.)
		gl_extensions.ARB_vertex_array_object = true;
		gl_extensions.ARB_framebuffer_object = true;
	}
#ifdef __APPLE__
	if (!gl_extensions.IsGLES && !gl_extensions.IsCoreContext) {
		// Apple doesn't allow OpenGL 3.x+ in compatibility contexts.
		gl_extensions.ForceGL2 = true;
	}
#endif

	ProcessGPUFeatures();

	int error = glGetError();
	if (error)
		ELOG("GL error in init: %i", error);

#endif

}
コード例 #15
0
ファイル: gl_state.cpp プロジェクト: Bublafus/native
void CheckGLExtensions() {
	// Make sure to only do this once. It's okay to call CheckGLExtensions from wherever.
	static bool done = false;
	if (done)
		return;
	done = true;
	memset(&gl_extensions, 0, sizeof(gl_extensions));

	const char *renderer = (const char *)glGetString(GL_RENDERER);
	const char *versionStr = (const char *)glGetString(GL_VERSION);

	// Check vendor string to try and guess GPU
	const char *cvendor = (char *)glGetString(GL_VENDOR);
	// TODO: move this stuff to gpu_features.cpp
	if (cvendor) {
		const std::string vendor(cvendor);
		if (vendor == "NVIDIA Corporation"
			|| vendor == "Nouveau"
			|| vendor == "nouveau") {
				gl_extensions.gpuVendor = GPU_VENDOR_NVIDIA;
		} else if (vendor == "Advanced Micro Devices, Inc."
			|| vendor == "ATI Technologies Inc.") {
				gl_extensions.gpuVendor = GPU_VENDOR_AMD;
		} else if (vendor == "Intel"
			|| vendor == "Intel Inc."
			|| vendor == "Intel Corporation"
			|| vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel
				gl_extensions.gpuVendor = GPU_VENDOR_INTEL;
		} else if (vendor == "ARM") {
			gl_extensions.gpuVendor = GPU_VENDOR_ARM;
		} else if (vendor == "Imagination Technologies") {
			gl_extensions.gpuVendor = GPU_VENDOR_POWERVR;
		} else if (vendor == "Qualcomm") {
			gl_extensions.gpuVendor = GPU_VENDOR_ADRENO;
		} else if (vendor == "Broadcom") {
			gl_extensions.gpuVendor = GPU_VENDOR_BROADCOM;
			// Just for reference: Galaxy Y has renderer == "VideoCore IV HW"
		} else {
			gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN;
		}
	} else {
		gl_extensions.gpuVendor = GPU_VENDOR_UNKNOWN;
	}

	ILOG("GPU Vendor : %s ; GL version str: %s", cvendor, versionStr ? versionStr : "N/A");

#ifndef USING_GLES2
	char buffer[64] = {0};
	if (versionStr) {
		strncpy(buffer, versionStr, 63);
	}
	const char *lastNumStart = buffer;
	int numVer = 0;
	int len = (int)strlen(buffer);
	for (int i = 0; i < len && numVer < 3; i++) {
		if (buffer[i] == '.') {
			buffer[i] = 0;
			gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10);
			i++;
			lastNumStart = buffer + i;
		}
	}
	if (numVer < 3)
		gl_extensions.ver[numVer++] = strtol(lastNumStart, NULL, 10);
#else
	gl_extensions.ver[0] = 2;
#endif

#if defined(USING_GLES2)
	// MAY_HAVE_GLES3 defined on all platforms that support it
#if defined(MAY_HAVE_GLES3)
	// Try to load GLES 3.0 only if "3.0" found in version
	// This simple heuristic avoids issues on older devices where you can only call eglGetProcAddress a limited
	// number of times.
	if (strstr(versionStr, "3.0") && GL_TRUE == gl3stubInit()) {
		gl_extensions.ver[0] = 3;
		gl_extensions.GLES3 = true;
		ILOG("Full OpenGL ES 3.0 support detected!\n");
		// Though, let's ban Mali from the GLES 3 path for now, see #4078
		if (strstr(renderer, "Mali") != 0) {
			gl_extensions.GLES3 = false;
		}
	}
#endif
#else
	// If the GL version >= 4.3, we know it's a true superset of OpenGL ES 3.0 and can thus enable
	// all the same modern paths.
	// Most of it could be enabled on lower GPUs as well, but let's start this way.
	if (gl_extensions.VersionGEThan(4, 3, 0)) {
		gl_extensions.GLES3 = true;
	}
#endif

	const char *extString = (const char *)glGetString(GL_EXTENSIONS);
	if (extString) {
		g_all_gl_extensions = extString;
	} else {
		g_all_gl_extensions = "";
	}

#ifdef WIN32
	const char *wglString = 0;
	if (wglGetExtensionsStringEXT)
		wglString = wglGetExtensionsStringEXT();
	if (wglString) {
		gl_extensions.EXT_swap_control_tear = strstr(wglString, "WGL_EXT_swap_control_tear") != 0;
		g_all_egl_extensions = wglString;
	} else {
		g_all_egl_extensions = "";
	}
#elif !defined(USING_GLES2)
	// const char *glXString = glXQueryExtensionString();
	// gl_extensions.EXT_swap_control_tear = strstr(glXString, "GLX_EXT_swap_control_tear") != 0;
#endif

	// Check the desktop extension instead of the OES one. They are very similar.
	// Also explicitly check those ATI devices that claims to support npot
	gl_extensions.OES_texture_npot = strstr(extString, "GL_ARB_texture_non_power_of_two") != 0
		&& !(((strncmp(renderer, "ATI RADEON X", 12) == 0) || (strncmp(renderer, "ATI MOBILITY RADEON X", 21) == 0)));

	gl_extensions.NV_draw_texture = strstr(extString, "GL_NV_draw_texture") != 0;
	gl_extensions.ARB_blend_func_extended = strstr(extString, "GL_ARB_blend_func_extended") != 0;
	gl_extensions.ARB_shader_image_load_store = (strstr(extString, "GL_ARB_shader_image_load_store") != 0) || (strstr(extString, "GL_EXT_shader_image_load_store") != 0);
	if (gl_extensions.gpuVendor == GPU_VENDOR_INTEL || !gl_extensions.VersionGEThan(3, 0, 0)) {
		// Force this extension to off on sub 3.0 OpenGL versions as it does not seem reliable
		// Also on Intel, see https://github.com/hrydgard/ppsspp/issues/4867
		gl_extensions.ARB_blend_func_extended = false;
	}

#ifdef USING_GLES2
	gl_extensions.OES_texture_npot = strstr(extString, "OES_texture_npot") != 0;
	gl_extensions.OES_packed_depth_stencil = strstr(extString, "GL_OES_packed_depth_stencil") != 0;
	gl_extensions.OES_depth24 = strstr(extString, "GL_OES_depth24") != 0;
	gl_extensions.OES_depth_texture = strstr(extString, "GL_OES_depth_texture") != 0;
	gl_extensions.OES_mapbuffer = strstr(extString, "GL_OES_mapbuffer") != 0;
	gl_extensions.EXT_blend_minmax = strstr(extString, "GL_EXT_blend_minmax") != 0;
	gl_extensions.EXT_shader_framebuffer_fetch = (strstr(extString, "GL_EXT_shader_framebuffer_fetch") != 0) || (strstr(extString, "GL_NV_shader_framebuffer_fetch") != 0);
	gl_extensions.NV_copy_image = strstr(extString, "GL_NV_copy_image") != 0;
	gl_extensions.EXT_unpack_subimage = strstr(extString, "GL_EXT_unpack_subimage") != 0;
#if defined(ANDROID) || defined(BLACKBERRY)
	// On Android, incredibly, this is not consistently non-zero! It does seem to have the same value though.
	// https://twitter.com/ID_AA_Carmack/status/387383037794603008
#ifdef _DEBUG
	void *invalidAddress = (void *)eglGetProcAddress("InvalidGlCall1");
	void *invalidAddress2 = (void *)eglGetProcAddress("AnotherInvalidGlCall2");
	DLOG("Addresses returned for invalid extensions: %p %p", invalidAddress, invalidAddress2);
#endif

	if (gl_extensions.NV_draw_texture) {
		glDrawTextureNV = (PFNGLDRAWTEXTURENVPROC)eglGetProcAddress("glDrawTextureNV");
	}

	if (gl_extensions.NV_copy_image) {
		glCopyImageSubDataNV = (PFNGLCOPYIMAGESUBDATANVPROC)eglGetProcAddress("glCopyImageSubDataNV");
	}

	gl_extensions.OES_vertex_array_object = strstr(extString, "GL_OES_vertex_array_object") != 0;
	if (gl_extensions.OES_vertex_array_object) {
		glGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress ( "glGenVertexArraysOES" );
		glBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress ( "glBindVertexArrayOES" );
		glDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress ( "glDeleteVertexArraysOES" );
		glIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress ( "glIsVertexArrayOES" );
	}

	gl_extensions.EXT_discard_framebuffer = strstr(extString, "GL_EXT_discard_framebuffer") != 0;
	if (gl_extensions.EXT_discard_framebuffer) {
		glDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC)eglGetProcAddress("glDiscardFramebufferEXT");
	}
#else
	gl_extensions.OES_vertex_array_object = false;
	gl_extensions.EXT_discard_framebuffer = false;
#endif
#else
	// Desktops support minmax and subimage unpack (GL_UNPACK_ROW_LENGTH etc)
	gl_extensions.EXT_blend_minmax = true;
	gl_extensions.EXT_unpack_subimage = true;
#endif
	// GLES 3 subsumes many ES2 extensions.
	if (gl_extensions.GLES3) {
		gl_extensions.EXT_unpack_subimage = true;
	}

#if defined(ANDROID) || defined(BLACKBERRY)
	if (gl_extensions.OES_mapbuffer) {
		glMapBuffer = (PFNGLMAPBUFFERPROC)eglGetProcAddress( "glMapBufferOES" );
	}

	// Look for EGL extensions
	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

	const char *eglString = eglQueryString(display, EGL_EXTENSIONS);
	if (eglString) {
		g_all_egl_extensions = eglString;

		gl_extensions.EGL_NV_system_time = strstr(eglString, "EGL_NV_system_time") != 0;
		gl_extensions.EGL_NV_coverage_sample = strstr(eglString, "EGL_NV_coverage_sample") != 0;

		if (gl_extensions.EGL_NV_system_time) {
			eglGetSystemTimeNV = (PFNEGLGETSYSTEMTIMENVPROC) eglGetProcAddress("eglGetSystemTimeNV");
			eglGetSystemTimeFrequencyNV = (PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) eglGetProcAddress("eglGetSystemTimeFrequencyNV");
		}
	} else {
		g_all_egl_extensions = "";
	}
#endif

#ifdef USING_GLES2
	gl_extensions.FBO_ARB = true;
	gl_extensions.FBO_EXT = false;
#else
	gl_extensions.FBO_ARB = false;
	gl_extensions.FBO_EXT = false;
	gl_extensions.PBO_ARB = true;
	if (extString) {
		gl_extensions.FBO_ARB = strstr(extString, "GL_ARB_framebuffer_object") != 0;
		gl_extensions.FBO_EXT = strstr(extString, "GL_EXT_framebuffer_object") != 0;
		gl_extensions.PBO_ARB = strstr(extString, "GL_ARB_pixel_buffer_object") != 0;
	}
#endif

	ProcessGPUFeatures();
}