color-management: parametrize bt1886
This commit is contained in:
parent
c37567f1cd
commit
ef1727a186
8 changed files with 189 additions and 85 deletions
|
|
@ -2,7 +2,7 @@ use {crate::cmm::cmm_eotf::Eotf, linearize::Linearize};
|
|||
|
||||
pub const EOTF_LINEAR: u32 = 1;
|
||||
pub const EOTF_ST2084_PQ: u32 = 2;
|
||||
pub const EOTF_GAMMA24: u32 = 3;
|
||||
pub const EOTF_BT1886: u32 = 3;
|
||||
pub const EOTF_GAMMA22: u32 = 4;
|
||||
pub const EOTF_GAMMA28: u32 = 5;
|
||||
pub const EOTF_ST240: u32 = 6;
|
||||
|
|
@ -10,6 +10,7 @@ pub const EOTF_LOG100: u32 = 8;
|
|||
pub const EOTF_LOG316: u32 = 9;
|
||||
pub const EOTF_ST428: u32 = 10;
|
||||
pub const EOTF_POW: u32 = 11;
|
||||
pub const EOTF_GAMMA24: u32 = 12;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Linearize)]
|
||||
pub enum VulkanEotf {
|
||||
|
|
@ -17,6 +18,7 @@ pub enum VulkanEotf {
|
|||
St2084Pq,
|
||||
Bt1886,
|
||||
Gamma22,
|
||||
Gamma24,
|
||||
Gamma28,
|
||||
St240,
|
||||
Log100,
|
||||
|
|
@ -45,6 +47,7 @@ impl EotfExt for Eotf {
|
|||
St2084Pq,
|
||||
Bt1886,
|
||||
Gamma22,
|
||||
Gamma24,
|
||||
Gamma28,
|
||||
St240,
|
||||
Log100,
|
||||
|
|
@ -60,8 +63,9 @@ impl VulkanEotf {
|
|||
match self {
|
||||
Self::Linear => EOTF_LINEAR,
|
||||
Self::St2084Pq => EOTF_ST2084_PQ,
|
||||
Self::Bt1886 => EOTF_GAMMA24,
|
||||
Self::Bt1886 => EOTF_BT1886,
|
||||
Self::Gamma22 => EOTF_GAMMA22,
|
||||
Self::Gamma24 => EOTF_GAMMA24,
|
||||
Self::Gamma28 => EOTF_GAMMA28,
|
||||
Self::St240 => EOTF_ST240,
|
||||
Self::Log100 => EOTF_LOG100,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use {
|
|||
async_engine::{AsyncEngine, SpawnedFuture},
|
||||
cmm::{
|
||||
cmm_description::{ColorDescription, LinearColorDescription, LinearColorDescriptionId},
|
||||
cmm_eotf::{Eotf, EotfPow},
|
||||
cmm_eotf::{Eotf, EotfPow, bt1886_eotf_args, bt1886_inv_eotf_args},
|
||||
cmm_transform::ColorMatrix,
|
||||
},
|
||||
cpu_worker::PendingJob,
|
||||
|
|
@ -35,7 +35,10 @@ use {
|
|||
io_uring::IoUring,
|
||||
rect::{Rect, Region},
|
||||
theme::Color,
|
||||
utils::{copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, stack::Stack},
|
||||
utils::{
|
||||
copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, ordered_float::F32,
|
||||
stack::Stack,
|
||||
},
|
||||
video::dmabuf::{DMA_BUF_SYNC_READ, DMA_BUF_SYNC_WRITE, dma_buf_export_sync_file},
|
||||
},
|
||||
ahash::AHashMap,
|
||||
|
|
@ -2328,7 +2331,13 @@ impl ColorTransforms {
|
|||
|
||||
#[derive(Default)]
|
||||
struct EotfArgsCache {
|
||||
map: AHashMap<(EotfPow, bool), EotfArg>,
|
||||
map: AHashMap<(EotfCacheKey, bool), EotfArg>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
enum EotfCacheKey {
|
||||
Pow(EotfPow),
|
||||
Bt1886(F32),
|
||||
}
|
||||
|
||||
struct EotfArg {
|
||||
|
|
@ -2343,27 +2352,43 @@ impl EotfArgsCache {
|
|||
uniform_buffer_offset_mask: DeviceSize,
|
||||
writer: &mut GenericBufferWriter,
|
||||
) -> Option<DeviceSize> {
|
||||
let Eotf::Pow(pow) = desc.eotf else {
|
||||
return None;
|
||||
let key = match desc.eotf {
|
||||
Eotf::Bt1886(c) => EotfCacheKey::Bt1886(c),
|
||||
Eotf::Pow(pow) => EotfCacheKey::Pow(pow),
|
||||
_ => return None,
|
||||
};
|
||||
let ct = match self.map.entry((pow, inv)) {
|
||||
let ct = match self.map.entry((key, inv)) {
|
||||
Entry::Occupied(o) => o.into_mut(),
|
||||
Entry::Vacant(e) => {
|
||||
#[expect(unused_assignments)]
|
||||
let [mut arg1, mut arg2, mut arg3, mut arg4] = [0.0; 4];
|
||||
if inv {
|
||||
match key {
|
||||
EotfCacheKey::Pow(pow) => arg1 = pow.inv_eotf_f32(),
|
||||
EotfCacheKey::Bt1886(c) => {
|
||||
[arg1, arg2, arg3, arg4] = bt1886_inv_eotf_args(c);
|
||||
}
|
||||
}
|
||||
let data = InvEotfArgs {
|
||||
arg1: pow.inv_eotf_f32(),
|
||||
arg2: 0.0,
|
||||
arg3: 0.0,
|
||||
arg4: 0.0,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
arg4,
|
||||
};
|
||||
let offset = writer.write(uniform_buffer_offset_mask, &data);
|
||||
e.insert(EotfArg { offset })
|
||||
} else {
|
||||
match key {
|
||||
EotfCacheKey::Pow(pow) => arg1 = pow.eotf_f32(),
|
||||
EotfCacheKey::Bt1886(c) => {
|
||||
[arg1, arg2, arg3, arg4] = bt1886_eotf_args(c);
|
||||
}
|
||||
}
|
||||
let data = EotfArgs {
|
||||
arg1: pow.eotf_f32(),
|
||||
arg2: 0.0,
|
||||
arg3: 0.0,
|
||||
arg4: 0.0,
|
||||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
arg4,
|
||||
};
|
||||
let offset = writer.write(uniform_buffer_offset_mask, &data);
|
||||
e.insert(EotfArg { offset })
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#define TF_LINEAR 1
|
||||
#define TF_ST2084_PQ 2
|
||||
#define TF_GAMMA24 3
|
||||
#define TF_BT1886 3
|
||||
#define TF_GAMMA22 4
|
||||
#define TF_GAMMA28 5
|
||||
#define TF_ST240 6
|
||||
|
|
@ -14,6 +14,25 @@
|
|||
#define TF_LOG316 9
|
||||
#define TF_ST428 10
|
||||
#define TF_POW 11
|
||||
#define TF_GAMMA24 12
|
||||
|
||||
vec3 eotf_bt1886(vec3 c) {
|
||||
c = clamp(c, 0.0, 1.0);
|
||||
float a1 = cm_eotf_args.arg1;
|
||||
float a2 = cm_eotf_args.arg2;
|
||||
float a3 = cm_eotf_args.arg3;
|
||||
float a4 = cm_eotf_args.arg4;
|
||||
return a1 * (pow(a2 * c + a3, vec3(2.4)) - a4);
|
||||
}
|
||||
|
||||
vec3 inv_eotf_bt1886(vec3 c) {
|
||||
c = clamp(c, 0.0, 1.0);
|
||||
float a1 = cm_inv_eotf_args.arg1;
|
||||
float a2 = cm_inv_eotf_args.arg2;
|
||||
float a3 = cm_inv_eotf_args.arg3;
|
||||
float a4 = cm_inv_eotf_args.arg4;
|
||||
return a1 * (pow(a2 * c + a3, vec3(1.0 / 2.4)) - a4);
|
||||
}
|
||||
|
||||
vec3 eotf_st2084_pq(vec3 c) {
|
||||
c = clamp(c, 0.0, 1.0);
|
||||
|
|
@ -86,8 +105,9 @@ vec3 apply_eotf(vec3 c) {
|
|||
switch (eotf) {
|
||||
case TF_LINEAR: return c;
|
||||
case TF_ST2084_PQ: return eotf_st2084_pq(c);
|
||||
case TF_GAMMA24: return sign(c) * pow(abs(c), vec3(2.4));
|
||||
case TF_BT1886: return eotf_bt1886(c);
|
||||
case TF_GAMMA22: return sign(c) * pow(abs(c), vec3(2.2));
|
||||
case TF_GAMMA24: return sign(c) * pow(abs(c), vec3(2.4));
|
||||
case TF_GAMMA28: return sign(c) * pow(abs(c), vec3(2.8));
|
||||
case TF_ST240: return eotf_st240(c);
|
||||
case TF_LOG100: return eotf_log100(c);
|
||||
|
|
@ -102,8 +122,9 @@ vec3 apply_inv_eotf(vec3 c) {
|
|||
switch (inv_eotf) {
|
||||
case TF_LINEAR: return c;
|
||||
case TF_ST2084_PQ: return inv_eotf_st2084_pq(c);
|
||||
case TF_GAMMA24: return sign(c) * pow(abs(c), vec3(1.0 / 2.4));
|
||||
case TF_BT1886: return inv_eotf_bt1886(c);
|
||||
case TF_GAMMA22: return sign(c) * pow(abs(c), vec3(1.0 / 2.2));
|
||||
case TF_GAMMA24: return sign(c) * pow(abs(c), vec3(1.0 / 2.4));
|
||||
case TF_GAMMA28: return sign(c) * pow(abs(c), vec3(1.0 / 2.8));
|
||||
case TF_ST240: return inv_eotf_st240(c);
|
||||
case TF_LOG100: return inv_eotf_log100(c);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue