vulkan: split renderer pipelines
This commit is contained in:
parent
ea7251d6e0
commit
9437a56807
2 changed files with 289 additions and 261 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
mod color;
|
mod color;
|
||||||
mod op;
|
mod op;
|
||||||
mod pipeline_cache;
|
mod pipeline_cache;
|
||||||
|
mod pipelines;
|
||||||
mod paint_region;
|
mod paint_region;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
|
@ -10,7 +11,7 @@ use {
|
||||||
VulkanRoundedTexOp, VulkanTexOp,
|
VulkanRoundedTexOp, VulkanTexOp,
|
||||||
},
|
},
|
||||||
paint_region::{PaintRegion, Point, constrain_to_fb},
|
paint_region::{PaintRegion, Point, constrain_to_fb},
|
||||||
pipeline_cache::{FillPipelines, OutPipelineKey, TexPipelineKey, TexPipelines},
|
pipeline_cache::{FillPipelines, OutPipelineKey, TexPipelines},
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{AsyncEngine, SpawnedFuture},
|
async_engine::{AsyncEngine, SpawnedFuture},
|
||||||
cmm::{
|
cmm::{
|
||||||
|
|
@ -19,8 +20,8 @@ use {
|
||||||
},
|
},
|
||||||
cpu_worker::PendingJob,
|
cpu_worker::PendingJob,
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, AlphaMode, BufferResv, BufferResvUser, FdSync, GfxApiOpt, GfxBlendBuffer,
|
AcquireSync, BufferResv, BufferResvUser, FdSync, GfxApiOpt, GfxBlendBuffer, GfxFormat,
|
||||||
GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync,
|
GfxTexture, GfxWriteModifier, ReleaseSync,
|
||||||
},
|
},
|
||||||
gfx_apis::vulkan::{
|
gfx_apis::vulkan::{
|
||||||
VulkanError, VulkanSync, VulkanTimelineSemaphore,
|
VulkanError, VulkanSync, VulkanTimelineSemaphore,
|
||||||
|
|
@ -30,9 +31,9 @@ use {
|
||||||
descriptor::VulkanDescriptorSetLayout,
|
descriptor::VulkanDescriptorSetLayout,
|
||||||
descriptor_buffer::VulkanDescriptorBufferWriter,
|
descriptor_buffer::VulkanDescriptorBufferWriter,
|
||||||
device::VulkanDevice,
|
device::VulkanDevice,
|
||||||
eotfs::{EOTF_LINEAR, EotfExt, VulkanEotf},
|
eotfs::VulkanEotf,
|
||||||
image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory},
|
image::{QueueFamily, QueueState, QueueTransfer, VulkanImage, VulkanImageMemory},
|
||||||
pipeline::{PipelineCreateInfo, VulkanPipeline},
|
pipeline::VulkanPipeline,
|
||||||
sampler::VulkanSampler,
|
sampler::VulkanSampler,
|
||||||
semaphore::VulkanSemaphore,
|
semaphore::VulkanSemaphore,
|
||||||
shaders::{
|
shaders::{
|
||||||
|
|
@ -78,7 +79,7 @@ use {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt},
|
isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt},
|
||||||
linearize::{Linearize, LinearizeExt, StaticMap, static_map},
|
linearize::{Linearize, LinearizeExt, StaticMap},
|
||||||
std::{
|
std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
|
@ -378,261 +379,6 @@ impl VulkanDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanRenderer {
|
impl VulkanRenderer {
|
||||||
fn get_or_create_fill_pipelines(
|
|
||||||
&self,
|
|
||||||
format: vk::Format,
|
|
||||||
) -> Result<FillPipelines, VulkanError> {
|
|
||||||
if let Some(pl) = self.fill_pipelines.get(&format) {
|
|
||||||
return Ok(pl);
|
|
||||||
}
|
|
||||||
let create_fill_pipeline = |src_has_alpha| {
|
|
||||||
let push_size = if self.device.descriptor_buffer.is_some() {
|
|
||||||
size_of::<FillPushConstants>()
|
|
||||||
} else {
|
|
||||||
size_of::<LegacyFillPushConstants>()
|
|
||||||
};
|
|
||||||
let info = PipelineCreateInfo {
|
|
||||||
format,
|
|
||||||
vert: self.fill_vert_shader.clone(),
|
|
||||||
frag: self.fill_frag_shader.clone(),
|
|
||||||
blend: src_has_alpha,
|
|
||||||
src_has_alpha,
|
|
||||||
has_alpha_mult: false,
|
|
||||||
alpha_mode: AlphaMode::PremultipliedOptical,
|
|
||||||
// all transformations are applied in the compositor
|
|
||||||
eotf: EOTF_LINEAR,
|
|
||||||
inv_eotf: EOTF_LINEAR,
|
|
||||||
descriptor_set_layouts: Default::default(),
|
|
||||||
has_color_management_data: false,
|
|
||||||
};
|
|
||||||
self.device.create_pipeline2(info, push_size)
|
|
||||||
};
|
|
||||||
let fill_pipelines = Rc::new(static_map! {
|
|
||||||
TexSourceType::HasAlpha => create_fill_pipeline(true)?,
|
|
||||||
TexSourceType::Opaque => create_fill_pipeline(false)?,
|
|
||||||
});
|
|
||||||
self.fill_pipelines.set(format, fill_pipelines.clone());
|
|
||||||
Ok(fill_pipelines)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_rounded_fill_pipelines(
|
|
||||||
&self,
|
|
||||||
format: vk::Format,
|
|
||||||
) -> Result<FillPipelines, VulkanError> {
|
|
||||||
if let Some(pl) = self.rounded_fill_pipelines.get(&format) {
|
|
||||||
return Ok(pl);
|
|
||||||
}
|
|
||||||
let create_pipeline = |src_has_alpha| {
|
|
||||||
let push_size = if self.device.descriptor_buffer.is_some() {
|
|
||||||
size_of::<RoundedFillPushConstants>()
|
|
||||||
} else {
|
|
||||||
size_of::<LegacyRoundedFillPushConstants>()
|
|
||||||
};
|
|
||||||
let info = PipelineCreateInfo {
|
|
||||||
format,
|
|
||||||
vert: self.rounded_fill_vert_shader.clone(),
|
|
||||||
frag: self.rounded_fill_frag_shader.clone(),
|
|
||||||
blend: src_has_alpha,
|
|
||||||
src_has_alpha,
|
|
||||||
has_alpha_mult: false,
|
|
||||||
alpha_mode: AlphaMode::PremultipliedOptical,
|
|
||||||
eotf: EOTF_LINEAR,
|
|
||||||
inv_eotf: EOTF_LINEAR,
|
|
||||||
descriptor_set_layouts: Default::default(),
|
|
||||||
has_color_management_data: false,
|
|
||||||
};
|
|
||||||
self.device.create_pipeline2(info, push_size)
|
|
||||||
};
|
|
||||||
let pipelines = Rc::new(static_map! {
|
|
||||||
TexSourceType::HasAlpha => create_pipeline(true)?,
|
|
||||||
TexSourceType::Opaque => create_pipeline(false)?,
|
|
||||||
});
|
|
||||||
self.rounded_fill_pipelines.set(format, pipelines.clone());
|
|
||||||
Ok(pipelines)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_rounded_tex_pipelines(
|
|
||||||
&self,
|
|
||||||
format: vk::Format,
|
|
||||||
target_cd: &ColorDescription,
|
|
||||||
) -> Rc<TexPipelines> {
|
|
||||||
let eotf = target_cd.eotf.to_vulkan();
|
|
||||||
let pipelines = &self.rounded_tex_pipelines[eotf];
|
|
||||||
match pipelines.get(&format) {
|
|
||||||
Some(pl) => pl,
|
|
||||||
_ => {
|
|
||||||
let pl = Rc::new(TexPipelines {
|
|
||||||
format,
|
|
||||||
eotf,
|
|
||||||
pipelines: Default::default(),
|
|
||||||
});
|
|
||||||
pipelines.set(format, pl.clone());
|
|
||||||
pl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_rounded_tex_pipeline(
|
|
||||||
&self,
|
|
||||||
pipelines: &TexPipelines,
|
|
||||||
tex_cd: &ColorDescription,
|
|
||||||
tex_copy_type: TexCopyType,
|
|
||||||
tex_source_type: TexSourceType,
|
|
||||||
mut tex_alpha_mode: AlphaMode,
|
|
||||||
has_color_management_data: bool,
|
|
||||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
|
||||||
if tex_source_type == TexSourceType::Opaque {
|
|
||||||
tex_alpha_mode = AlphaMode::PremultipliedElectrical;
|
|
||||||
}
|
|
||||||
let key = TexPipelineKey {
|
|
||||||
tex_copy_type,
|
|
||||||
tex_source_type,
|
|
||||||
tex_alpha_mode,
|
|
||||||
eotf: tex_cd.eotf.to_vulkan(),
|
|
||||||
has_color_management_data,
|
|
||||||
};
|
|
||||||
if let Some(pl) = pipelines.pipelines.get(&key) {
|
|
||||||
return Ok(pl);
|
|
||||||
}
|
|
||||||
let has_alpha_mult = match tex_copy_type {
|
|
||||||
TexCopyType::Identity => false,
|
|
||||||
TexCopyType::Multiply => true,
|
|
||||||
};
|
|
||||||
let push_size = if self.device.descriptor_buffer.is_some() {
|
|
||||||
size_of::<RoundedTexPushConstants>()
|
|
||||||
} else {
|
|
||||||
size_of::<LegacyRoundedTexPushConstants>()
|
|
||||||
};
|
|
||||||
let info = PipelineCreateInfo {
|
|
||||||
format: pipelines.format,
|
|
||||||
vert: self.rounded_tex_vert_shader.clone(),
|
|
||||||
frag: self.rounded_tex_frag_shader.clone(),
|
|
||||||
blend: true, // always blend since corners are transparent
|
|
||||||
src_has_alpha: true, // rounding makes everything have alpha
|
|
||||||
has_alpha_mult,
|
|
||||||
alpha_mode: key.tex_alpha_mode,
|
|
||||||
eotf: key.eotf.to_vulkan(),
|
|
||||||
inv_eotf: pipelines.eotf.to_vulkan(),
|
|
||||||
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
|
||||||
has_color_management_data,
|
|
||||||
};
|
|
||||||
let pl = self.device.create_pipeline2(info, push_size)?;
|
|
||||||
pipelines.pipelines.set(key, pl.clone());
|
|
||||||
Ok(pl)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_tex_pipelines(
|
|
||||||
&self,
|
|
||||||
format: vk::Format,
|
|
||||||
target_cd: &ColorDescription,
|
|
||||||
) -> Rc<TexPipelines> {
|
|
||||||
let eotf = target_cd.eotf.to_vulkan();
|
|
||||||
let pipelines = &self.tex_pipelines[eotf];
|
|
||||||
match pipelines.get(&format) {
|
|
||||||
Some(pl) => pl,
|
|
||||||
_ => {
|
|
||||||
let pl = Rc::new(TexPipelines {
|
|
||||||
format,
|
|
||||||
eotf,
|
|
||||||
pipelines: Default::default(),
|
|
||||||
});
|
|
||||||
pipelines.set(format, pl.clone());
|
|
||||||
pl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_tex_pipeline(
|
|
||||||
&self,
|
|
||||||
pipelines: &TexPipelines,
|
|
||||||
tex_cd: &ColorDescription,
|
|
||||||
tex_copy_type: TexCopyType,
|
|
||||||
tex_source_type: TexSourceType,
|
|
||||||
mut tex_alpha_mode: AlphaMode,
|
|
||||||
has_color_management_data: bool,
|
|
||||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
|
||||||
if tex_source_type == TexSourceType::Opaque {
|
|
||||||
tex_alpha_mode = AlphaMode::PremultipliedElectrical;
|
|
||||||
}
|
|
||||||
let key = TexPipelineKey {
|
|
||||||
tex_copy_type,
|
|
||||||
tex_source_type,
|
|
||||||
tex_alpha_mode,
|
|
||||||
eotf: tex_cd.eotf.to_vulkan(),
|
|
||||||
has_color_management_data,
|
|
||||||
};
|
|
||||||
if let Some(pl) = pipelines.pipelines.get(&key) {
|
|
||||||
return Ok(pl);
|
|
||||||
}
|
|
||||||
let src_has_alpha = match tex_source_type {
|
|
||||||
TexSourceType::Opaque => false,
|
|
||||||
TexSourceType::HasAlpha => true,
|
|
||||||
};
|
|
||||||
let has_alpha_mult = match tex_copy_type {
|
|
||||||
TexCopyType::Identity => false,
|
|
||||||
TexCopyType::Multiply => true,
|
|
||||||
};
|
|
||||||
let push_size = if self.device.descriptor_buffer.is_some() {
|
|
||||||
size_of::<TexPushConstants>()
|
|
||||||
} else {
|
|
||||||
size_of::<LegacyTexPushConstants>()
|
|
||||||
};
|
|
||||||
let info = PipelineCreateInfo {
|
|
||||||
format: pipelines.format,
|
|
||||||
vert: self.tex_vert_shader.clone(),
|
|
||||||
frag: self.tex_frag_shader.clone(),
|
|
||||||
blend: src_has_alpha || has_alpha_mult,
|
|
||||||
src_has_alpha,
|
|
||||||
has_alpha_mult,
|
|
||||||
alpha_mode: key.tex_alpha_mode,
|
|
||||||
eotf: key.eotf.to_vulkan(),
|
|
||||||
inv_eotf: pipelines.eotf.to_vulkan(),
|
|
||||||
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
|
||||||
has_color_management_data,
|
|
||||||
};
|
|
||||||
let pl = self.device.create_pipeline2(info, push_size)?;
|
|
||||||
pipelines.pipelines.set(key, pl.clone());
|
|
||||||
Ok(pl)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_out_pipeline(
|
|
||||||
&self,
|
|
||||||
format: vk::Format,
|
|
||||||
bb_cd: &ColorDescription,
|
|
||||||
fb_cd: &ColorDescription,
|
|
||||||
has_color_management_data: bool,
|
|
||||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
|
||||||
let key = OutPipelineKey {
|
|
||||||
format,
|
|
||||||
eotf: bb_cd.eotf.to_vulkan(),
|
|
||||||
has_color_management_data,
|
|
||||||
};
|
|
||||||
let fb_eotf = fb_cd.eotf.to_vulkan();
|
|
||||||
let pipelines = &self.out_pipelines[fb_eotf];
|
|
||||||
if let Some(pl) = pipelines.get(&key) {
|
|
||||||
return Ok(pl);
|
|
||||||
}
|
|
||||||
let mut descriptor_set_layouts = ArrayVec::new();
|
|
||||||
descriptor_set_layouts.push(self.out_descriptor_set_layout.clone().unwrap());
|
|
||||||
let out = self
|
|
||||||
.device
|
|
||||||
.create_pipeline::<OutPushConstants>(PipelineCreateInfo {
|
|
||||||
format: key.format,
|
|
||||||
vert: self.out_vert_shader.clone().unwrap(),
|
|
||||||
frag: self.out_frag_shader.clone().unwrap(),
|
|
||||||
blend: false,
|
|
||||||
src_has_alpha: true,
|
|
||||||
has_alpha_mult: false,
|
|
||||||
alpha_mode: AlphaMode::PremultipliedElectrical,
|
|
||||||
eotf: key.eotf.to_vulkan(),
|
|
||||||
inv_eotf: fb_eotf.to_vulkan(),
|
|
||||||
descriptor_set_layouts,
|
|
||||||
has_color_management_data,
|
|
||||||
})?;
|
|
||||||
pipelines.set(key, out.clone());
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn allocate_point(&self) -> u64 {
|
pub(super) fn allocate_point(&self) -> u64 {
|
||||||
self.last_point.fetch_add(1) + 1
|
self.last_point.fetch_add(1) + 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
282
src/gfx_apis/vulkan/renderer/pipelines.rs
Normal file
282
src/gfx_apis/vulkan/renderer/pipelines.rs
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
use {
|
||||||
|
super::{
|
||||||
|
VulkanRenderer,
|
||||||
|
op::{TexCopyType, TexSourceType},
|
||||||
|
pipeline_cache::{FillPipelines, OutPipelineKey, TexPipelineKey, TexPipelines},
|
||||||
|
},
|
||||||
|
crate::{
|
||||||
|
cmm::cmm_description::ColorDescription,
|
||||||
|
gfx_api::AlphaMode,
|
||||||
|
gfx_apis::vulkan::{
|
||||||
|
VulkanError,
|
||||||
|
eotfs::{EOTF_LINEAR, EotfExt},
|
||||||
|
pipeline::{PipelineCreateInfo, VulkanPipeline},
|
||||||
|
shaders::{
|
||||||
|
FillPushConstants, LegacyFillPushConstants, LegacyRoundedFillPushConstants,
|
||||||
|
LegacyRoundedTexPushConstants, LegacyTexPushConstants, OutPushConstants,
|
||||||
|
RoundedFillPushConstants, RoundedTexPushConstants, TexPushConstants,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
arrayvec::ArrayVec,
|
||||||
|
ash::vk,
|
||||||
|
linearize::static_map,
|
||||||
|
std::{mem::size_of, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl VulkanRenderer {
|
||||||
|
pub(super) fn get_or_create_fill_pipelines(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
) -> Result<FillPipelines, VulkanError> {
|
||||||
|
if let Some(pl) = self.fill_pipelines.get(&format) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let create_fill_pipeline = |src_has_alpha| {
|
||||||
|
let push_size = if self.device.descriptor_buffer.is_some() {
|
||||||
|
size_of::<FillPushConstants>()
|
||||||
|
} else {
|
||||||
|
size_of::<LegacyFillPushConstants>()
|
||||||
|
};
|
||||||
|
let info = PipelineCreateInfo {
|
||||||
|
format,
|
||||||
|
vert: self.fill_vert_shader.clone(),
|
||||||
|
frag: self.fill_frag_shader.clone(),
|
||||||
|
blend: src_has_alpha,
|
||||||
|
src_has_alpha,
|
||||||
|
has_alpha_mult: false,
|
||||||
|
alpha_mode: AlphaMode::PremultipliedOptical,
|
||||||
|
// all transformations are applied in the compositor
|
||||||
|
eotf: EOTF_LINEAR,
|
||||||
|
inv_eotf: EOTF_LINEAR,
|
||||||
|
descriptor_set_layouts: Default::default(),
|
||||||
|
has_color_management_data: false,
|
||||||
|
};
|
||||||
|
self.device.create_pipeline2(info, push_size)
|
||||||
|
};
|
||||||
|
let fill_pipelines = Rc::new(static_map! {
|
||||||
|
TexSourceType::HasAlpha => create_fill_pipeline(true)?,
|
||||||
|
TexSourceType::Opaque => create_fill_pipeline(false)?,
|
||||||
|
});
|
||||||
|
self.fill_pipelines.set(format, fill_pipelines.clone());
|
||||||
|
Ok(fill_pipelines)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_rounded_fill_pipelines(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
) -> Result<FillPipelines, VulkanError> {
|
||||||
|
if let Some(pl) = self.rounded_fill_pipelines.get(&format) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let create_pipeline = |src_has_alpha| {
|
||||||
|
let push_size = if self.device.descriptor_buffer.is_some() {
|
||||||
|
size_of::<RoundedFillPushConstants>()
|
||||||
|
} else {
|
||||||
|
size_of::<LegacyRoundedFillPushConstants>()
|
||||||
|
};
|
||||||
|
let info = PipelineCreateInfo {
|
||||||
|
format,
|
||||||
|
vert: self.rounded_fill_vert_shader.clone(),
|
||||||
|
frag: self.rounded_fill_frag_shader.clone(),
|
||||||
|
blend: src_has_alpha,
|
||||||
|
src_has_alpha,
|
||||||
|
has_alpha_mult: false,
|
||||||
|
alpha_mode: AlphaMode::PremultipliedOptical,
|
||||||
|
eotf: EOTF_LINEAR,
|
||||||
|
inv_eotf: EOTF_LINEAR,
|
||||||
|
descriptor_set_layouts: Default::default(),
|
||||||
|
has_color_management_data: false,
|
||||||
|
};
|
||||||
|
self.device.create_pipeline2(info, push_size)
|
||||||
|
};
|
||||||
|
let pipelines = Rc::new(static_map! {
|
||||||
|
TexSourceType::HasAlpha => create_pipeline(true)?,
|
||||||
|
TexSourceType::Opaque => create_pipeline(false)?,
|
||||||
|
});
|
||||||
|
self.rounded_fill_pipelines.set(format, pipelines.clone());
|
||||||
|
Ok(pipelines)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_rounded_tex_pipelines(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
target_cd: &ColorDescription,
|
||||||
|
) -> Rc<TexPipelines> {
|
||||||
|
let eotf = target_cd.eotf.to_vulkan();
|
||||||
|
let pipelines = &self.rounded_tex_pipelines[eotf];
|
||||||
|
match pipelines.get(&format) {
|
||||||
|
Some(pl) => pl,
|
||||||
|
_ => {
|
||||||
|
let pl = Rc::new(TexPipelines {
|
||||||
|
format,
|
||||||
|
eotf,
|
||||||
|
pipelines: Default::default(),
|
||||||
|
});
|
||||||
|
pipelines.set(format, pl.clone());
|
||||||
|
pl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_rounded_tex_pipeline(
|
||||||
|
&self,
|
||||||
|
pipelines: &TexPipelines,
|
||||||
|
tex_cd: &ColorDescription,
|
||||||
|
tex_copy_type: TexCopyType,
|
||||||
|
tex_source_type: TexSourceType,
|
||||||
|
mut tex_alpha_mode: AlphaMode,
|
||||||
|
has_color_management_data: bool,
|
||||||
|
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||||
|
if tex_source_type == TexSourceType::Opaque {
|
||||||
|
tex_alpha_mode = AlphaMode::PremultipliedElectrical;
|
||||||
|
}
|
||||||
|
let key = TexPipelineKey {
|
||||||
|
tex_copy_type,
|
||||||
|
tex_source_type,
|
||||||
|
tex_alpha_mode,
|
||||||
|
eotf: tex_cd.eotf.to_vulkan(),
|
||||||
|
has_color_management_data,
|
||||||
|
};
|
||||||
|
if let Some(pl) = pipelines.pipelines.get(&key) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let has_alpha_mult = match tex_copy_type {
|
||||||
|
TexCopyType::Identity => false,
|
||||||
|
TexCopyType::Multiply => true,
|
||||||
|
};
|
||||||
|
let push_size = if self.device.descriptor_buffer.is_some() {
|
||||||
|
size_of::<RoundedTexPushConstants>()
|
||||||
|
} else {
|
||||||
|
size_of::<LegacyRoundedTexPushConstants>()
|
||||||
|
};
|
||||||
|
let info = PipelineCreateInfo {
|
||||||
|
format: pipelines.format,
|
||||||
|
vert: self.rounded_tex_vert_shader.clone(),
|
||||||
|
frag: self.rounded_tex_frag_shader.clone(),
|
||||||
|
blend: true,
|
||||||
|
src_has_alpha: true,
|
||||||
|
has_alpha_mult,
|
||||||
|
alpha_mode: key.tex_alpha_mode,
|
||||||
|
eotf: key.eotf.to_vulkan(),
|
||||||
|
inv_eotf: pipelines.eotf.to_vulkan(),
|
||||||
|
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
||||||
|
has_color_management_data,
|
||||||
|
};
|
||||||
|
let pl = self.device.create_pipeline2(info, push_size)?;
|
||||||
|
pipelines.pipelines.set(key, pl.clone());
|
||||||
|
Ok(pl)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_tex_pipelines(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
target_cd: &ColorDescription,
|
||||||
|
) -> Rc<TexPipelines> {
|
||||||
|
let eotf = target_cd.eotf.to_vulkan();
|
||||||
|
let pipelines = &self.tex_pipelines[eotf];
|
||||||
|
match pipelines.get(&format) {
|
||||||
|
Some(pl) => pl,
|
||||||
|
_ => {
|
||||||
|
let pl = Rc::new(TexPipelines {
|
||||||
|
format,
|
||||||
|
eotf,
|
||||||
|
pipelines: Default::default(),
|
||||||
|
});
|
||||||
|
pipelines.set(format, pl.clone());
|
||||||
|
pl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_tex_pipeline(
|
||||||
|
&self,
|
||||||
|
pipelines: &TexPipelines,
|
||||||
|
tex_cd: &ColorDescription,
|
||||||
|
tex_copy_type: TexCopyType,
|
||||||
|
tex_source_type: TexSourceType,
|
||||||
|
mut tex_alpha_mode: AlphaMode,
|
||||||
|
has_color_management_data: bool,
|
||||||
|
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||||
|
if tex_source_type == TexSourceType::Opaque {
|
||||||
|
tex_alpha_mode = AlphaMode::PremultipliedElectrical;
|
||||||
|
}
|
||||||
|
let key = TexPipelineKey {
|
||||||
|
tex_copy_type,
|
||||||
|
tex_source_type,
|
||||||
|
tex_alpha_mode,
|
||||||
|
eotf: tex_cd.eotf.to_vulkan(),
|
||||||
|
has_color_management_data,
|
||||||
|
};
|
||||||
|
if let Some(pl) = pipelines.pipelines.get(&key) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let src_has_alpha = match tex_source_type {
|
||||||
|
TexSourceType::Opaque => false,
|
||||||
|
TexSourceType::HasAlpha => true,
|
||||||
|
};
|
||||||
|
let has_alpha_mult = match tex_copy_type {
|
||||||
|
TexCopyType::Identity => false,
|
||||||
|
TexCopyType::Multiply => true,
|
||||||
|
};
|
||||||
|
let push_size = if self.device.descriptor_buffer.is_some() {
|
||||||
|
size_of::<TexPushConstants>()
|
||||||
|
} else {
|
||||||
|
size_of::<LegacyTexPushConstants>()
|
||||||
|
};
|
||||||
|
let info = PipelineCreateInfo {
|
||||||
|
format: pipelines.format,
|
||||||
|
vert: self.tex_vert_shader.clone(),
|
||||||
|
frag: self.tex_frag_shader.clone(),
|
||||||
|
blend: src_has_alpha || has_alpha_mult,
|
||||||
|
src_has_alpha,
|
||||||
|
has_alpha_mult,
|
||||||
|
alpha_mode: key.tex_alpha_mode,
|
||||||
|
eotf: key.eotf.to_vulkan(),
|
||||||
|
inv_eotf: pipelines.eotf.to_vulkan(),
|
||||||
|
descriptor_set_layouts: self.tex_descriptor_set_layouts.clone(),
|
||||||
|
has_color_management_data,
|
||||||
|
};
|
||||||
|
let pl = self.device.create_pipeline2(info, push_size)?;
|
||||||
|
pipelines.pipelines.set(key, pl.clone());
|
||||||
|
Ok(pl)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_or_create_out_pipeline(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
bb_cd: &ColorDescription,
|
||||||
|
fb_cd: &ColorDescription,
|
||||||
|
has_color_management_data: bool,
|
||||||
|
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||||
|
let key = OutPipelineKey {
|
||||||
|
format,
|
||||||
|
eotf: bb_cd.eotf.to_vulkan(),
|
||||||
|
has_color_management_data,
|
||||||
|
};
|
||||||
|
let fb_eotf = fb_cd.eotf.to_vulkan();
|
||||||
|
let pipelines = &self.out_pipelines[fb_eotf];
|
||||||
|
if let Some(pl) = pipelines.get(&key) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let mut descriptor_set_layouts = ArrayVec::new();
|
||||||
|
descriptor_set_layouts.push(self.out_descriptor_set_layout.clone().unwrap());
|
||||||
|
let out = self
|
||||||
|
.device
|
||||||
|
.create_pipeline::<OutPushConstants>(PipelineCreateInfo {
|
||||||
|
format: key.format,
|
||||||
|
vert: self.out_vert_shader.clone().unwrap(),
|
||||||
|
frag: self.out_frag_shader.clone().unwrap(),
|
||||||
|
blend: false,
|
||||||
|
src_has_alpha: true,
|
||||||
|
has_alpha_mult: false,
|
||||||
|
alpha_mode: AlphaMode::PremultipliedElectrical,
|
||||||
|
eotf: key.eotf.to_vulkan(),
|
||||||
|
inv_eotf: fb_eotf.to_vulkan(),
|
||||||
|
descriptor_set_layouts,
|
||||||
|
has_color_management_data,
|
||||||
|
})?;
|
||||||
|
pipelines.set(key, out.clone());
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue