vulkan: allow EOTFs to be parametrized
This commit is contained in:
parent
6d28bfd4e2
commit
a2d726e508
4 changed files with 174 additions and 25 deletions
|
|
@ -15,7 +15,7 @@ pub(super) struct VulkanDescriptorSetLayout {
|
|||
pub(super) device: Rc<VulkanDevice>,
|
||||
pub(super) layout: DescriptorSetLayout,
|
||||
pub(super) size: DeviceSize,
|
||||
pub(super) offsets: ArrayVec<DeviceSize, 2>,
|
||||
pub(super) offsets: ArrayVec<DeviceSize, 4>,
|
||||
pub(super) _sampler: Option<Rc<VulkanSampler>>,
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +98,16 @@ impl VulkanDevice {
|
|||
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||
.descriptor_count(1)
|
||||
.descriptor_type(DescriptorType::UNIFORM_BUFFER),
|
||||
DescriptorSetLayoutBinding::default()
|
||||
.binding(2)
|
||||
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||
.descriptor_count(1)
|
||||
.descriptor_type(DescriptorType::UNIFORM_BUFFER),
|
||||
DescriptorSetLayoutBinding::default()
|
||||
.binding(3)
|
||||
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||
.descriptor_count(1)
|
||||
.descriptor_type(DescriptorType::UNIFORM_BUFFER),
|
||||
];
|
||||
let create_info = DescriptorSetLayoutCreateInfo::default()
|
||||
.bindings(&bindings)
|
||||
|
|
@ -110,6 +120,8 @@ impl VulkanDevice {
|
|||
unsafe {
|
||||
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0));
|
||||
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 1));
|
||||
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 2));
|
||||
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 3));
|
||||
}
|
||||
Ok(Rc::new(VulkanDescriptorSetLayout {
|
||||
device: self.clone(),
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ use {
|
|||
sampler::VulkanSampler,
|
||||
semaphore::VulkanSemaphore,
|
||||
shaders::{
|
||||
ColorManagementData, FILL_FRAG, FILL_VERT, FillPushConstants, LEGACY_FILL_FRAG,
|
||||
LEGACY_FILL_VERT, LEGACY_TEX_FRAG, LEGACY_TEX_VERT, LegacyFillPushConstants,
|
||||
LegacyTexPushConstants, OUT_FRAG, OUT_VERT, OutPushConstants, TEX_FRAG, TEX_VERT,
|
||||
TexPushConstants, TexVertex, VulkanShader,
|
||||
ColorManagementData, EotfArgs, FILL_FRAG, FILL_VERT, FillPushConstants,
|
||||
InvEotfArgs, LEGACY_FILL_FRAG, LEGACY_FILL_VERT, LEGACY_TEX_FRAG, LEGACY_TEX_VERT,
|
||||
LegacyFillPushConstants, LegacyTexPushConstants, OUT_FRAG, OUT_VERT,
|
||||
OutPushConstants, TEX_FRAG, TEX_VERT, TexPushConstants, TexVertex, VulkanShader,
|
||||
},
|
||||
},
|
||||
io_uring::IoUring,
|
||||
|
|
@ -176,10 +176,16 @@ pub(super) struct Memory {
|
|||
data_buffer: Vec<u8>,
|
||||
out_address: DeviceAddress,
|
||||
color_transforms: ColorTransforms,
|
||||
eotf_args_cache: EotfArgsCache,
|
||||
uniform_buffer_writer: GenericBufferWriter,
|
||||
uniform_buffer_descriptor_cache: Option<Box<[u8]>>,
|
||||
blend_buffer_inv_eotf_args_descriptor: Option<Box<[u8]>>,
|
||||
fb_inv_eotf_args_descriptor: Option<Box<[u8]>>,
|
||||
blend_buffer_descriptor_buffer_offset: DeviceAddress,
|
||||
blend_buffer_color_management_data_address: Option<DeviceSize>,
|
||||
blend_buffer_eotf_args_address: Option<DeviceSize>,
|
||||
blend_buffer_inv_eotf_args_address: Option<DeviceSize>,
|
||||
fb_inv_eotf_args_address: Option<DeviceSize>,
|
||||
}
|
||||
|
||||
type Point = [[f32; 2]; 4];
|
||||
|
|
@ -202,6 +208,7 @@ struct VulkanTexOp {
|
|||
instances: u32,
|
||||
tex_cd: Rc<ColorDescription>,
|
||||
color_management_data_address: Option<DeviceAddress>,
|
||||
eotf_args_address: Option<DeviceAddress>,
|
||||
resource_descriptor_buffer_offset: DeviceAddress,
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +359,9 @@ impl VulkanDevice {
|
|||
};
|
||||
let uniform_buffer_cache = {
|
||||
let usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS | BufferUsageFlags::UNIFORM_BUFFER;
|
||||
let align = align_of::<ColorManagementData>() as DeviceSize;
|
||||
let align = align_of::<ColorManagementData>()
|
||||
.max(align_of::<EotfArgs>())
|
||||
.max(align_of::<InvEotfArgs>()) as DeviceSize;
|
||||
VulkanBufferCache::new(self, &allocator, usage, align)
|
||||
};
|
||||
let render = Rc::new(VulkanRenderer {
|
||||
|
|
@ -562,11 +571,14 @@ impl VulkanRenderer {
|
|||
}
|
||||
let resource_writer = &mut memory.resource_descriptor_buffer_writer;
|
||||
resource_writer.clear();
|
||||
let uniform_buffer_descriptor_cache = memory
|
||||
.uniform_buffer_descriptor_cache
|
||||
.get_or_insert_with(|| {
|
||||
vec![0u8; self.device.uniform_buffer_descriptor_size].into_boxed_slice()
|
||||
});
|
||||
macro_rules! ub_descriptor_cache {
|
||||
($field:ident) => {
|
||||
memory.$field.get_or_insert_with(|| {
|
||||
vec![0u8; self.device.uniform_buffer_descriptor_size].into_boxed_slice()
|
||||
})
|
||||
};
|
||||
}
|
||||
let uniform_buffer_descriptor_cache = ub_descriptor_cache!(uniform_buffer_descriptor_cache);
|
||||
macro_rules! get_ub_descriptor {
|
||||
($addr:expr, $ty:ty, $descriptor:expr $(,)?) => {{
|
||||
let uniform_buffer = DescriptorAddressInfoEXT::default()
|
||||
|
|
@ -586,6 +598,22 @@ impl VulkanRenderer {
|
|||
get_ub_descriptor!($addr, $ty, uniform_buffer_descriptor_cache)
|
||||
};
|
||||
}
|
||||
let mut blend_buffer_inv_eotf_args_descriptor = None;
|
||||
if let Some(addr) = memory.blend_buffer_inv_eotf_args_address {
|
||||
blend_buffer_inv_eotf_args_descriptor = Some(get_ub_descriptor!(
|
||||
addr,
|
||||
InvEotfArgs,
|
||||
ub_descriptor_cache!(blend_buffer_inv_eotf_args_descriptor),
|
||||
));
|
||||
}
|
||||
let mut fb_inv_eotf_args_descriptor = None;
|
||||
if let Some(addr) = memory.fb_inv_eotf_args_address {
|
||||
fb_inv_eotf_args_descriptor = Some(get_ub_descriptor!(
|
||||
addr,
|
||||
InvEotfArgs,
|
||||
ub_descriptor_cache!(fb_inv_eotf_args_descriptor),
|
||||
));
|
||||
}
|
||||
if let Some(bb) = bb {
|
||||
let layout = self.out_descriptor_set_layout.as_ref().unwrap();
|
||||
memory.blend_buffer_descriptor_buffer_offset = resource_writer.next_offset();
|
||||
|
|
@ -597,9 +625,19 @@ impl VulkanRenderer {
|
|||
get_ub_descriptor!(addr, ColorManagementData),
|
||||
);
|
||||
}
|
||||
if let Some(addr) = memory.blend_buffer_eotf_args_address {
|
||||
writer.write(layout.offsets[2], get_ub_descriptor!(addr, EotfArgs));
|
||||
}
|
||||
if let Some(desc) = fb_inv_eotf_args_descriptor {
|
||||
writer.write(layout.offsets[3], desc);
|
||||
}
|
||||
}
|
||||
let tex_descriptor_set_layout = &self.tex_descriptor_set_layouts[1];
|
||||
for pass in RenderPass::variants() {
|
||||
let inv_eotf_desc = match pass {
|
||||
RenderPass::BlendBuffer => blend_buffer_inv_eotf_args_descriptor,
|
||||
RenderPass::FrameBuffer => fb_inv_eotf_args_descriptor,
|
||||
};
|
||||
for cmd in &mut memory.ops[pass] {
|
||||
let VulkanOp::Tex(c) = cmd else {
|
||||
continue;
|
||||
|
|
@ -617,6 +655,15 @@ impl VulkanRenderer {
|
|||
get_ub_descriptor!(addr, ColorManagementData),
|
||||
);
|
||||
}
|
||||
if let Some(addr) = c.eotf_args_address {
|
||||
writer.write(
|
||||
tex_descriptor_set_layout.offsets[2],
|
||||
get_ub_descriptor!(addr, EotfArgs),
|
||||
);
|
||||
}
|
||||
if let Some(desc) = inv_eotf_desc {
|
||||
writer.write(tex_descriptor_set_layout.offsets[3], desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut infos = ArrayVec::<_, 2>::new();
|
||||
|
|
@ -659,6 +706,7 @@ impl VulkanRenderer {
|
|||
memory.data_buffer.clear();
|
||||
memory.uniform_buffer_writer.clear();
|
||||
memory.color_transforms.map.clear();
|
||||
memory.eotf_args_cache.map.clear();
|
||||
let sync = |memory: &mut Memory| {
|
||||
for pass in RenderPass::variants() {
|
||||
let ops = &mut memory.ops_tmp[pass];
|
||||
|
|
@ -813,6 +861,12 @@ impl VulkanRenderer {
|
|||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
let eotf_args_address = memory.eotf_args_cache.get_offset(
|
||||
&ct.cd,
|
||||
false,
|
||||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
ops.push(VulkanOp::Tex(VulkanTexOp {
|
||||
tex: tex.clone(),
|
||||
range: lo..hi,
|
||||
|
|
@ -826,6 +880,7 @@ impl VulkanRenderer {
|
|||
instances: 0,
|
||||
tex_cd: ct.cd.clone(),
|
||||
color_management_data_address,
|
||||
eotf_args_address,
|
||||
resource_descriptor_buffer_offset: 0,
|
||||
}));
|
||||
}
|
||||
|
|
@ -836,21 +891,41 @@ impl VulkanRenderer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn create_blend_cm_data(
|
||||
fn create_fixed_cm_data(
|
||||
&self,
|
||||
bb: Option<&VulkanImage>,
|
||||
bb_cd: &ColorDescription,
|
||||
fb_cd: &ColorDescription,
|
||||
) {
|
||||
zone!("create_blend_cm_data");
|
||||
zone!("create_fixed_cm_data");
|
||||
let memory = &mut *self.memory.borrow_mut();
|
||||
memory.blend_buffer_color_management_data_address = None;
|
||||
if bb.is_none() {
|
||||
return;
|
||||
memory.blend_buffer_eotf_args_address = None;
|
||||
memory.blend_buffer_inv_eotf_args_address = None;
|
||||
memory.fb_inv_eotf_args_address = None;
|
||||
if bb.is_some() {
|
||||
memory.blend_buffer_color_management_data_address = memory.color_transforms.get_offset(
|
||||
&bb_cd.linear,
|
||||
fb_cd,
|
||||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
memory.blend_buffer_eotf_args_address = memory.eotf_args_cache.get_offset(
|
||||
bb_cd,
|
||||
false,
|
||||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
memory.blend_buffer_inv_eotf_args_address = memory.eotf_args_cache.get_offset(
|
||||
bb_cd,
|
||||
true,
|
||||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
}
|
||||
memory.blend_buffer_color_management_data_address = memory.color_transforms.get_offset(
|
||||
&bb_cd.linear,
|
||||
memory.fb_inv_eotf_args_address = memory.eotf_args_cache.get_offset(
|
||||
fb_cd,
|
||||
true,
|
||||
self.device.uniform_buffer_offset_mask,
|
||||
&mut memory.uniform_buffer_writer,
|
||||
);
|
||||
|
|
@ -912,18 +987,25 @@ impl VulkanRenderer {
|
|||
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
||||
ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
|
||||
})?;
|
||||
macro_rules! adj {
|
||||
($expr:expr) => {
|
||||
if let Some(addr) = $expr {
|
||||
*addr += buffer.buffer.address;
|
||||
}
|
||||
};
|
||||
}
|
||||
for ops in memory.ops.values_mut() {
|
||||
for op in ops {
|
||||
if let VulkanOp::Tex(c) = op
|
||||
&& let Some(addr) = &mut c.color_management_data_address
|
||||
{
|
||||
*addr += buffer.buffer.address;
|
||||
if let VulkanOp::Tex(c) = op {
|
||||
adj!(&mut c.color_management_data_address);
|
||||
adj!(&mut c.eotf_args_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(addr) = &mut memory.blend_buffer_color_management_data_address {
|
||||
*addr += buffer.buffer.address;
|
||||
}
|
||||
adj!(&mut memory.blend_buffer_color_management_data_address);
|
||||
adj!(&mut memory.blend_buffer_eotf_args_address);
|
||||
adj!(&mut memory.blend_buffer_inv_eotf_args_address);
|
||||
adj!(&mut memory.fb_inv_eotf_args_address);
|
||||
memory.used_buffers.push(buffer);
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1942,7 +2024,7 @@ impl VulkanRenderer {
|
|||
let bb = blend_buffer.as_deref();
|
||||
let buf = self.gfx_command_buffers.allocate()?;
|
||||
self.convert_ops(opts, bb_cd, fb_cd)?;
|
||||
self.create_blend_cm_data(bb, bb_cd, fb_cd);
|
||||
self.create_fixed_cm_data(bb, bb_cd, fb_cd);
|
||||
self.create_data_buffer()?;
|
||||
self.create_uniform_buffer()?;
|
||||
self.collect_memory();
|
||||
|
|
@ -2242,3 +2324,24 @@ impl ColorTransforms {
|
|||
ct.offset
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct EotfArgsCache {
|
||||
map: AHashMap<(), EotfArg>,
|
||||
}
|
||||
|
||||
struct EotfArg {
|
||||
_offset: DeviceSize,
|
||||
}
|
||||
|
||||
impl EotfArgsCache {
|
||||
fn get_offset(
|
||||
&mut self,
|
||||
_desc: &ColorDescription,
|
||||
_inv: bool,
|
||||
_uniform_buffer_offset_mask: DeviceSize,
|
||||
_writer: &mut GenericBufferWriter,
|
||||
) -> Option<DeviceSize> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,28 @@ pub struct ColorManagementData {
|
|||
|
||||
unsafe impl Packed for ColorManagementData {}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C, align(16))]
|
||||
pub struct EotfArgs {
|
||||
pub arg1: f32,
|
||||
pub arg2: f32,
|
||||
pub arg3: f32,
|
||||
pub arg4: f32,
|
||||
}
|
||||
|
||||
unsafe impl Packed for EotfArgs {}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C, align(16))]
|
||||
pub struct InvEotfArgs {
|
||||
pub arg1: f32,
|
||||
pub arg2: f32,
|
||||
pub arg3: f32,
|
||||
pub arg4: f32,
|
||||
}
|
||||
|
||||
unsafe impl Packed for InvEotfArgs {}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct LegacyTexPushConstants {
|
||||
|
|
|
|||
|
|
@ -5,5 +5,17 @@ layout(set = TEX_SET, binding = 0) uniform texture2D tex;
|
|||
layout(set = TEX_SET, binding = 1, row_major, std430) uniform ColorManagementData {
|
||||
mat4x4 matrix;
|
||||
} cm_data;
|
||||
layout(set = TEX_SET, binding = 2, row_major, std430) uniform EotfArgs {
|
||||
float arg1;
|
||||
float arg2;
|
||||
float arg3;
|
||||
float arg4;
|
||||
} cm_eotf_args;
|
||||
layout(set = TEX_SET, binding = 3, row_major, std430) uniform InvEotfArgs {
|
||||
float arg1;
|
||||
float arg2;
|
||||
float arg3;
|
||||
float arg4;
|
||||
} cm_inv_eotf_args;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue