[glsl-out] Support extended shadow sampling instructions, and the offset

This commit is contained in:
Dzmitry Malyshau 2021-06-28 12:38:11 -04:00
parent cfbe83e384
commit e8b71b8dc5
2 changed files with 41 additions and 10 deletions

View File

@ -132,6 +132,9 @@ bitflags::bitflags! {
pub struct WriterFlags: u32 { pub struct WriterFlags: u32 {
/// Extend output Z from (0,1) to (-1,1). /// Extend output Z from (0,1) to (-1,1).
const ADJUST_COORDINATE_SPACE = 0x1; const ADJUST_COORDINATE_SPACE = 0x1;
/// Supports GL_EXT_texture_shadow_lod on the host, which provides
/// additional functions on shadows and arrays of shadows.
const TEXTURE_SHADOW_LOD = 0x2;
} }
} }
@ -391,6 +394,16 @@ impl<'a, W: Write> Writer<'a, W> {
// preprocessor not the processor ¯\_(ツ)_/¯ // preprocessor not the processor ¯\_(ツ)_/¯
self.features.write(self.options.version, &mut self.out)?; self.features.write(self.options.version, &mut self.out)?;
// Write the additional extensions
if self
.options
.writer_flags
.contains(WriterFlags::TEXTURE_SHADOW_LOD)
{
// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_shadow_lod.txt
writeln!(self.out, "#extension GL_EXT_texture_shadow_lod : require")?;
}
// glsl es requires a precision to be specified for floats // glsl es requires a precision to be specified for floats
// TODO: Should this be user configurable? // TODO: Should this be user configurable?
if es { if es {
@ -1677,19 +1690,27 @@ impl<'a, W: Write> Writer<'a, W> {
// Furthermore if `depth_ref` is some we need to append it to the coordinate vector // Furthermore if `depth_ref` is some we need to append it to the coordinate vector
Expression::ImageSample { Expression::ImageSample {
image, image,
sampler: _, //TODO sampler: _, //TODO?
coordinate, coordinate,
array_index, array_index,
offset: _, //TODO offset,
level, level,
depth_ref, depth_ref,
} => { } => {
//TODO: handle MS let dim = match *ctx.info[image].ty.inner_with(&self.module.types) {
TypeInner::Image { dim, .. } => dim,
_ => unreachable!(),
};
// textureLod on sampler2DArrayShadow and samplerCubeShadow does not exist in GLSL. // textureLod on sampler2DArrayShadow and samplerCubeShadow does not exist in GLSL.
// To emulate this, we will have to use textureGrad with a constant gradient of 0. // To emulate this, we will have to use textureGrad with a constant gradient of 0.
let workaround_lod_array_shadow_as_grad = let workaround_lod_array_shadow_as_grad = (array_index.is_some()
array_index.is_some() && depth_ref.is_some(); || dim == crate::ImageDimension::Cube)
&& depth_ref.is_some()
&& !self
.options
.writer_flags
.contains(WriterFlags::TEXTURE_SHADOW_LOD);
//Write the function to be used depending on the sample level //Write the function to be used depending on the sample level
let fun_name = match level { let fun_name = match level {
@ -1703,8 +1724,12 @@ impl<'a, W: Write> Writer<'a, W> {
} }
crate::SampleLevel::Gradient { .. } => "textureGrad", crate::SampleLevel::Gradient { .. } => "textureGrad",
}; };
let offset_name = match offset {
Some(_) => "Offset",
None => "",
};
write!(self.out, "{}(", fun_name)?; write!(self.out, "{}{}(", fun_name, offset_name)?;
// Write the image that will be used // Write the image that will be used
self.write_expr(image, ctx)?; self.write_expr(image, ctx)?;
@ -1745,15 +1770,16 @@ impl<'a, W: Write> Writer<'a, W> {
// Zero needs level set to 0 // Zero needs level set to 0
crate::SampleLevel::Zero => { crate::SampleLevel::Zero => {
if workaround_lod_array_shadow_as_grad { if workaround_lod_array_shadow_as_grad {
write!(self.out, ", vec2(0, 0), vec2(0,0)")?; write!(self.out, ", vec2(0,0), vec2(0,0)")?;
} else { } else {
write!(self.out, ", 0")?; write!(self.out, ", 0.0")?;
} }
} }
// Exact and bias require another argument // Exact and bias require another argument
crate::SampleLevel::Exact(expr) => { crate::SampleLevel::Exact(expr) => {
if workaround_lod_array_shadow_as_grad { if workaround_lod_array_shadow_as_grad {
write!(self.out, ", vec2(0, 0), vec2(0,0)")?; log::warn!("Unable to `textureLod` a shadow array, ignoring the LOD");
write!(self.out, ", vec2(0,0), vec2(0,0)")?;
} else { } else {
write!(self.out, ", ")?; write!(self.out, ", ")?;
self.write_expr(expr, ctx)?; self.write_expr(expr, ctx)?;
@ -1771,6 +1797,11 @@ impl<'a, W: Write> Writer<'a, W> {
} }
} }
if let Some(constant) = offset {
write!(self.out, ", ")?;
self.write_constant(&self.module.constants[constant])?;
}
// End the function // End the function
write!(self.out, ")")? write!(self.out, ")")?
} }

View File

@ -28,7 +28,7 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) {
} }
vec2 flip_correction = vec2(0.5, -0.5); vec2 flip_correction = vec2(0.5, -0.5);
vec2 light_local = (((homogeneous_coords.xy * flip_correction) / vec2(homogeneous_coords.w)) + vec2(0.5, 0.5)); vec2 light_local = (((homogeneous_coords.xy * flip_correction) / vec2(homogeneous_coords.w)) + vec2(0.5, 0.5));
float _expr26 = textureGrad(_group_0_binding_2, vec4(light_local, int(light_id), (homogeneous_coords.z / homogeneous_coords.w)), vec2(0, 0), vec2(0,0)); float _expr26 = textureGrad(_group_0_binding_2, vec4(light_local, int(light_id), (homogeneous_coords.z / homogeneous_coords.w)), vec2(0,0), vec2(0,0));
return _expr26; return _expr26;
} }