[glsl] Inject default gl_PointSize = 1.0 in vertex shaders if FORCE_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>
This commit is contained in:
Artavazd Balaian
2023-02-02 19:08:18 +07:00
committed by GitHub
parent a5c2cf94b8
commit fe851fb008
6 changed files with 94 additions and 16 deletions

View File

@@ -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;
}
}
@@ -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();
@@ -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;
}
}
@@ -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;")?;
}

View File

@@ -0,0 +1,11 @@
(
glsl: (
version: Embedded (
version: 300,
is_webgl: true
),
writer_flags: (bits: 16),
binding_map: {},
zero_initialize_workgroup_memory: true,
),
)

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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() {