Skip to content

Commit

Permalink
Merge pull request servo#319 from pcwalton/gl4
Browse files Browse the repository at this point in the history
Add OpenGL 4.3 support to the GL backend, enabling compute shader on non-Metal platforms
  • Loading branch information
pcwalton committed May 8, 2020
2 parents cfc1d44 + 520817e commit 371c853
Show file tree
Hide file tree
Showing 25 changed files with 1,414 additions and 29 deletions.
7 changes: 6 additions & 1 deletion demo/native/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ enum CustomEvent {
}

impl Window for WindowImpl {
#[cfg(any(not(target_os = "macos"), feature = "pf-gl"))]
#[cfg(not(target_os = "macos"))]
fn gl_version(&self) -> GLVersion {
GLVersion::GL4
}

#[cfg(all(target_os = "macos", feature = "pf-gl"))]
fn gl_version(&self) -> GLVersion {
GLVersion::GL3
}
Expand Down
70 changes: 48 additions & 22 deletions gl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ use gl::types::{GLuint, GLvoid};
use half::f16;
use pathfinder_geometry::rect::RectI;
use pathfinder_geometry::vector::Vector2I;
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps, ComputeDimensions, ComputeState};
use pathfinder_gpu::{DepthFunc, Device, ImageAccess, ImageBinding, Primitive, ProgramKind, RenderOptions, RenderState, RenderTarget};
use pathfinder_gpu::{ShaderKind, StencilFunc, TextureData, TextureDataRef, TextureFormat};
use pathfinder_gpu::{TextureSamplingFlags, UniformData, VertexAttrClass};
use pathfinder_gpu::{BlendFactor, BlendOp, BufferData, BufferTarget, BufferUploadMode, ClearOps};
use pathfinder_gpu::{ComputeDimensions, ComputeState, DepthFunc, Device, ImageAccess};
use pathfinder_gpu::{ImageBinding, Primitive, ProgramKind, RenderOptions, RenderState};
use pathfinder_gpu::{RenderTarget, ShaderKind, StencilFunc, TextureData, TextureDataRef};
use pathfinder_gpu::{TextureFormat, TextureSamplingFlags, UniformData, VertexAttrClass};
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
use pathfinder_resources::ResourceLoader;
use pathfinder_simd::default::F32x4;
Expand Down Expand Up @@ -68,6 +69,7 @@ impl GLDevice {
}

render_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data));

self.set_render_options(&render_state.options);
}

Expand All @@ -81,6 +83,10 @@ impl GLDevice {
}

compute_state.uniforms.iter().for_each(|(uniform, data)| self.set_uniform(uniform, data));

for &(storage_buffer, buffer) in compute_state.storage_buffers {
self.set_storage_buffer(storage_buffer, buffer);
}
}

fn set_render_options(&self, render_options: &RenderOptions) {
Expand Down Expand Up @@ -196,6 +202,20 @@ impl GLDevice {
}
}

fn set_storage_buffer(&self, storage_buffer: &GLStorageBuffer, buffer: &GLBuffer) {
unsafe {
gl::BindBufferBase(gl::SHADER_STORAGE_BUFFER,
storage_buffer.location as GLuint,
buffer.gl_buffer);
}
}

fn unset_storage_buffer(&self, storage_buffer: &GLStorageBuffer) {
unsafe {
gl::BindBufferBase(gl::SHADER_STORAGE_BUFFER, storage_buffer.location as GLuint, 0);
}
}

fn reset_render_state(&self, render_state: &RenderState<GLDevice>) {
self.reset_render_options(&render_state.options);
for texture_unit in 0..(render_state.textures.len() as u32) {
Expand All @@ -207,6 +227,9 @@ impl GLDevice {
}

fn reset_compute_state(&self, compute_state: &ComputeState<GLDevice>) {
for &(storage_buffer, _) in compute_state.storage_buffers {
self.unset_storage_buffer(storage_buffer);
}
for image_unit in 0..(compute_state.images.len() as u32) {
self.unbind_image(image_unit);
}
Expand Down Expand Up @@ -372,12 +395,7 @@ impl Device for GLDevice {
}
}

match shaders {
ProgramKind::Raster { vertex: vertex_shader, fragment: fragment_shader } => {
GLProgram { gl_program, vertex_shader, fragment_shader }
}
ProgramKind::Compute(_) => unimplemented!(),
}
GLProgram { gl_program, shaders }
}

#[inline]
Expand Down Expand Up @@ -774,18 +792,28 @@ impl Device for GLDevice {
}

#[inline]
fn create_shader(
&self,
resources: &dyn ResourceLoader,
name: &str,
kind: ShaderKind,
) -> Self::Shader {
fn create_shader(&self, resources: &dyn ResourceLoader, name: &str, kind: ShaderKind)
-> Self::Shader {
match (self.version, kind) {
(GLVersion::GL3, ShaderKind::Compute) | (GLVersion::GLES3, ShaderKind::Compute) => {
panic!("Compute shaders are not supported on OpenGL versions prior to 4!")
}
(GLVersion::GL3, ShaderKind::Vertex) |
(GLVersion::GL3, ShaderKind::Fragment) |
(GLVersion::GLES3, ShaderKind::Vertex) |
(GLVersion::GLES3, ShaderKind::Fragment) |
(GLVersion::GL4, _) => {}
}
let directory = match self.version {
GLVersion::GL3 | GLVersion::GLES3 => "gl3",
GLVersion::GL4 => "gl4",
};
let suffix = match kind {
ShaderKind::Vertex => 'v',
ShaderKind::Fragment => 'f',
ShaderKind::Compute => 'c',
};
let path = format!("shaders/gl3/{}.{}s.glsl", name, suffix);
let path = format!("shaders/{}/{}.{}s.glsl", directory, name, suffix);
self.create_shader_from_source(name, &resources.slurp(&path).unwrap(), kind)
}

Expand Down Expand Up @@ -1087,9 +1115,7 @@ pub struct GLStorageBuffer {
pub struct GLProgram {
pub gl_program: GLuint,
#[allow(dead_code)]
vertex_shader: GLShader,
#[allow(dead_code)]
fragment_shader: GLShader,
shaders: ProgramKind<GLShader>,
}

impl Drop for GLProgram {
Expand Down Expand Up @@ -1329,15 +1355,15 @@ pub enum GLVersion {
/// OpenGL ES 3.0+.
GLES3 = 1,
/// OpenGL 4.3+, core profile.
GL4_3 = 2,
GL4 = 2,
}

impl GLVersion {
fn to_glsl_version_spec(&self) -> &'static str {
match *self {
GLVersion::GL3 => "330",
GLVersion::GLES3 => "300 es",
GLVersion::GL4_3 => "430",
GLVersion::GL4 => "430",
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions resources/shaders/gl4/blit.fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform sampler2D uSrc;

in vec2 vTexCoord;

out vec4 oFragColor;

void main(){
vec4 color = texture(uSrc, vTexCoord);
oFragColor = vec4(color . rgb * color . a, color . a);
}

30 changes: 30 additions & 0 deletions resources/shaders/gl4/blit.vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

in ivec2 aPosition;

out vec2 vTexCoord;

void main(){
vec2 texCoord = vec2(aPosition);



vTexCoord = texCoord;
gl_Position = vec4(mix(vec2(- 1.0), vec2(1.0), vec2(aPosition)), 0.0, 1.0);
}

25 changes: 25 additions & 0 deletions resources/shaders/gl4/debug_solid.fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform vec4 uColor;

out vec4 oFragColor;

void main(){
oFragColor = vec4(uColor . rgb, 1.0)* uColor . a;
}

26 changes: 26 additions & 0 deletions resources/shaders/gl4/debug_solid.vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform vec2 uFramebufferSize;

in ivec2 aPosition;

void main(){
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
}

29 changes: 29 additions & 0 deletions resources/shaders/gl4/debug_texture.fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform sampler2D uTexture;
uniform vec4 uColor;

in vec2 vTexCoord;

out vec4 oFragColor;

void main(){
float alpha = texture(uTexture, vTexCoord). r * uColor . a;
oFragColor = alpha * vec4(uColor . rgb, 1.0);
}

31 changes: 31 additions & 0 deletions resources/shaders/gl4/debug_texture.vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform vec2 uFramebufferSize;
uniform vec2 uTextureSize;

in ivec2 aPosition;
in ivec2 aTexCoord;

out vec2 vTexCoord;

void main(){
vTexCoord = vec2(aTexCoord)/ uTextureSize;
vec2 position = vec2(aPosition)/ uFramebufferSize * 2.0 - 1.0;
gl_Position = vec4(position . x, - position . y, 0.0, 1.0);
}

29 changes: 29 additions & 0 deletions resources/shaders/gl4/demo_ground.fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform vec4 uGroundColor;
uniform vec4 uGridlineColor;

in vec2 vTexCoord;

out vec4 oFragColor;

void main(){
vec2 texCoordPx = fract(vTexCoord)/ fwidth(vTexCoord);
oFragColor = any(lessThanEqual(texCoordPx, vec2(1.0)))? uGridlineColor : uGroundColor;
}

29 changes: 29 additions & 0 deletions resources/shaders/gl4/demo_ground.vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#version {{version}}
// Automatically generated from files in pathfinder/shaders/. Do not edit!












precision highp float;
precision highp sampler2D;

uniform mat4 uTransform;
uniform int uGridlineCount;

in ivec2 aPosition;

out vec2 vTexCoord;

void main(){
vTexCoord = vec2(aPosition * uGridlineCount);
gl_Position = uTransform * vec4(ivec4(aPosition . x, 0, aPosition . y, 1));
}

Loading

0 comments on commit 371c853

Please sign in to comment.