/// <summary> /// Reallocates the renderbuffer's storage. /// </summary> /// <param name="width">The renderbuffer's width in pixels.</param> /// <param name="height">The renderbuffer's height in pixels.</param> private void AllocateRenderbufferStorage(Int32 width, Int32 height) { using (OpenGLState.ScopedBindRenderbuffer(renderbuffer, true)) { switch (format) { case RenderBufferFormat.Color: gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.IsGLES2 ? gl.GL_RGBA4 : gl.GL_RGBA8, width, height); gl.ThrowIfError(); break; case RenderBufferFormat.Depth24Stencil8: gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH24_STENCIL8, width, height); gl.ThrowIfError(); break; case RenderBufferFormat.Depth32: gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT32, width, height); gl.ThrowIfError(); break; case RenderBufferFormat.Depth16: gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT16, width, height); gl.ThrowIfError(); break; case RenderBufferFormat.Stencil8: gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_STENCIL_INDEX8, width, height); break; default: throw new NotSupportedException("format"); } } }
/// <summary> /// Initializes a new instance of the <see cref="OpenGLGraphicsCapabilities"/> class. /// </summary> /// <param name="configuration">The configuration settings for the Ultraviolet context.</param> internal unsafe OpenGLGraphicsCapabilities(OpenGLUltravioletConfiguration configuration) { this.maximumTextureSize = gl.GetInteger(gl.GL_MAX_TEXTURE_SIZE); gl.ThrowIfError(); var viewportDims = stackalloc int[2]; gl.GetIntegerv(gl.GL_MAX_VIEWPORT_DIMS, viewportDims); gl.ThrowIfError(); this.maximumViewportWidth = viewportDims[0]; this.maximumViewportHeight = viewportDims[1]; this.supportsDepthStencilTextures = !gl.IsGLES2 || gl.IsExtensionSupported("GL_OES_packed_depth_stencil"); if (gl.IsGLES2 && !this.supportsDepthStencilTextures) { // HACK: Guess what? The Visual Studio Emulator for Android flat-out lies about this. // So it seems the only reliable way to determine support for depth/stencil is to // actually try to create one and see if it fails. I hate Android emulators. var rb = gl.GenRenderbuffer(); using (var state = OpenGLState.ScopedBindRenderbuffer(rb, true)) { gl.RenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH24_STENCIL8, 32, 32); this.supportsDepthStencilTextures = (gl.GetError() == gl.GL_NO_ERROR); } gl.DeleteRenderBuffers(rb); } this.SupportsNonZeroBaseInstance = SupportsInstancedRendering && !gl.IsGLES && (gl.IsVersionAtLeast(4, 2) || gl.IsExtensionSupported("GL_ARB_base_instance")); this.SupportsIndependentSamplerState = (gl.IsGLES ? gl.IsVersionAtLeast(3, 0) : gl.IsVersionAtLeast(3, 3)) || gl.IsExtensionSupported("GL_ARB_sampler_objects"); this.SupportsIntegerVertexAttributes = !gl.IsGLES2 || gl.IsExtensionSupported("GL_EXT_gpu_shader4"); this.SupportsDoublePrecisionVertexAttributes = !gl.IsGLES && gl.IsVersionAtLeast(4, 1); this.SupportsMapBufferRange = true; if (gl.IsGLES2) { this.SupportsMapBufferRange = gl.IsExtensionSupported("GL_ARB_map_buffer_range") || gl.IsExtensionSupported("GL_EXT_map_buffer_range"); } this.MinMapBufferAlignment = gl.IsExtensionSupported("GL_ARB_map_buffer_alignment") ? gl.GetInteger(gl.GL_MIN_MAP_BUFFER_ALIGNMENT) : 0; // There seems to be a bug in the version of Mesa which is distributed // with Ubuntu 16.04 that causes long stalls when using glMapBufferRange. // Testing indicates that this is fixed in 11.2.2. var version = gl.GetString(gl.GL_VERSION); var versionMatchMesa = Regex.Match(version, "Mesa (?<major>\\d+).(?<minor>\\d+).(?<build>\\d+)"); if (versionMatchMesa != null && versionMatchMesa.Success) { var mesaMajor = Int32.Parse(versionMatchMesa.Groups["major"].Value); var mesaMinor = Int32.Parse(versionMatchMesa.Groups["minor"].Value); var mesaBuild = Int32.Parse(versionMatchMesa.Groups["build"].Value); var mesaVersion = new Version(mesaMajor, mesaMinor, mesaBuild); if (mesaVersion < new Version(11, 2, 2)) { configuration.UseBufferMapping = false; } } // If we've been explicitly told to disable buffer mapping, override the caps from the driver. if (!configuration.UseBufferMapping) { this.SupportsMapBufferRange = false; } }