Skip to content

Commit

Permalink
[spv-out] option to clamp frag_depth
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Sep 27, 2021
1 parent aa08cf9 commit 1153bc6
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 40 deletions.
119 changes: 85 additions & 34 deletions src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,85 @@ fn get_dimension(type_inner: &crate::TypeInner) -> Dimension {
}

impl Writer {
// Flip Y coordinate to adjust for coordinate space difference
// between SPIR-V and our IR.
fn write_epilogue_position_y_flip(
&mut self,
position_id: Word,
body: &mut Vec<Instruction>,
) -> Result<(), Error> {
let access_id = self.id_gen.next();
let float_ptr_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width: 4,
pointer_class: Some(spirv::StorageClass::Output),
}));
let index_y_id = self.get_index_constant(1);
body.push(Instruction::access_chain(
float_ptr_type_id,
access_id,
position_id,
&[index_y_id],
));

let load_id = self.id_gen.next();
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width: 4,
pointer_class: None,
}));
body.push(Instruction::load(float_type_id, load_id, access_id, None));

let neg_id = self.id_gen.next();
body.push(Instruction::unary(
spirv::Op::FNegate,
float_type_id,
neg_id,
load_id,
));

body.push(Instruction::store(access_id, neg_id, None));
Ok(())
}

// Clamp fragment depth between 0 and 1.
fn write_epilogue_frag_depth_clamp(
&mut self,
frag_depth_id: Word,
body: &mut Vec<Instruction>,
) -> Result<(), Error> {
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width: 4,
pointer_class: None,
}));
let value0_id = self.get_constant_scalar(crate::ScalarValue::Float(0.0), 4);
let value1_id = self.get_constant_scalar(crate::ScalarValue::Float(1.0), 4);

let original_id = self.id_gen.next();
body.push(Instruction::load(
float_type_id,
original_id,
frag_depth_id,
None,
));

let clamp_id = self.id_gen.next();
body.push(Instruction::ext_inst(
self.gl450_ext_inst_id,
spirv::GLOp::FClamp,
float_type_id,
clamp_id,
&[original_id, value0_id, value1_id],
));

body.push(Instruction::store(frag_depth_id, clamp_id, None));
Ok(())
}

fn write_entry_point_return(
&mut self,
value_id: Word,
Expand All @@ -44,43 +123,15 @@ impl Writer {

body.push(Instruction::store(res_member.id, member_value_id, None));

// Flip Y coordinate to adjust for coordinate space difference
// between SPIR-V and our IR.
if self.flags.contains(WriterFlags::ADJUST_COORDINATE_SPACE)
&& res_member.built_in == Some(crate::BuiltIn::Position)
{
let access_id = self.id_gen.next();
let float_ptr_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width: 4,
pointer_class: Some(spirv::StorageClass::Output),
}));
let index_y_id = self.get_index_constant(1);
body.push(Instruction::access_chain(
float_ptr_type_id,
access_id,
res_member.id,
&[index_y_id],
));

let load_id = self.id_gen.next();
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
vector_size: None,
kind: crate::ScalarKind::Float,
width: 4,
pointer_class: None,
}));
body.push(Instruction::load(float_type_id, load_id, access_id, None));

let neg_id = self.id_gen.next();
body.push(Instruction::unary(
spirv::Op::FNegate,
float_type_id,
neg_id,
load_id,
));
body.push(Instruction::store(access_id, neg_id, None));
self.write_epilogue_position_y_flip(res_member.id, body)?;
}
if self.flags.contains(WriterFlags::CLAMP_FRAG_DEPTH)
&& res_member.built_in == Some(crate::BuiltIn::FragDepth)
{
self.write_epilogue_frag_depth_clamp(res_member.id, body)?;
}
}
Ok(())
Expand Down
6 changes: 5 additions & 1 deletion src/back/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,8 @@ bitflags::bitflags! {
/// Emit `PointSize` output builtin to vertex shaders, which is
/// required for drawing with `PointList` topology.
const FORCE_POINT_SIZE = 0x8;
/// Clamp `BuiltIn::FragDepth` output between 0 and 1.
const CLAMP_FRAG_DEPTH = 0x10;
}
}

Expand All @@ -592,7 +594,9 @@ pub struct Options {

impl Default for Options {
fn default() -> Self {
let mut flags = WriterFlags::ADJUST_COORDINATE_SPACE | WriterFlags::LABEL_VARYINGS;
let mut flags = WriterFlags::ADJUST_COORDINATE_SPACE
| WriterFlags::LABEL_VARYINGS
| WriterFlags::CLAMP_FRAG_DEPTH;
if cfg!(debug_assertions) {
flags |= WriterFlags::DEBUG;
}
Expand Down
1 change: 1 addition & 0 deletions tests/in/interface.param.ron
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
capabilities: [ Shader, SampleRateShading ],
adjust_coordinate_space: false,
force_point_size: true,
clamp_frag_depth: true,
separate_entry_points: true,
),
hlsl_custom: true,
Expand Down
13 changes: 8 additions & 5 deletions tests/out/spv/interface.fragment.spvasm
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.0
; Generator: rspirv
; Bound: 49
; Bound: 51
OpCapability Shader
OpCapability SampleRateShading
%1 = OpExtInstImport "GLSL.std.450"
Expand Down Expand Up @@ -70,9 +70,12 @@ OpBranch %40
%45 = OpCompositeConstruct %13 %44 %42 %43
%46 = OpCompositeExtract %4 %45 0
OpStore %33 %46
%47 = OpCompositeExtract %6 %45 1
OpStore %35 %47
%48 = OpCompositeExtract %4 %45 2
OpStore %37 %48
%47 = OpLoad %4 %33
%48 = OpExtInst %4 %1 FClamp %47 %7 %3
OpStore %33 %48
%49 = OpCompositeExtract %6 %45 1
OpStore %35 %49
%50 = OpCompositeExtract %4 %45 2
OpStore %37 %50
OpReturn
OpFunctionEnd
6 changes: 6 additions & 0 deletions tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ struct SpirvOutParameters {
#[serde(default)]
force_point_size: bool,
#[serde(default)]
clamp_frag_depth: bool,
#[serde(default)]
separate_entry_points: bool,
}

Expand Down Expand Up @@ -201,6 +203,10 @@ fn write_output_spv(
spv::WriterFlags::FORCE_POINT_SIZE,
params.spv.force_point_size,
);
flags.set(
spv::WriterFlags::CLAMP_FRAG_DEPTH,
params.spv.clamp_frag_depth,
);
let options = spv::Options {
lang_version: (params.spv.version.0, params.spv.version.1),
flags,
Expand Down

0 comments on commit 1153bc6

Please sign in to comment.