mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[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:
@@ -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;")?;
|
||||
}
|
||||
|
||||
11
tests/in/force_point_size_vertex_shader_webgl.param.ron
Normal file
11
tests/in/force_point_size_vertex_shader_webgl.param.ron
Normal file
@@ -0,0 +1,11 @@
|
||||
(
|
||||
glsl: (
|
||||
version: Embedded (
|
||||
version: 300,
|
||||
is_webgl: true
|
||||
),
|
||||
writer_flags: (bits: 16),
|
||||
binding_map: {},
|
||||
zero_initialize_workgroup_memory: true,
|
||||
),
|
||||
)
|
||||
14
tests/in/force_point_size_vertex_shader_webgl.wgsl
Normal file
14
tests/in/force_point_size_vertex_shader_webgl.wgsl
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user