vulkan: apply color space transforms to textures
This commit is contained in:
parent
c4d0fdd4bb
commit
8e65de91f9
12 changed files with 233 additions and 66 deletions
|
|
@ -157,7 +157,6 @@ impl<T, U> ColorMatrix<T, U> {
|
||||||
Self(m, PhantomData)
|
Self(m, PhantomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(dead_code)]
|
|
||||||
pub const fn to_f32(&self) -> [[f32; 4]; 4] {
|
pub const fn to_f32(&self) -> [[f32; 4]; 4] {
|
||||||
let m = &self.0;
|
let m = &self.0;
|
||||||
macro_rules! map {
|
macro_rules! map {
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,6 @@ impl VulkanRenderer {
|
||||||
ty: VulkanImageMemory::Blend(allocation),
|
ty: VulkanImageMemory::Blend(allocation),
|
||||||
bridge: None,
|
bridge: None,
|
||||||
sampled_image_descriptor: self.sampled_image_descriptor(view),
|
sampled_image_descriptor: self.sampled_image_descriptor(view),
|
||||||
descriptor_buffer_version: Default::default(),
|
|
||||||
descriptor_buffer_offset: Default::default(),
|
|
||||||
execution_version: Default::default(),
|
execution_version: Default::default(),
|
||||||
});
|
});
|
||||||
cached.insert_entry(Rc::downgrade(&img));
|
cached.insert_entry(Rc::downgrade(&img));
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ use {
|
||||||
DeviceSize,
|
DeviceSize,
|
||||||
},
|
},
|
||||||
gpu_alloc::UsageFlags,
|
gpu_alloc::UsageFlags,
|
||||||
std::{cell::RefCell, mem::ManuallyDrop, rc::Rc},
|
std::{cell::RefCell, mem::ManuallyDrop, ops::Deref, rc::Rc},
|
||||||
|
uapi::Packed,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct VulkanBufferCache {
|
pub struct VulkanBufferCache {
|
||||||
|
|
@ -20,6 +21,7 @@ pub struct VulkanBufferCache {
|
||||||
allocator: Rc<VulkanAllocator>,
|
allocator: Rc<VulkanAllocator>,
|
||||||
buffers: RefCell<Vec<VulkanBufferUnused>>,
|
buffers: RefCell<Vec<VulkanBufferUnused>>,
|
||||||
usage: BufferUsageFlags,
|
usage: BufferUsageFlags,
|
||||||
|
min_alignment: DeviceSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct VulkanBuffer {
|
pub struct VulkanBuffer {
|
||||||
|
|
@ -40,12 +42,14 @@ impl VulkanBufferCache {
|
||||||
device: &Rc<VulkanDevice>,
|
device: &Rc<VulkanDevice>,
|
||||||
allocator: &Rc<VulkanAllocator>,
|
allocator: &Rc<VulkanAllocator>,
|
||||||
usage: BufferUsageFlags,
|
usage: BufferUsageFlags,
|
||||||
|
min_alignment: DeviceSize,
|
||||||
) -> Rc<Self> {
|
) -> Rc<Self> {
|
||||||
Rc::new(Self {
|
Rc::new(Self {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
allocator: allocator.clone(),
|
allocator: allocator.clone(),
|
||||||
buffers: Default::default(),
|
buffers: Default::default(),
|
||||||
usage,
|
usage,
|
||||||
|
min_alignment,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,25 +59,27 @@ impl VulkanBufferCache {
|
||||||
for_sampler: bool,
|
for_sampler: bool,
|
||||||
) -> Rc<Self> {
|
) -> Rc<Self> {
|
||||||
let mut usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS;
|
let mut usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS;
|
||||||
|
let mut min_alignment = 1;
|
||||||
if for_sampler {
|
if for_sampler {
|
||||||
usage |= BufferUsageFlags::SAMPLER_DESCRIPTOR_BUFFER_EXT;
|
usage |= BufferUsageFlags::SAMPLER_DESCRIPTOR_BUFFER_EXT;
|
||||||
} else {
|
} else {
|
||||||
usage |= BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT;
|
usage |= BufferUsageFlags::RESOURCE_DESCRIPTOR_BUFFER_EXT;
|
||||||
|
if device.is_anv {
|
||||||
|
// https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33903
|
||||||
|
min_alignment = 4096;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Self::new(device, allocator, usage)
|
Self::new(device, allocator, usage, min_alignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn usage(&self) -> BufferUsageFlags {
|
pub fn usage(&self) -> BufferUsageFlags {
|
||||||
self.usage
|
self.usage
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate(
|
pub fn allocate(self: &Rc<Self>, capacity: DeviceSize) -> Result<VulkanBuffer, VulkanError> {
|
||||||
self: &Rc<Self>,
|
|
||||||
capacity: DeviceSize,
|
|
||||||
align: DeviceSize,
|
|
||||||
) -> Result<VulkanBuffer, VulkanError> {
|
|
||||||
const MIN_ALLOCATION: DeviceSize = 1024;
|
const MIN_ALLOCATION: DeviceSize = 1024;
|
||||||
let capacity = (capacity.max(MIN_ALLOCATION) + align - 1) & !(align - 1);
|
let align_mask = self.min_alignment - 1;
|
||||||
|
let capacity = (capacity.max(MIN_ALLOCATION) + align_mask) & !align_mask;
|
||||||
let mut smallest = None;
|
let mut smallest = None;
|
||||||
let mut smallest_size = DeviceSize::MAX;
|
let mut smallest_size = DeviceSize::MAX;
|
||||||
let mut fitting = None;
|
let mut fitting = None;
|
||||||
|
|
@ -116,7 +122,7 @@ impl VulkanBufferCache {
|
||||||
let destroy_buffer = OnDrop(|| unsafe { self.device.device.destroy_buffer(buffer, None) });
|
let destroy_buffer = OnDrop(|| unsafe { self.device.device.destroy_buffer(buffer, None) });
|
||||||
let mut memory_requirements =
|
let mut memory_requirements =
|
||||||
unsafe { self.device.device.get_buffer_memory_requirements(buffer) };
|
unsafe { self.device.device.get_buffer_memory_requirements(buffer) };
|
||||||
memory_requirements.alignment = memory_requirements.alignment.max(align);
|
memory_requirements.alignment = memory_requirements.alignment.max(self.min_alignment);
|
||||||
let allocation = {
|
let allocation = {
|
||||||
let flags = UsageFlags::UPLOAD
|
let flags = UsageFlags::UPLOAD
|
||||||
| UsageFlags::FAST_DEVICE_ACCESS
|
| UsageFlags::FAST_DEVICE_ACCESS
|
||||||
|
|
@ -162,3 +168,31 @@ impl Drop for VulkanBufferUnused {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct GenericBufferWriter {
|
||||||
|
buf: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericBufferWriter {
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.buf.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(&mut self, offset_mask: DeviceSize, data: &(impl Packed + ?Sized)) -> DeviceSize {
|
||||||
|
let mut offset = self.buf.len() as DeviceSize;
|
||||||
|
let mask = offset_mask | (align_of_val(data) as DeviceSize - 1);
|
||||||
|
offset = (offset + mask) & !mask;
|
||||||
|
self.buf.resize(offset as usize, 0);
|
||||||
|
self.buf.extend_from_slice(uapi::as_bytes(data));
|
||||||
|
offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for GenericBufferWriter {
|
||||||
|
type Target = [u8];
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ pub(super) struct VulkanDescriptorSetLayout {
|
||||||
pub(super) device: Rc<VulkanDevice>,
|
pub(super) device: Rc<VulkanDevice>,
|
||||||
pub(super) layout: DescriptorSetLayout,
|
pub(super) layout: DescriptorSetLayout,
|
||||||
pub(super) size: DeviceSize,
|
pub(super) size: DeviceSize,
|
||||||
pub(super) offsets: ArrayVec<DeviceSize, 1>,
|
pub(super) offsets: ArrayVec<DeviceSize, 2>,
|
||||||
pub(super) _sampler: Option<Rc<VulkanSampler>>,
|
pub(super) _sampler: Option<Rc<VulkanSampler>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,12 +87,20 @@ impl VulkanDevice {
|
||||||
pub(super) fn create_tex_resource_descriptor_set_layout(
|
pub(super) fn create_tex_resource_descriptor_set_layout(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
) -> Result<Rc<VulkanDescriptorSetLayout>, VulkanError> {
|
) -> Result<Rc<VulkanDescriptorSetLayout>, VulkanError> {
|
||||||
let binding = DescriptorSetLayoutBinding::default()
|
let bindings = [
|
||||||
.stage_flags(ShaderStageFlags::FRAGMENT)
|
DescriptorSetLayoutBinding::default()
|
||||||
.descriptor_count(1)
|
.binding(0)
|
||||||
.descriptor_type(DescriptorType::SAMPLED_IMAGE);
|
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||||
|
.descriptor_count(1)
|
||||||
|
.descriptor_type(DescriptorType::SAMPLED_IMAGE),
|
||||||
|
DescriptorSetLayoutBinding::default()
|
||||||
|
.binding(1)
|
||||||
|
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||||
|
.descriptor_count(1)
|
||||||
|
.descriptor_type(DescriptorType::UNIFORM_BUFFER),
|
||||||
|
];
|
||||||
let create_info = DescriptorSetLayoutCreateInfo::default()
|
let create_info = DescriptorSetLayoutCreateInfo::default()
|
||||||
.bindings(slice::from_ref(&binding))
|
.bindings(&bindings)
|
||||||
.flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT);
|
.flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT);
|
||||||
let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) };
|
let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) };
|
||||||
let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?;
|
let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?;
|
||||||
|
|
@ -101,6 +109,7 @@ impl VulkanDevice {
|
||||||
let mut offsets = ArrayVec::new();
|
let mut offsets = ArrayVec::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0));
|
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0));
|
||||||
|
offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 1));
|
||||||
}
|
}
|
||||||
Ok(Rc::new(VulkanDescriptorSetLayout {
|
Ok(Rc::new(VulkanDescriptorSetLayout {
|
||||||
device: self.clone(),
|
device: self.clone(),
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,9 @@ use {
|
||||||
PhysicalDeviceDrmPropertiesEXT, PhysicalDeviceDynamicRenderingFeatures,
|
PhysicalDeviceDrmPropertiesEXT, PhysicalDeviceDynamicRenderingFeatures,
|
||||||
PhysicalDeviceExternalSemaphoreInfo, PhysicalDeviceProperties,
|
PhysicalDeviceExternalSemaphoreInfo, PhysicalDeviceProperties,
|
||||||
PhysicalDeviceProperties2, PhysicalDeviceSynchronization2Features,
|
PhysicalDeviceProperties2, PhysicalDeviceSynchronization2Features,
|
||||||
PhysicalDeviceTimelineSemaphoreFeatures, PhysicalDeviceVulkan12Properties, Queue,
|
PhysicalDeviceTimelineSemaphoreFeatures,
|
||||||
QueueFlags,
|
PhysicalDeviceUniformBufferStandardLayoutFeatures, PhysicalDeviceVulkan12Properties,
|
||||||
|
Queue, QueueFlags,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isnt::std_1::collections::IsntHashMap2Ext,
|
isnt::std_1::collections::IsntHashMap2Ext,
|
||||||
|
|
@ -75,6 +76,8 @@ pub struct VulkanDevice {
|
||||||
pub(super) sampler_descriptor_size: usize,
|
pub(super) sampler_descriptor_size: usize,
|
||||||
pub(super) sampled_image_descriptor_size: usize,
|
pub(super) sampled_image_descriptor_size: usize,
|
||||||
pub(super) is_anv: bool,
|
pub(super) is_anv: bool,
|
||||||
|
pub(super) uniform_buffer_offset_mask: DeviceSize,
|
||||||
|
pub(super) uniform_buffer_descriptor_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for VulkanDevice {
|
impl Drop for VulkanDevice {
|
||||||
|
|
@ -308,6 +311,9 @@ impl VulkanInstance {
|
||||||
PhysicalDeviceDescriptorBufferFeaturesEXT::default().descriptor_buffer(true);
|
PhysicalDeviceDescriptorBufferFeaturesEXT::default().descriptor_buffer(true);
|
||||||
let mut buffer_device_address_features =
|
let mut buffer_device_address_features =
|
||||||
PhysicalDeviceBufferDeviceAddressFeatures::default().buffer_device_address(true);
|
PhysicalDeviceBufferDeviceAddressFeatures::default().buffer_device_address(true);
|
||||||
|
let mut uniform_buffer_standard_layout_features =
|
||||||
|
PhysicalDeviceUniformBufferStandardLayoutFeatures::default()
|
||||||
|
.uniform_buffer_standard_layout(true);
|
||||||
let mut queue_create_infos = ArrayVec::<_, 2>::new();
|
let mut queue_create_infos = ArrayVec::<_, 2>::new();
|
||||||
queue_create_infos.push(
|
queue_create_infos.push(
|
||||||
DeviceQueueCreateInfo::default()
|
DeviceQueueCreateInfo::default()
|
||||||
|
|
@ -325,6 +331,7 @@ impl VulkanInstance {
|
||||||
.push_next(&mut semaphore_features)
|
.push_next(&mut semaphore_features)
|
||||||
.push_next(&mut synchronization2_features)
|
.push_next(&mut synchronization2_features)
|
||||||
.push_next(&mut dynamic_rendering_features)
|
.push_next(&mut dynamic_rendering_features)
|
||||||
|
.push_next(&mut uniform_buffer_standard_layout_features)
|
||||||
.queue_create_infos(&queue_create_infos)
|
.queue_create_infos(&queue_create_infos)
|
||||||
.enabled_extension_names(&enabled_extensions);
|
.enabled_extension_names(&enabled_extensions);
|
||||||
if supports_descriptor_buffer {
|
if supports_descriptor_buffer {
|
||||||
|
|
@ -382,6 +389,14 @@ impl VulkanInstance {
|
||||||
let mut descriptor_buffer_offset_mask = 0;
|
let mut descriptor_buffer_offset_mask = 0;
|
||||||
let mut sampler_descriptor_size = 0;
|
let mut sampler_descriptor_size = 0;
|
||||||
let mut sampled_image_descriptor_size = 0;
|
let mut sampled_image_descriptor_size = 0;
|
||||||
|
let mut uniform_buffer_descriptor_size = 0;
|
||||||
|
let uniform_buffer_offset_mask = physical_device_properties2
|
||||||
|
.properties
|
||||||
|
.limits
|
||||||
|
.min_uniform_buffer_offset_alignment
|
||||||
|
.checked_next_power_of_two()
|
||||||
|
.unwrap()
|
||||||
|
- 1;
|
||||||
if supports_descriptor_buffer {
|
if supports_descriptor_buffer {
|
||||||
descriptor_buffer_offset_mask = descriptor_buffer_props
|
descriptor_buffer_offset_mask = descriptor_buffer_props
|
||||||
.descriptor_buffer_offset_alignment
|
.descriptor_buffer_offset_alignment
|
||||||
|
|
@ -390,6 +405,7 @@ impl VulkanInstance {
|
||||||
- 1;
|
- 1;
|
||||||
sampler_descriptor_size = descriptor_buffer_props.sampler_descriptor_size;
|
sampler_descriptor_size = descriptor_buffer_props.sampler_descriptor_size;
|
||||||
sampled_image_descriptor_size = descriptor_buffer_props.sampled_image_descriptor_size;
|
sampled_image_descriptor_size = descriptor_buffer_props.sampled_image_descriptor_size;
|
||||||
|
uniform_buffer_descriptor_size = descriptor_buffer_props.uniform_buffer_descriptor_size;
|
||||||
}
|
}
|
||||||
let memory_properties =
|
let memory_properties =
|
||||||
unsafe { self.instance.get_physical_device_memory_properties(phy_dev) };
|
unsafe { self.instance.get_physical_device_memory_properties(phy_dev) };
|
||||||
|
|
@ -432,6 +448,8 @@ impl VulkanInstance {
|
||||||
blend_limits,
|
blend_limits,
|
||||||
is_anv: physical_device_vulkan12_properties.driver_id
|
is_anv: physical_device_vulkan12_properties.driver_id
|
||||||
== DriverId::INTEL_OPEN_SOURCE_MESA,
|
== DriverId::INTEL_OPEN_SOURCE_MESA,
|
||||||
|
uniform_buffer_offset_mask,
|
||||||
|
uniform_buffer_descriptor_size,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ use {
|
||||||
ash::vk::{
|
ash::vk::{
|
||||||
BindImageMemoryInfo, BindImagePlaneMemoryInfo, ComponentMapping, ComponentSwizzle,
|
BindImageMemoryInfo, BindImagePlaneMemoryInfo, ComponentMapping, ComponentSwizzle,
|
||||||
DescriptorDataEXT, DescriptorGetInfoEXT, DescriptorImageInfo, DescriptorType, DeviceMemory,
|
DescriptorDataEXT, DescriptorGetInfoEXT, DescriptorImageInfo, DescriptorType, DeviceMemory,
|
||||||
DeviceSize, Extent3D, ExternalMemoryHandleTypeFlags, ExternalMemoryImageCreateInfo,
|
Extent3D, ExternalMemoryHandleTypeFlags, ExternalMemoryImageCreateInfo, FormatFeatureFlags,
|
||||||
FormatFeatureFlags, Image, ImageAspectFlags, ImageCreateFlags, ImageCreateInfo,
|
Image, ImageAspectFlags, ImageCreateFlags, ImageCreateInfo,
|
||||||
ImageDrmFormatModifierExplicitCreateInfoEXT, ImageLayout, ImageMemoryRequirementsInfo2,
|
ImageDrmFormatModifierExplicitCreateInfoEXT, ImageLayout, ImageMemoryRequirementsInfo2,
|
||||||
ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType,
|
ImagePlaneMemoryRequirementsInfo, ImageSubresourceRange, ImageTiling, ImageType,
|
||||||
ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR,
|
ImageUsageFlags, ImageView, ImageViewCreateInfo, ImageViewType, ImportMemoryFdInfoKHR,
|
||||||
|
|
@ -66,8 +66,6 @@ pub struct VulkanImage {
|
||||||
pub(super) ty: VulkanImageMemory,
|
pub(super) ty: VulkanImageMemory,
|
||||||
pub(super) bridge: Option<VulkanFramebufferBridge>,
|
pub(super) bridge: Option<VulkanFramebufferBridge>,
|
||||||
pub(super) sampled_image_descriptor: Box<[u8]>,
|
pub(super) sampled_image_descriptor: Box<[u8]>,
|
||||||
pub(super) descriptor_buffer_version: Cell<u64>,
|
|
||||||
pub(super) descriptor_buffer_offset: Cell<DeviceSize>,
|
|
||||||
pub(super) execution_version: Cell<u64>,
|
pub(super) execution_version: Cell<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,8 +466,6 @@ impl VulkanDmaBufImageTemplate {
|
||||||
}),
|
}),
|
||||||
bridge,
|
bridge,
|
||||||
sampled_image_descriptor: self.renderer.sampled_image_descriptor(texture_view),
|
sampled_image_descriptor: self.renderer.sampled_image_descriptor(texture_view),
|
||||||
descriptor_buffer_version: Cell::new(0),
|
|
||||||
descriptor_buffer_offset: Cell::new(0),
|
|
||||||
execution_version: Cell::new(0),
|
execution_version: Cell::new(0),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ pub(super) struct PipelineCreateInfo {
|
||||||
pub(super) eotf: u32,
|
pub(super) eotf: u32,
|
||||||
pub(super) oetf: u32,
|
pub(super) oetf: u32,
|
||||||
pub(super) descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
|
pub(super) descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
|
||||||
|
pub(super) has_color_management_data: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanDevice {
|
impl VulkanDevice {
|
||||||
|
|
@ -77,8 +78,8 @@ impl VulkanDevice {
|
||||||
};
|
};
|
||||||
let destroy_layout =
|
let destroy_layout =
|
||||||
OnDrop(|| unsafe { self.device.destroy_pipeline_layout(pipeline_layout, None) });
|
OnDrop(|| unsafe { self.device.destroy_pipeline_layout(pipeline_layout, None) });
|
||||||
let mut frag_spec_data = ArrayVec::<_, { 4 * 4 }>::new();
|
let mut frag_spec_data = ArrayVec::<_, { 5 * 4 }>::new();
|
||||||
let mut frag_spec_entries = ArrayVec::<_, 4>::new();
|
let mut frag_spec_entries = ArrayVec::<_, 5>::new();
|
||||||
let mut frag_spec_entry = |data: &[u8]| {
|
let mut frag_spec_entry = |data: &[u8]| {
|
||||||
let entry = SpecializationMapEntry::default()
|
let entry = SpecializationMapEntry::default()
|
||||||
.constant_id(frag_spec_entries.len() as _)
|
.constant_id(frag_spec_entries.len() as _)
|
||||||
|
|
@ -91,6 +92,7 @@ impl VulkanDevice {
|
||||||
frag_spec_entry(&(info.has_alpha_mult as u32).to_ne_bytes());
|
frag_spec_entry(&(info.has_alpha_mult as u32).to_ne_bytes());
|
||||||
frag_spec_entry(&info.eotf.to_ne_bytes());
|
frag_spec_entry(&info.eotf.to_ne_bytes());
|
||||||
frag_spec_entry(&info.oetf.to_ne_bytes());
|
frag_spec_entry(&info.oetf.to_ne_bytes());
|
||||||
|
frag_spec_entry(&(info.has_color_management_data as u32).to_ne_bytes());
|
||||||
let frag_spec = SpecializationInfo::default()
|
let frag_spec = SpecializationInfo::default()
|
||||||
.map_entries(&frag_spec_entries)
|
.map_entries(&frag_spec_entries)
|
||||||
.data(&frag_spec_data);
|
.data(&frag_spec_data);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use {
|
||||||
gfx_apis::vulkan::{
|
gfx_apis::vulkan::{
|
||||||
VulkanError,
|
VulkanError,
|
||||||
allocator::{VulkanAllocator, VulkanThreadedAllocator},
|
allocator::{VulkanAllocator, VulkanThreadedAllocator},
|
||||||
buffer_cache::{VulkanBuffer, VulkanBufferCache},
|
buffer_cache::{GenericBufferWriter, VulkanBuffer, VulkanBufferCache},
|
||||||
command::{VulkanCommandBuffer, VulkanCommandPool},
|
command::{VulkanCommandBuffer, VulkanCommandPool},
|
||||||
descriptor::VulkanDescriptorSetLayout,
|
descriptor::VulkanDescriptorSetLayout,
|
||||||
descriptor_buffer::VulkanDescriptorBufferWriter,
|
descriptor_buffer::VulkanDescriptorBufferWriter,
|
||||||
|
|
@ -27,8 +27,8 @@ use {
|
||||||
shaders::{
|
shaders::{
|
||||||
FILL_FRAG, FILL_VERT, FillPushConstants, LEGACY_FILL_FRAG, LEGACY_FILL_VERT,
|
FILL_FRAG, FILL_VERT, FillPushConstants, LEGACY_FILL_FRAG, LEGACY_FILL_VERT,
|
||||||
LEGACY_TEX_FRAG, LEGACY_TEX_VERT, LegacyFillPushConstants, LegacyTexPushConstants,
|
LEGACY_TEX_FRAG, LEGACY_TEX_VERT, LegacyFillPushConstants, LegacyTexPushConstants,
|
||||||
OUT_FRAG, OUT_VERT, OutPushConstants, TEX_FRAG, TEX_VERT, TexPushConstants,
|
OUT_FRAG, OUT_VERT, OutPushConstants, TEX_FRAG, TEX_VERT, TexColorManagementData,
|
||||||
TexVertex, VulkanShader,
|
TexPushConstants, TexVertex, VulkanShader,
|
||||||
},
|
},
|
||||||
transfer_functions::{TF_LINEAR, TransferFunctionExt},
|
transfer_functions::{TF_LINEAR, TransferFunctionExt},
|
||||||
},
|
},
|
||||||
|
|
@ -46,9 +46,10 @@ use {
|
||||||
self, AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferUsageFlags,
|
self, AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferUsageFlags,
|
||||||
ClearAttachment, ClearColorValue, ClearRect, ClearValue, CommandBuffer,
|
ClearAttachment, ClearColorValue, ClearRect, ClearValue, CommandBuffer,
|
||||||
CommandBufferBeginInfo, CommandBufferSubmitInfo, CommandBufferUsageFlags,
|
CommandBufferBeginInfo, CommandBufferSubmitInfo, CommandBufferUsageFlags,
|
||||||
CopyImageInfo2, DependencyInfoKHR, DescriptorBufferBindingInfoEXT, DescriptorImageInfo,
|
CopyImageInfo2, DependencyInfoKHR, DescriptorAddressInfoEXT,
|
||||||
DescriptorType, DeviceAddress, DeviceSize, Extent2D, Extent3D, ImageAspectFlags,
|
DescriptorBufferBindingInfoEXT, DescriptorDataEXT, DescriptorGetInfoEXT,
|
||||||
ImageCopy2, ImageLayout, ImageMemoryBarrier2, ImageSubresourceLayers,
|
DescriptorImageInfo, DescriptorType, DeviceAddress, DeviceSize, Extent2D, Extent3D,
|
||||||
|
ImageAspectFlags, ImageCopy2, ImageLayout, ImageMemoryBarrier2, ImageSubresourceLayers,
|
||||||
ImageSubresourceRange, Offset2D, Offset3D, PipelineBindPoint, PipelineStageFlags2,
|
ImageSubresourceRange, Offset2D, Offset3D, PipelineBindPoint, PipelineStageFlags2,
|
||||||
QUEUE_FAMILY_FOREIGN_EXT, Rect2D, RenderingAttachmentInfo, RenderingInfo,
|
QUEUE_FAMILY_FOREIGN_EXT, Rect2D, RenderingAttachmentInfo, RenderingInfo,
|
||||||
SemaphoreSubmitInfo, SemaphoreSubmitInfoKHR, ShaderStageFlags, SubmitInfo2, Viewport,
|
SemaphoreSubmitInfo, SemaphoreSubmitInfoKHR, ShaderStageFlags, SubmitInfo2, Viewport,
|
||||||
|
|
@ -108,6 +109,7 @@ pub struct VulkanRenderer {
|
||||||
pub(super) resource_descriptor_buffer_cache: Rc<VulkanBufferCache>,
|
pub(super) resource_descriptor_buffer_cache: Rc<VulkanBufferCache>,
|
||||||
pub(super) blend_buffers: RefCell<AHashMap<(u32, u32), Weak<VulkanImage>>>,
|
pub(super) blend_buffers: RefCell<AHashMap<(u32, u32), Weak<VulkanImage>>>,
|
||||||
pub(super) shader_buffer_cache: Rc<VulkanBufferCache>,
|
pub(super) shader_buffer_cache: Rc<VulkanBufferCache>,
|
||||||
|
pub(super) uniform_buffer_cache: Rc<VulkanBufferCache>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct CachedCommandBuffers {
|
pub(super) struct CachedCommandBuffers {
|
||||||
|
|
@ -159,7 +161,7 @@ pub(super) struct Memory {
|
||||||
wait_semaphore_infos: Vec<SemaphoreSubmitInfo<'static>>,
|
wait_semaphore_infos: Vec<SemaphoreSubmitInfo<'static>>,
|
||||||
release_fence: Option<Rc<VulkanFence>>,
|
release_fence: Option<Rc<VulkanFence>>,
|
||||||
release_sync_file: Option<SyncFile>,
|
release_sync_file: Option<SyncFile>,
|
||||||
used_buffers: ArrayVec<VulkanBuffer, 3>,
|
used_buffers: ArrayVec<VulkanBuffer, 4>,
|
||||||
paint_bounds: StaticMap<RenderPass, Option<PaintRegion>>,
|
paint_bounds: StaticMap<RenderPass, Option<PaintRegion>>,
|
||||||
paint_regions: StaticMap<RenderPass, Vec<PaintRegion>>,
|
paint_regions: StaticMap<RenderPass, Vec<PaintRegion>>,
|
||||||
clear_rects: StaticMap<RenderPass, Vec<ClearRect>>,
|
clear_rects: StaticMap<RenderPass, Vec<ClearRect>>,
|
||||||
|
|
@ -175,6 +177,9 @@ pub(super) struct Memory {
|
||||||
data_buffer: Vec<u8>,
|
data_buffer: Vec<u8>,
|
||||||
out_address: DeviceAddress,
|
out_address: DeviceAddress,
|
||||||
color_transforms: ColorTransforms,
|
color_transforms: ColorTransforms,
|
||||||
|
uniform_buffer_writer: GenericBufferWriter,
|
||||||
|
uniform_buffer_descriptor_cache: Option<Box<[u8]>>,
|
||||||
|
blend_buffer_descriptor_buffer_offset: DeviceAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Point = [[f32; 2]; 4];
|
type Point = [[f32; 2]; 4];
|
||||||
|
|
@ -196,6 +201,8 @@ struct VulkanTexOp {
|
||||||
range_address: DeviceAddress,
|
range_address: DeviceAddress,
|
||||||
instances: u32,
|
instances: u32,
|
||||||
tex_cd: Rc<ColorDescription>,
|
tex_cd: Rc<ColorDescription>,
|
||||||
|
color_management_data_address: Option<DeviceAddress>,
|
||||||
|
resource_descriptor_buffer_offset: DeviceAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VulkanFillOp {
|
struct VulkanFillOp {
|
||||||
|
|
@ -230,7 +237,7 @@ pub(super) struct PendingFrame {
|
||||||
wait_semaphores: Cell<Vec<Rc<VulkanSemaphore>>>,
|
wait_semaphores: Cell<Vec<Rc<VulkanSemaphore>>>,
|
||||||
waiter: Cell<Option<SpawnedFuture<()>>>,
|
waiter: Cell<Option<SpawnedFuture<()>>>,
|
||||||
_release_fence: Option<Rc<VulkanFence>>,
|
_release_fence: Option<Rc<VulkanFence>>,
|
||||||
_used_buffers: ArrayVec<VulkanBuffer, 3>,
|
_used_buffers: ArrayVec<VulkanBuffer, 4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type FillPipelines = Rc<StaticMap<TexSourceType, Rc<VulkanPipeline>>>;
|
type FillPipelines = Rc<StaticMap<TexSourceType, Rc<VulkanPipeline>>>;
|
||||||
|
|
@ -240,6 +247,7 @@ struct TexPipelineKey {
|
||||||
tex_copy_type: TexCopyType,
|
tex_copy_type: TexCopyType,
|
||||||
tex_source_type: TexSourceType,
|
tex_source_type: TexSourceType,
|
||||||
eotf: TransferFunction,
|
eotf: TransferFunction,
|
||||||
|
has_color_management_data: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct TexPipelines {
|
pub(super) struct TexPipelines {
|
||||||
|
|
@ -338,7 +346,13 @@ impl VulkanDevice {
|
||||||
let shader_buffer_cache = {
|
let shader_buffer_cache = {
|
||||||
// TODO: https://github.com/KhronosGroup/Vulkan-Samples/issues/1286
|
// TODO: https://github.com/KhronosGroup/Vulkan-Samples/issues/1286
|
||||||
let usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS | BufferUsageFlags::STORAGE_BUFFER;
|
let usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS | BufferUsageFlags::STORAGE_BUFFER;
|
||||||
VulkanBufferCache::new(self, &allocator, usage)
|
let align = 8;
|
||||||
|
VulkanBufferCache::new(self, &allocator, usage, align)
|
||||||
|
};
|
||||||
|
let uniform_buffer_cache = {
|
||||||
|
let usage = BufferUsageFlags::SHADER_DEVICE_ADDRESS | BufferUsageFlags::UNIFORM_BUFFER;
|
||||||
|
let align = align_of::<TexColorManagementData>() as DeviceSize;
|
||||||
|
VulkanBufferCache::new(self, &allocator, usage, align)
|
||||||
};
|
};
|
||||||
let render = Rc::new(VulkanRenderer {
|
let render = Rc::new(VulkanRenderer {
|
||||||
formats: Rc::new(formats),
|
formats: Rc::new(formats),
|
||||||
|
|
@ -374,6 +388,7 @@ impl VulkanDevice {
|
||||||
resource_descriptor_buffer_cache,
|
resource_descriptor_buffer_cache,
|
||||||
blend_buffers: Default::default(),
|
blend_buffers: Default::default(),
|
||||||
shader_buffer_cache,
|
shader_buffer_cache,
|
||||||
|
uniform_buffer_cache,
|
||||||
});
|
});
|
||||||
Ok(render)
|
Ok(render)
|
||||||
}
|
}
|
||||||
|
|
@ -404,6 +419,7 @@ impl VulkanRenderer {
|
||||||
eotf: TF_LINEAR,
|
eotf: TF_LINEAR,
|
||||||
oetf: TF_LINEAR,
|
oetf: TF_LINEAR,
|
||||||
descriptor_set_layouts: Default::default(),
|
descriptor_set_layouts: Default::default(),
|
||||||
|
has_color_management_data: false,
|
||||||
};
|
};
|
||||||
self.device.create_pipeline2(info, push_size)
|
self.device.create_pipeline2(info, push_size)
|
||||||
};
|
};
|
||||||
|
|
@ -441,11 +457,13 @@ impl VulkanRenderer {
|
||||||
tex_cd: &ColorDescription,
|
tex_cd: &ColorDescription,
|
||||||
tex_copy_type: TexCopyType,
|
tex_copy_type: TexCopyType,
|
||||||
tex_source_type: TexSourceType,
|
tex_source_type: TexSourceType,
|
||||||
|
has_color_management_data: bool,
|
||||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||||
let key = TexPipelineKey {
|
let key = TexPipelineKey {
|
||||||
tex_copy_type,
|
tex_copy_type,
|
||||||
tex_source_type,
|
tex_source_type,
|
||||||
eotf: tex_cd.transfer_function,
|
eotf: tex_cd.transfer_function,
|
||||||
|
has_color_management_data,
|
||||||
};
|
};
|
||||||
if let Some(pl) = pipelines.pipelines.get(&key) {
|
if let Some(pl) = pipelines.pipelines.get(&key) {
|
||||||
return Ok(pl);
|
return Ok(pl);
|
||||||
|
|
@ -473,6 +491,7 @@ impl VulkanRenderer {
|
||||||
eotf: key.eotf.to_vulkan(),
|
eotf: key.eotf.to_vulkan(),
|
||||||
oetf: pipelines.oetf.to_vulkan(),
|
oetf: pipelines.oetf.to_vulkan(),
|
||||||
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
||||||
|
has_color_management_data,
|
||||||
};
|
};
|
||||||
let pl = self.device.create_pipeline2(info, push_size)?;
|
let pl = self.device.create_pipeline2(info, push_size)?;
|
||||||
pipelines.pipelines.set(key, pl.clone());
|
pipelines.pipelines.set(key, pl.clone());
|
||||||
|
|
@ -507,6 +526,7 @@ impl VulkanRenderer {
|
||||||
eotf: key.eotf.to_vulkan(),
|
eotf: key.eotf.to_vulkan(),
|
||||||
oetf: fb_cd.transfer_function.to_vulkan(),
|
oetf: fb_cd.transfer_function.to_vulkan(),
|
||||||
descriptor_set_layouts,
|
descriptor_set_layouts,
|
||||||
|
has_color_management_data: false,
|
||||||
})?;
|
})?;
|
||||||
pipelines.set(key, out.clone());
|
pipelines.set(key, out.clone());
|
||||||
Ok(out)
|
Ok(out)
|
||||||
|
|
@ -525,7 +545,6 @@ impl VulkanRenderer {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
zone!("create_descriptor_buffers");
|
zone!("create_descriptor_buffers");
|
||||||
let version = self.allocate_point();
|
|
||||||
let memory = &mut *self.memory.borrow_mut();
|
let memory = &mut *self.memory.borrow_mut();
|
||||||
let sampler_writer = &mut memory.sampler_descriptor_buffer_writer;
|
let sampler_writer = &mut memory.sampler_descriptor_buffer_writer;
|
||||||
sampler_writer.clear();
|
sampler_writer.clear();
|
||||||
|
|
@ -538,30 +557,47 @@ impl VulkanRenderer {
|
||||||
}
|
}
|
||||||
let resource_writer = &mut memory.resource_descriptor_buffer_writer;
|
let resource_writer = &mut memory.resource_descriptor_buffer_writer;
|
||||||
resource_writer.clear();
|
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()
|
||||||
|
});
|
||||||
if let Some(bb) = bb {
|
if let Some(bb) = bb {
|
||||||
let layout = self.out_descriptor_set_layout.as_ref().unwrap();
|
let layout = self.out_descriptor_set_layout.as_ref().unwrap();
|
||||||
let offset = resource_writer.next_offset();
|
memory.blend_buffer_descriptor_buffer_offset = resource_writer.next_offset();
|
||||||
bb.descriptor_buffer_offset.set(offset);
|
|
||||||
let mut writer = resource_writer.add_set(layout);
|
let mut writer = resource_writer.add_set(layout);
|
||||||
writer.write(layout.offsets[0], &bb.sampled_image_descriptor);
|
writer.write(layout.offsets[0], &bb.sampled_image_descriptor);
|
||||||
}
|
}
|
||||||
let tex_descriptor_set_layout = &self.tex_descriptor_set_layouts[1];
|
let tex_descriptor_set_layout = &self.tex_descriptor_set_layouts[1];
|
||||||
for pass in RenderPass::variants() {
|
for pass in RenderPass::variants() {
|
||||||
for cmd in &memory.ops[pass] {
|
for cmd in &mut memory.ops[pass] {
|
||||||
let VulkanOp::Tex(c) = cmd else {
|
let VulkanOp::Tex(c) = cmd else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let tex = &c.tex;
|
let tex = &c.tex;
|
||||||
if tex.descriptor_buffer_version.replace(version) == version {
|
c.resource_descriptor_buffer_offset = resource_writer.next_offset();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let offset = resource_writer.next_offset();
|
|
||||||
tex.descriptor_buffer_offset.set(offset);
|
|
||||||
let mut writer = resource_writer.add_set(tex_descriptor_set_layout);
|
let mut writer = resource_writer.add_set(tex_descriptor_set_layout);
|
||||||
writer.write(
|
writer.write(
|
||||||
tex_descriptor_set_layout.offsets[0],
|
tex_descriptor_set_layout.offsets[0],
|
||||||
&tex.sampled_image_descriptor,
|
&tex.sampled_image_descriptor,
|
||||||
);
|
);
|
||||||
|
if let Some(addr) = c.color_management_data_address {
|
||||||
|
let uniform_buffer = DescriptorAddressInfoEXT::default()
|
||||||
|
.address(addr)
|
||||||
|
.range(size_of::<TexColorManagementData>() as _);
|
||||||
|
let info = DescriptorGetInfoEXT::default()
|
||||||
|
.ty(DescriptorType::UNIFORM_BUFFER)
|
||||||
|
.data(DescriptorDataEXT {
|
||||||
|
p_uniform_buffer: &uniform_buffer,
|
||||||
|
});
|
||||||
|
unsafe {
|
||||||
|
db.get_descriptor(&info, uniform_buffer_descriptor_cache);
|
||||||
|
}
|
||||||
|
writer.write(
|
||||||
|
tex_descriptor_set_layout.offsets[1],
|
||||||
|
uniform_buffer_descriptor_cache,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut infos = ArrayVec::<_, 2>::new();
|
let mut infos = ArrayVec::<_, 2>::new();
|
||||||
|
|
@ -569,12 +605,7 @@ impl VulkanRenderer {
|
||||||
(&sampler_writer, &self.sampler_descriptor_buffer_cache),
|
(&sampler_writer, &self.sampler_descriptor_buffer_cache),
|
||||||
(&resource_writer, &self.resource_descriptor_buffer_cache),
|
(&resource_writer, &self.resource_descriptor_buffer_cache),
|
||||||
] {
|
] {
|
||||||
let mut min_alignment = 1;
|
let buffer = cache.allocate(writer.len() as DeviceSize)?;
|
||||||
if self.device.is_anv {
|
|
||||||
// https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33903
|
|
||||||
min_alignment = 4096;
|
|
||||||
}
|
|
||||||
let buffer = cache.allocate(writer.len() as DeviceSize, min_alignment)?;
|
|
||||||
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
||||||
ptr::copy_nonoverlapping(writer.as_ptr(), ptr, writer.len())
|
ptr::copy_nonoverlapping(writer.as_ptr(), ptr, writer.len())
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -607,6 +638,7 @@ impl VulkanRenderer {
|
||||||
memory.tex_targets.clear();
|
memory.tex_targets.clear();
|
||||||
memory.fill_targets.clear();
|
memory.fill_targets.clear();
|
||||||
memory.data_buffer.clear();
|
memory.data_buffer.clear();
|
||||||
|
memory.uniform_buffer_writer.clear();
|
||||||
memory.color_transforms.map.clear();
|
memory.color_transforms.map.clear();
|
||||||
let sync = |memory: &mut Memory| {
|
let sync = |memory: &mut Memory| {
|
||||||
for pass in RenderPass::variants() {
|
for pass in RenderPass::variants() {
|
||||||
|
|
@ -751,6 +783,16 @@ impl VulkanRenderer {
|
||||||
true => TexSourceType::HasAlpha,
|
true => TexSourceType::HasAlpha,
|
||||||
false => TexSourceType::Opaque,
|
false => TexSourceType::Opaque,
|
||||||
};
|
};
|
||||||
|
let target_cd = match pass {
|
||||||
|
RenderPass::BlendBuffer => blend_cd,
|
||||||
|
RenderPass::FrameBuffer => fb_cd,
|
||||||
|
};
|
||||||
|
let color_management_data_address = memory.color_transforms.get_offset(
|
||||||
|
&ct.cd.linear,
|
||||||
|
target_cd,
|
||||||
|
self.device.uniform_buffer_offset_mask,
|
||||||
|
&mut memory.uniform_buffer_writer,
|
||||||
|
);
|
||||||
ops.push(VulkanOp::Tex(VulkanTexOp {
|
ops.push(VulkanOp::Tex(VulkanTexOp {
|
||||||
tex: tex.clone(),
|
tex: tex.clone(),
|
||||||
range: lo..hi,
|
range: lo..hi,
|
||||||
|
|
@ -763,6 +805,8 @@ impl VulkanRenderer {
|
||||||
range_address: 0,
|
range_address: 0,
|
||||||
instances: 0,
|
instances: 0,
|
||||||
tex_cd: ct.cd.clone(),
|
tex_cd: ct.cd.clone(),
|
||||||
|
color_management_data_address,
|
||||||
|
resource_descriptor_buffer_offset: 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -792,7 +836,7 @@ impl VulkanRenderer {
|
||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let buffer = self.shader_buffer_cache.allocate(buf.len() as _, 8)?;
|
let buffer = self.shader_buffer_cache.allocate(buf.len() as _)?;
|
||||||
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
||||||
ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
|
ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -813,6 +857,33 @@ impl VulkanRenderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_uniform_buffer(&self) -> Result<(), VulkanError> {
|
||||||
|
if self.device.descriptor_buffer.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
zone!("create_uniform_buffer");
|
||||||
|
let memory = &mut *self.memory.borrow_mut();
|
||||||
|
let buf = &memory.uniform_buffer_writer;
|
||||||
|
if buf.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let buffer = self.uniform_buffer_cache.allocate(buf.len() as _)?;
|
||||||
|
buffer.buffer.allocation.upload(|ptr, _| unsafe {
|
||||||
|
ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buf.len());
|
||||||
|
})?;
|
||||||
|
for ops in memory.ops.values_mut() {
|
||||||
|
for op in ops {
|
||||||
|
if let VulkanOp::Tex(c) = op {
|
||||||
|
if let Some(addr) = &mut c.color_management_data_address {
|
||||||
|
*addr += buffer.buffer.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memory.used_buffers.push(buffer);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_memory(&self) {
|
fn collect_memory(&self) {
|
||||||
zone!("collect_memory");
|
zone!("collect_memory");
|
||||||
let memory = &mut *self.memory.borrow_mut();
|
let memory = &mut *self.memory.borrow_mut();
|
||||||
|
|
@ -1126,6 +1197,7 @@ impl VulkanRenderer {
|
||||||
&c.tex_cd,
|
&c.tex_cd,
|
||||||
c.copy_type,
|
c.copy_type,
|
||||||
c.source_type,
|
c.source_type,
|
||||||
|
c.color_management_data_address.is_some(),
|
||||||
)?;
|
)?;
|
||||||
bind(&pipeline);
|
bind(&pipeline);
|
||||||
let image_info = DescriptorImageInfo::default()
|
let image_info = DescriptorImageInfo::default()
|
||||||
|
|
@ -1143,7 +1215,7 @@ impl VulkanRenderer {
|
||||||
pipeline.pipeline_layout,
|
pipeline.pipeline_layout,
|
||||||
0,
|
0,
|
||||||
&[0, 1],
|
&[0, 1],
|
||||||
&[0, tex.descriptor_buffer_offset.get()],
|
&[0, c.resource_descriptor_buffer_offset],
|
||||||
);
|
);
|
||||||
dev.cmd_push_constants(
|
dev.cmd_push_constants(
|
||||||
buf,
|
buf,
|
||||||
|
|
@ -1219,7 +1291,6 @@ impl VulkanRenderer {
|
||||||
buf: CommandBuffer,
|
buf: CommandBuffer,
|
||||||
fb: &VulkanImage,
|
fb: &VulkanImage,
|
||||||
fb_cd: &ColorDescription,
|
fb_cd: &ColorDescription,
|
||||||
bb: &VulkanImage,
|
|
||||||
bb_cd: &ColorDescription,
|
bb_cd: &ColorDescription,
|
||||||
) -> Result<(), VulkanError> {
|
) -> Result<(), VulkanError> {
|
||||||
zone!("blend_buffer_copy");
|
zone!("blend_buffer_copy");
|
||||||
|
|
@ -1239,7 +1310,7 @@ impl VulkanRenderer {
|
||||||
pipeline.pipeline_layout,
|
pipeline.pipeline_layout,
|
||||||
0,
|
0,
|
||||||
&[1],
|
&[1],
|
||||||
&[bb.descriptor_buffer_offset.get()],
|
&[memory.blend_buffer_descriptor_buffer_offset],
|
||||||
);
|
);
|
||||||
dev.cmd_push_constants(
|
dev.cmd_push_constants(
|
||||||
buf,
|
buf,
|
||||||
|
|
@ -1808,6 +1879,7 @@ impl VulkanRenderer {
|
||||||
let buf = self.gfx_command_buffers.allocate()?;
|
let buf = self.gfx_command_buffers.allocate()?;
|
||||||
self.convert_ops(opts, bb_cd, fb_cd);
|
self.convert_ops(opts, bb_cd, fb_cd);
|
||||||
self.create_data_buffer()?;
|
self.create_data_buffer()?;
|
||||||
|
self.create_uniform_buffer()?;
|
||||||
self.collect_memory();
|
self.collect_memory();
|
||||||
self.begin_command_buffer(buf.buffer)?;
|
self.begin_command_buffer(buf.buffer)?;
|
||||||
self.create_descriptor_buffers(buf.buffer, bb)?;
|
self.create_descriptor_buffers(buf.buffer, bb)?;
|
||||||
|
|
@ -1827,8 +1899,8 @@ impl VulkanRenderer {
|
||||||
let rp = RenderPass::FrameBuffer;
|
let rp = RenderPass::FrameBuffer;
|
||||||
self.begin_rendering(buf.buffer, fb, clear, clear_cd, rp, fb_cd);
|
self.begin_rendering(buf.buffer, fb, clear, clear_cd, rp, fb_cd);
|
||||||
self.record_draws(buf.buffer, fb, rp, fb_cd)?;
|
self.record_draws(buf.buffer, fb, rp, fb_cd)?;
|
||||||
if let Some(bb) = bb {
|
if bb.is_some() {
|
||||||
self.blend_buffer_copy(buf.buffer, fb, fb_cd, bb, bb_cd)?;
|
self.blend_buffer_copy(buf.buffer, fb, fb_cd, bb_cd)?;
|
||||||
}
|
}
|
||||||
self.end_rendering(buf.buffer);
|
self.end_rendering(buf.buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -2055,6 +2127,7 @@ struct ColorTransforms {
|
||||||
|
|
||||||
struct ColorTransform {
|
struct ColorTransform {
|
||||||
matrix: ColorMatrix,
|
matrix: ColorMatrix,
|
||||||
|
offset: Option<DeviceSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorTransforms {
|
impl ColorTransforms {
|
||||||
|
|
@ -2070,7 +2143,10 @@ impl ColorTransforms {
|
||||||
Entry::Occupied(o) => o.into_mut(),
|
Entry::Occupied(o) => o.into_mut(),
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
let matrix = src.color_transform(&dst.linear);
|
let matrix = src.color_transform(&dst.linear);
|
||||||
let ct = ColorTransform { matrix };
|
let ct = ColorTransform {
|
||||||
|
matrix,
|
||||||
|
offset: None,
|
||||||
|
};
|
||||||
e.insert(ct)
|
e.insert(ct)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2088,4 +2164,22 @@ impl ColorTransforms {
|
||||||
};
|
};
|
||||||
color
|
color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_offset(
|
||||||
|
&mut self,
|
||||||
|
src: &LinearColorDescription,
|
||||||
|
dst: &ColorDescription,
|
||||||
|
uniform_buffer_offset_mask: DeviceSize,
|
||||||
|
writer: &mut GenericBufferWriter,
|
||||||
|
) -> Option<DeviceSize> {
|
||||||
|
let ct = self.get_or_create(src, dst)?;
|
||||||
|
if ct.offset.is_none() {
|
||||||
|
let data = TexColorManagementData {
|
||||||
|
matrix: ct.matrix.to_f32(),
|
||||||
|
};
|
||||||
|
let offset = writer.write(uniform_buffer_offset_mask, &data);
|
||||||
|
ct.offset = Some(offset);
|
||||||
|
}
|
||||||
|
ct.offset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,14 @@ pub struct TexPushConstants {
|
||||||
|
|
||||||
unsafe impl Packed for TexPushConstants {}
|
unsafe impl Packed for TexPushConstants {}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[repr(C, align(16))]
|
||||||
|
pub struct TexColorManagementData {
|
||||||
|
pub matrix: [[f32; 4]; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Packed for TexColorManagementData {}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct LegacyTexPushConstants {
|
pub struct LegacyTexPushConstants {
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,6 @@ layout(constant_id = 0) const bool src_has_alpha = false;
|
||||||
layout(constant_id = 1) const bool has_alpha_multiplier = false;
|
layout(constant_id = 1) const bool has_alpha_multiplier = false;
|
||||||
layout(constant_id = 2) const uint eotf = 0;
|
layout(constant_id = 2) const uint eotf = 0;
|
||||||
layout(constant_id = 3) const uint oetf = 0;
|
layout(constant_id = 3) const uint oetf = 0;
|
||||||
|
layout(constant_id = 4) const bool has_matrix = false;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,35 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
#extension GL_EXT_scalar_block_layout : require
|
||||||
|
|
||||||
#include "frag_spec_const.glsl"
|
#include "frag_spec_const.glsl"
|
||||||
#include "transfer_functions.glsl"
|
#include "transfer_functions.glsl"
|
||||||
#include "tex.common.glsl"
|
#include "tex.common.glsl"
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform sampler sam;
|
layout(set = 0, binding = 0) uniform sampler sam;
|
||||||
layout(set = 1, binding = 0) uniform texture2D tex;
|
layout(set = 1, binding = 0) uniform texture2D tex;
|
||||||
|
layout(set = 1, binding = 1, row_major, std430) uniform ColorManagementData {
|
||||||
|
mat4x4 matrix;
|
||||||
|
} cm_data;
|
||||||
layout(location = 0) in vec2 tex_pos;
|
layout(location = 0) in vec2 tex_pos;
|
||||||
layout(location = 0) out vec4 out_color;
|
layout(location = 0) out vec4 out_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 c = textureLod(sampler2D(tex, sam), tex_pos, 0);
|
vec4 c = textureLod(sampler2D(tex, sam), tex_pos, 0);
|
||||||
if (eotf != oetf) {
|
if (eotf != oetf || has_matrix) {
|
||||||
|
vec3 rgb = c.rgb;
|
||||||
if (src_has_alpha) {
|
if (src_has_alpha) {
|
||||||
c.rgb /= mix(c.a, 1.0, c.a == 0.0);
|
rgb /= mix(c.a, 1.0, c.a == 0.0);
|
||||||
}
|
}
|
||||||
c.rgb = apply_eotf(c.rgb);
|
rgb = apply_eotf(rgb);
|
||||||
c.rgb = apply_oetf(c.rgb);
|
if (has_matrix) {
|
||||||
|
rgb = (cm_data.matrix * vec4(rgb, 1.0)).rgb;
|
||||||
|
}
|
||||||
|
rgb = apply_oetf(rgb);
|
||||||
if (src_has_alpha) {
|
if (src_has_alpha) {
|
||||||
c.rgb *= c.a;
|
rgb *= c.a;
|
||||||
}
|
}
|
||||||
|
c.rgb = rgb;
|
||||||
}
|
}
|
||||||
if (has_alpha_multiplier) {
|
if (has_alpha_multiplier) {
|
||||||
if (src_has_alpha) {
|
if (src_has_alpha) {
|
||||||
|
|
|
||||||
|
|
@ -460,8 +460,6 @@ impl VulkanRenderer {
|
||||||
ty: VulkanImageMemory::Internal(shm),
|
ty: VulkanImageMemory::Internal(shm),
|
||||||
bridge: None,
|
bridge: None,
|
||||||
sampled_image_descriptor: self.sampled_image_descriptor(view),
|
sampled_image_descriptor: self.sampled_image_descriptor(view),
|
||||||
descriptor_buffer_version: Cell::new(0),
|
|
||||||
descriptor_buffer_offset: Cell::new(0),
|
|
||||||
execution_version: Cell::new(0),
|
execution_version: Cell::new(0),
|
||||||
});
|
});
|
||||||
let shm = match &img.ty {
|
let shm = match &img.ty {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue