Skip to content

Commit

Permalink
Auto merge of #1286 - ColinKinloch:master, r=kvark
Browse files Browse the repository at this point in the history
Improved GLES capability list

I think these values are correct.
I compared the header at https://www.khronos.org/registry/OpenGL/api/GLES3/gl32.h to the functions listed in the extension specifications at https://www.khronos.org/registry/OpenGL/extensions/ARB/
  • Loading branch information
homu committed Jun 2, 2017
2 parents 75553c0 + 1c00543 commit 190728a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/backend/gl/src/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl f::Factory<R> for Factory {

fn create_sampler(&mut self, info: t::SamplerInfo) -> handle::Sampler<R> {
let name = if self.share.private_caps.sampler_objects_supported {
tex::make_sampler(&self.share.context, &info)
tex::make_sampler(&self.share.context, &info, &self.share.private_caps)
} else {
0
};
Expand Down
88 changes: 68 additions & 20 deletions src/backend/gl/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub struct PrivateCaps {
pub buffer_storage_supported: bool,
pub clear_buffer_supported: bool,
pub frag_data_location_supported: bool,
pub sampler_lod_bias_supported: bool,
}

/// OpenGL implementation information
Expand All @@ -186,6 +187,13 @@ pub struct Info {
pub extensions: HashSet<&'static str>,
}

#[derive(Copy, Clone)]
enum Requirement {
Core(u32,u32),
Es(u32, u32),
Ext(&'static str),
}

impl Info {
fn get(gl: &gl::Gl) -> Info {
let platform_name = PlatformName::get(gl);
Expand Down Expand Up @@ -224,41 +232,81 @@ impl Info {
pub fn is_version_or_extension_supported(&self, major: u32, minor: u32, ext: &'static str) -> bool {
self.is_version_supported(major, minor) || self.is_extension_supported(ext)
}

pub fn is_any_extension_supported(&self, exts: &[&'static str]) -> bool {
exts.iter().any(|e| self.extensions.contains(e))
}

fn is_supported(&self, requirements: &[Requirement]) -> bool {
use self::Requirement::*;
requirements.iter().any(|r| {
match *r {
Core(major, minor) => self.is_version_supported(major, minor),
Es(major, minor) => self.is_embedded_version_supported(major, minor),
Ext(extension) => self.is_extension_supported(extension),
}
})
}
}

/// Load the information pertaining to the driver and the corresponding device
/// capabilities.
pub fn get(gl: &gl::Gl) -> (Info, Capabilities, PrivateCaps) {
use self::Requirement::*;
let info = Info::get(gl);
let tessellation_supported = info.is_version_or_extension_supported(4, 0, "GL_ARB_tessellation_shader");
let tessellation_supported = info.is_supported(&[Core(4,0),
Ext("GL_ARB_tessellation_shader")]);
let caps = Capabilities {
max_vertex_count: get_usize(gl, gl::MAX_ELEMENTS_VERTICES),
max_index_count: get_usize(gl, gl::MAX_ELEMENTS_INDICES),
max_texture_size: get_usize(gl, gl::MAX_TEXTURE_SIZE),
max_patch_size: if tessellation_supported { get_usize(gl, gl::MAX_PATCH_VERTICES) } else {0},

instance_base_supported: info.is_version_or_extension_supported(4, 2, "GL_ARB_base_instance"),
instance_call_supported: info.is_version_or_extension_supported(3, 1, "GL_ARB_draw_instanced"),
instance_rate_supported: info.is_version_or_extension_supported(3, 3, "GL_ARB_instanced_arrays"),
vertex_base_supported: info.is_version_or_extension_supported(3, 2, "GL_ARB_draw_elements_base_vertex"),
srgb_color_supported: info.is_version_or_extension_supported(3, 2, "GL_ARB_framebuffer_sRGB"),
constant_buffer_supported: info.is_version_or_extension_supported(3, 1, "GL_ARB_uniform_buffer_object"),
unordered_access_view_supported: info.is_version_supported(4, 0), //TODO: extension
separate_blending_slots_supported: info.is_version_or_extension_supported(4, 0, "GL_ARB_draw_buffers_blend"),
copy_buffer_supported: info.is_version_or_extension_supported(3, 1, "GL_ARB_copy_buffer") |
info.is_embedded_version_supported(3, 0) |
(info.is_embedded_version_supported(2, 0) & info.is_extension_supported("GL_NV_copy_buffer")),
instance_base_supported: info.is_supported(&[Core(4,2),
Ext ("GL_ARB_base_instance")]),
instance_call_supported: info.is_supported(&[Core(3,1),
Es (3,0),
Ext ("GL_ARB_draw_instanced")]),
instance_rate_supported: info.is_supported(&[Core(3,3),
Es (3,0),
Ext ("GL_ARB_instanced_arrays")]),
vertex_base_supported: info.is_supported(&[Core(3,2),
Es (3,2),
Ext ("GL_ARB_draw_elements_base_vertex")]),
srgb_color_supported: info.is_supported(&[Core(3,2),
Ext ("GL_ARB_framebuffer_sRGB")]),
constant_buffer_supported: info.is_supported(&[Core(3,1),
Es (3,0),
Ext ("GL_ARB_uniform_buffer_object")]),
unordered_access_view_supported: info.is_supported(&[Core(4,0)]), //TODO: extension
separate_blending_slots_supported: info.is_supported(&[Core(4,0),
Es (3,0),
Ext ("GL_ARB_draw_buffers_blend")]),
copy_buffer_supported: info.is_supported(&[Core(3,1),
Es (3,0),
Ext ("GL_ARB_copy_buffer"),
Ext ("GL_NV_copy_buffer")]),
};
let private = PrivateCaps {
array_buffer_supported: info.is_version_or_extension_supported(3, 0, "GL_ARB_vertex_array_object"),
frame_buffer_supported: info.is_version_or_extension_supported(3, 0, "GL_ARB_framebuffer_object") |
info.is_embedded_version_supported(2, 0),
immutable_storage_supported: info.is_version_or_extension_supported(4, 2, "GL_ARB_texture_storage"),
sampler_objects_supported: info.is_version_or_extension_supported(3, 3, "GL_ARB_sampler_objects"),
program_interface_supported: info.is_version_or_extension_supported(4, 3, "GL_ARB_program_interface_query"),
buffer_storage_supported: info.is_version_or_extension_supported(4, 4, "GL_ARB_buffer_storage"),
clear_buffer_supported: info.is_version_supported(3, 0) | info.is_embedded_version_supported(3, 0),
array_buffer_supported: info.is_supported(&[Core(3,0),
Es (3,0),
Ext ("GL_ARB_vertex_array_object")]),
frame_buffer_supported: info.is_supported(&[Core(3,0),
Es (2,0),
Ext ("GL_ARB_framebuffer_object")]),
immutable_storage_supported: info.is_supported(&[Core(3,2),
Ext ("GL_ARB_texture_storage")]),
sampler_objects_supported: info.is_supported(&[Core(3,3),
Es (3,0),
Ext ("GL_ARB_sampler_objects")]),
program_interface_supported: info.is_supported(&[Core(4,3),
Ext ("GL_ARB_program_interface_query")]),
buffer_storage_supported: info.is_supported(&[Core(4,4),
Ext ("GL_ARB_buffer_storage")]),
clear_buffer_supported: info.is_supported(&[Core(3,0),
Es (3,0)]),
frag_data_location_supported: !info.version.is_embedded,
sampler_lod_bias_supported: !info.version.is_embedded,
};
(info, caps, private)
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/gl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ impl Device {
assert!(c::MAX_SAMPLERS <= c::MAX_RESOURCE_VIEWS);
debug_assert_eq!(sampler.object, 0);
if let Some(bind) = bind_opt {
tex::bind_sampler(gl, bind, &sampler.info, self.info.version.is_embedded);
tex::bind_sampler(gl, bind, &sampler.info, &self.share.private_caps);
}else {
error!("Trying to bind a sampler to slot {}, when sampler objects are not supported, and no texture is bound there", slot);
}
Expand Down
15 changes: 9 additions & 6 deletions src/backend/gl/src/tex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use {gl, Surface, Texture, NewTexture, Buffer, Sampler};
use gl::types::{GLenum, GLuint, GLint, GLfloat, GLsizei, GLvoid};
use state;
use info::PrivateCaps;
use core::memory::SHADER_RESOURCE;
use core::format::{Format as NewFormat, ChannelType};
use core::texture as t;
Expand Down Expand Up @@ -539,7 +540,7 @@ pub fn make_with_storage(gl: &gl::Gl, desc: &t::Info, cty: ChannelType) ->

/// Bind a sampler using a given binding anchor.
/// Used for GL compatibility profile only. The core profile has sampler objects
pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo, is_embedded: bool) { unsafe {
pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo, private_caps: &PrivateCaps) { unsafe {
let (min, mag) = filter_to_gl(info.filter);

match info.filter {
Expand All @@ -556,11 +557,11 @@ pub fn bind_sampler(gl: &gl::Gl, target: GLenum, info: &t::SamplerInfo, is_embed
gl.TexParameteri(target, gl::TEXTURE_WRAP_T, wrap_to_gl(t) as GLint);
gl.TexParameteri(target, gl::TEXTURE_WRAP_R, wrap_to_gl(r) as GLint);

if !is_embedded {
let border: [f32; 4] = info.border.into();
gl.TexParameterfv(target, gl::TEXTURE_BORDER_COLOR, &border[0]);
if private_caps.sampler_lod_bias_supported {
gl.TexParameterf(target, gl::TEXTURE_LOD_BIAS, info.lod_bias.into());
}
let border: [f32; 4] = info.border.into();
gl.TexParameterfv(target, gl::TEXTURE_BORDER_COLOR, &border[0]);

let (min, max) = info.lod_range;
gl.TexParameterf(target, gl::TEXTURE_MIN_LOD, min.into());
Expand Down Expand Up @@ -899,7 +900,7 @@ fn filter_to_gl(f: t::FilterMethod) -> (GLenum, GLenum) {
}
}

pub fn make_sampler(gl: &gl::Gl, info: &t::SamplerInfo) -> Sampler { unsafe {
pub fn make_sampler(gl: &gl::Gl, info: &t::SamplerInfo, private_caps: &PrivateCaps) -> Sampler { unsafe {
let mut name = 0 as Sampler;
gl.GenSamplers(1, &mut name);

Expand All @@ -919,7 +920,9 @@ pub fn make_sampler(gl: &gl::Gl, info: &t::SamplerInfo) -> Sampler { unsafe {
gl.SamplerParameteri(name, gl::TEXTURE_WRAP_T, wrap_to_gl(t) as GLint);
gl.SamplerParameteri(name, gl::TEXTURE_WRAP_R, wrap_to_gl(r) as GLint);

gl.SamplerParameterf(name, gl::TEXTURE_LOD_BIAS, info.lod_bias.into());
if private_caps.sampler_lod_bias_supported {
gl.SamplerParameterf(name, gl::TEXTURE_LOD_BIAS, info.lod_bias.into());
}
let border: [f32; 4] = info.border.into();
gl.SamplerParameterfv(name, gl::TEXTURE_BORDER_COLOR, &border[0]);

Expand Down

0 comments on commit 190728a

Please sign in to comment.