vulkan: rewrite shaders in terms of eotf and oetf
This commit is contained in:
parent
cb9dc4c182
commit
b7f93b37a6
8 changed files with 52 additions and 14 deletions
|
|
@ -17,6 +17,7 @@ mod shaders;
|
|||
mod shm_image;
|
||||
mod staging;
|
||||
mod transfer;
|
||||
mod transfer_functions;
|
||||
|
||||
use {
|
||||
crate::{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
2
src/gfx_apis/vulkan/transfer_functions.rs
Normal file
2
src/gfx_apis/vulkan/transfer_functions.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub const TF_SRGB: u32 = 0;
|
||||
pub const TF_LINEAR: u32 = 1;
|
||||
Loading…
Add table
Add a link
Reference in a new issue