Skip to content

Commit

Permalink
[glsl] Inject default gl_PointSize = 1.0 in vertex shaders if `FORC…
Browse files Browse the repository at this point in the history
…E_POINT_SIZE` option was set (#2223)

According to https://registry.khronos.org/OpenGL/specs/es/3.2/GLSL_ES_Specification_3.20.html#built-in-language-variables

> The variable gl_PointSize is intended for a shader to write the size of the point to be rasterized. It is measured in pixels. If gl_PointSize is not written to, its value is undefined in subsequent pipe stages.

- Write warn message if `ClipDistance` and `CullDistance` are used on unsupported version

---------

Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com>
  • Loading branch information
REASY and teoxoy authored Feb 2, 2023
1 parent a5c2cf9 commit fe851fb
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 16 deletions.
57 changes: 41 additions & 16 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ bitflags::bitflags! {
/// global variables that are not used in the specified entrypoint (including indirect use),
/// all constant declarations, and functions that use excluded global variables.
const INCLUDE_UNUSED_ITEMS = 0x4;
/// Emit `PointSize` output builtin to vertex shaders, which is
/// required for drawing with `PointList` topology.
///
/// https://registry.khronos.org/OpenGL/specs/es/3.2/GLSL_ES_Specification_3.20.html#built-in-language-variables
/// The variable gl_PointSize is intended for a shader to write the size of the point to be rasterized. It is measured in pixels.
/// If gl_PointSize is not written to, its value is undefined in subsequent pipe stages.
const FORCE_POINT_SIZE = 0x10;
}
}

Expand Down Expand Up @@ -1978,6 +1985,7 @@ impl<'a, W: Write> Writer<'a, W> {
writeln!(self.out, ";")?;
}
back::FunctionType::EntryPoint(ep_index) => {
let mut has_point_size = false;
let ep = &self.module.entry_points[ep_index as usize];
if let Some(ref result) = ep.function.result {
let value = value.unwrap();
Expand Down Expand Up @@ -2005,11 +2013,18 @@ impl<'a, W: Write> Writer<'a, W> {
if let Some(crate::Binding::BuiltIn(builtin)) =
member.binding
{
has_point_size |= builtin == crate::BuiltIn::PointSize;

match builtin {
crate::BuiltIn::ClipDistance
| crate::BuiltIn::CullDistance
| crate::BuiltIn::PointSize => {
| crate::BuiltIn::CullDistance => {
if self.options.version.is_es() {
// Note that gl_ClipDistance and gl_CullDistance are listed in the GLSL ES 3.2 spec but shouldn't
// See https://github.com/KhronosGroup/GLSL/issues/132#issuecomment-685818465
log::warn!(
"{:?} is not part of GLSL ES",
builtin
);
continue;
}
}
Expand Down Expand Up @@ -2056,20 +2071,30 @@ impl<'a, W: Write> Writer<'a, W> {
}
}

if let back::FunctionType::EntryPoint(ep_index) = ctx.ty {
if self.module.entry_points[ep_index as usize].stage
== crate::ShaderStage::Vertex
&& self
.options
.writer_flags
.contains(WriterFlags::ADJUST_COORDINATE_SPACE)
{
writeln!(
self.out,
"gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w);",
)?;
write!(self.out, "{level}")?;
}
let is_vertex_stage = self.module.entry_points[ep_index as usize].stage
== ShaderStage::Vertex;
if is_vertex_stage
&& self
.options
.writer_flags
.contains(WriterFlags::ADJUST_COORDINATE_SPACE)
{
writeln!(
self.out,
"gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w);",
)?;
write!(self.out, "{level}")?;
}

if is_vertex_stage
&& self
.options
.writer_flags
.contains(WriterFlags::FORCE_POINT_SIZE)
&& !has_point_size
{
writeln!(self.out, "gl_PointSize = 1.0;")?;
write!(self.out, "{level}")?;
}
writeln!(self.out, "return;")?;
}
Expand Down
11 changes: 11 additions & 0 deletions tests/in/force_point_size_vertex_shader_webgl.param.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(
glsl: (
version: Embedded (
version: 300,
is_webgl: true
),
writer_flags: (bits: 16),
binding_map: {},
zero_initialize_workgroup_memory: true,
),
)
14 changes: 14 additions & 0 deletions tests/in/force_point_size_vertex_shader_webgl.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// AUTHOR: REASY
// ISSUE: https://github.com/gfx-rs/wgpu/issues/3179
// FIX: https://github.com/gfx-rs/wgpu/pull/3440
@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
let x = f32(i32(in_vertex_index) - 1);
let y = f32(i32(in_vertex_index & 1u) * 2 - 1);
return vec4<f32>(x, y, 0.0, 1.0);
}

@fragment
fn fs_main() -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 300 es

precision highp float;
precision highp int;

layout(location = 0) out vec4 _fs2p_location0;

void main() {
_fs2p_location0 = vec4(1.0, 0.0, 0.0, 1.0);
return;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 300 es

precision highp float;
precision highp int;


void main() {
uint in_vertex_index = uint(gl_VertexID);
float x = float((int(in_vertex_index) - 1));
float y = float(((int((in_vertex_index & 1u)) * 2) - 1));
gl_Position = vec4(x, y, 0.0, 1.0);
gl_PointSize = 1.0;
return;
}

1 change: 1 addition & 0 deletions tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ fn convert_wgsl() {
Targets::WGSL | Targets::GLSL | Targets::SPIRV | Targets::HLSL | Targets::METAL,
),
("sprite", Targets::SPIRV),
("force_point_size_vertex_shader_webgl", Targets::GLSL),
];

for &(name, targets) in inputs.iter() {
Expand Down

0 comments on commit fe851fb

Please sign in to comment.