1
0
Fork 0
forked from wry/wry

vulkan: rewrite shaders in terms of eotf and oetf

This commit is contained in:
Julian Orth 2025-02-25 14:52:43 +01:00
parent cb9dc4c182
commit b7f93b37a6
8 changed files with 52 additions and 14 deletions

View file

@ -17,6 +17,7 @@ mod shaders;
mod shm_image;
mod staging;
mod transfer;
mod transfer_functions;
use {
crate::{

View file

@ -39,7 +39,8 @@ pub(super) struct PipelineCreateInfo {
pub(super) blend: bool,
pub(super) src_has_alpha: bool,
pub(super) has_alpha_mult: bool,
pub(super) with_linear_output: bool,
pub(super) eotf: u32,
pub(super) oetf: u32,
pub(super) frag_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>,
}
@ -77,8 +78,8 @@ impl VulkanDevice {
};
let destroy_layout =
OnDrop(|| unsafe { self.device.destroy_pipeline_layout(pipeline_layout, None) });
let mut frag_spec_data = ArrayVec::<_, { 3 * 4 }>::new();
let mut frag_spec_entries = ArrayVec::<_, 3>::new();
let mut frag_spec_data = ArrayVec::<_, { 4 * 4 }>::new();
let mut frag_spec_entries = ArrayVec::<_, 4>::new();
let mut frag_spec_entry = |data: &[u8]| {
let entry = SpecializationMapEntry::default()
.constant_id(frag_spec_entries.len() as _)
@ -89,7 +90,8 @@ impl VulkanDevice {
};
frag_spec_entry(&(info.src_has_alpha as u32).to_ne_bytes());
frag_spec_entry(&(info.has_alpha_mult as u32).to_ne_bytes());
frag_spec_entry(&(info.with_linear_output as u32).to_ne_bytes());
frag_spec_entry(&info.eotf.to_ne_bytes());
frag_spec_entry(&info.oetf.to_ne_bytes());
let frag_spec = SpecializationInfo::default()
.map_entries(&frag_spec_entries)
.data(&frag_spec_data);

View file

@ -26,6 +26,7 @@ use {
LEGACY_TEX_FRAG, LEGACY_TEX_VERT, OUT_FRAG, OUT_VERT, OutPushConstants, TEX_FRAG,
TEX_VERT, TexPushConstants, VulkanShader,
},
transfer_functions::{TF_LINEAR, TF_SRGB},
},
io_uring::IoUring,
rect::{Rect, Region},
@ -305,7 +306,10 @@ impl VulkanRenderer {
format: vk::Format,
pass: RenderPass,
) -> Result<Rc<VulkanFormatPipelines>, VulkanError> {
let with_linear_output = pass == RenderPass::BlendBuffer;
let (eotf, oetf) = match pass {
RenderPass::BlendBuffer => (TF_SRGB, TF_LINEAR),
RenderPass::FrameBuffer => (TF_SRGB, TF_SRGB),
};
let pipelines = &self.pipelines[pass];
if let Some(pl) = pipelines.get(&format) {
return Ok(pl);
@ -319,7 +323,8 @@ impl VulkanRenderer {
blend: src_has_alpha,
src_has_alpha,
has_alpha_mult: false,
with_linear_output,
eotf,
oetf,
frag_descriptor_set_layout: None,
})
};
@ -334,7 +339,8 @@ impl VulkanRenderer {
blend: src_has_alpha || has_alpha_mult,
src_has_alpha,
has_alpha_mult,
with_linear_output,
eotf,
oetf,
frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()),
})
};
@ -847,7 +853,8 @@ impl VulkanRenderer {
blend: false,
src_has_alpha: true,
has_alpha_mult: false,
with_linear_output: true,
eotf: TF_LINEAR,
oetf: TF_SRGB,
frag_descriptor_set_layout: Some(layout.clone()),
})?;
e.insert(out.clone());

View file

@ -3,6 +3,7 @@
layout(constant_id = 0) const bool src_has_alpha = false;
layout(constant_id = 1) const bool has_alpha_multiplier = false;
layout(constant_id = 2) const bool color_management = false;
layout(constant_id = 2) const uint eotf = 0;
layout(constant_id = 3) const uint oetf = 0;
#endif

View file

@ -10,8 +10,11 @@ layout(location = 0) out vec4 out_color;
void main() {
vec4 c = texelFetch(in_color, ivec2(gl_FragCoord.xy), 0);
c.rgb /= mix(c.a, 1.0, c.a == 0.0);
c.rgb = oetf_srgb(c.rgb);
c.rgb *= c.a;
if (eotf != oetf) {
c.rgb /= mix(c.a, 1.0, c.a == 0.0);
c.rgb = apply_eotf(c.rgb);
c.rgb = apply_oetf(c.rgb);
c.rgb *= c.a;
}
out_color = c;
}

View file

@ -10,11 +10,12 @@ layout(location = 0) out vec4 out_color;
void main() {
vec4 c = textureLod(tex, tex_pos, 0);
if (color_management) {
if (eotf != oetf) {
if (src_has_alpha) {
c.rgb /= mix(c.a, 1.0, c.a == 0.0);
}
c.rgb = eotf_srgb(c.rgb);
c.rgb = apply_eotf(c.rgb);
c.rgb = apply_oetf(c.rgb);
if (src_has_alpha) {
c.rgb *= c.a;
}

View file

@ -1,6 +1,11 @@
#ifndef TRANSFER_FUNCTIONS_GLSL
#define TRANSFER_FUNCTIONS_GLSL
#include "frag_spec_const.glsl"
#define SRGB 0
#define LINEAR 1
vec3 eotf_srgb(vec3 c) {
return mix(
c * vec3(1.0 / 12.92),
@ -18,4 +23,20 @@ vec3 oetf_srgb(vec3 c) {
);
}
vec3 apply_eotf(vec3 c) {
switch (eotf) {
case SRGB: return eotf_srgb(c);
case LINEAR: return c;
default: return c;
}
}
vec3 apply_oetf(vec3 c) {
switch (oetf) {
case SRGB: return oetf_srgb(c);
case LINEAR: return c;
default: return c;
}
}
#endif

View file

@ -0,0 +1,2 @@
pub const TF_SRGB: u32 = 0;
pub const TF_LINEAR: u32 = 1;