vulkan: implement all alpha modes
This commit is contained in:
parent
69ca5d92e7
commit
56a6012a7c
12 changed files with 62 additions and 11 deletions
|
|
@ -1,4 +1,5 @@
|
|||
mod allocator;
|
||||
mod alpha_modes;
|
||||
mod blend_buffer;
|
||||
mod bo_allocator;
|
||||
mod buffer_cache;
|
||||
|
|
@ -387,6 +388,10 @@ impl GfxContext for Context {
|
|||
self.0.device.descriptor_buffer.is_some()
|
||||
}
|
||||
|
||||
fn supports_alpha_modes(&self) -> bool {
|
||||
self.0.device.descriptor_buffer.is_some()
|
||||
}
|
||||
|
||||
fn create_dmabuf_buffer(
|
||||
&self,
|
||||
dmabuf: &OwnedFd,
|
||||
|
|
|
|||
15
src/gfx_apis/vulkan/alpha_modes.rs
Normal file
15
src/gfx_apis/vulkan/alpha_modes.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use crate::gfx_api::AlphaMode;
|
||||
|
||||
pub const AM_PREMULTIPLIED_ELECTRICAL: u32 = 0;
|
||||
pub const AM_PREMULTIPLIED_OPTICAL: u32 = 1;
|
||||
pub const AM_STRAIGHT: u32 = 2;
|
||||
|
||||
impl AlphaMode {
|
||||
pub fn to_vulkan(self) -> u32 {
|
||||
match self {
|
||||
AlphaMode::PremultipliedElectrical => AM_PREMULTIPLIED_ELECTRICAL,
|
||||
AlphaMode::PremultipliedOptical => AM_PREMULTIPLIED_OPTICAL,
|
||||
AlphaMode::Straight => AM_STRAIGHT,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
use {
|
||||
crate::gfx_apis::vulkan::{
|
||||
VulkanError, descriptor::VulkanDescriptorSetLayout, device::VulkanDevice,
|
||||
shaders::VulkanShader,
|
||||
crate::{
|
||||
gfx_api::AlphaMode,
|
||||
gfx_apis::vulkan::{
|
||||
VulkanError, descriptor::VulkanDescriptorSetLayout, device::VulkanDevice,
|
||||
shaders::VulkanShader,
|
||||
},
|
||||
},
|
||||
arrayvec::ArrayVec,
|
||||
ash::{
|
||||
|
|
@ -37,6 +40,7 @@ pub(super) struct PipelineCreateInfo {
|
|||
pub(super) blend: bool,
|
||||
pub(super) src_has_alpha: bool,
|
||||
pub(super) has_alpha_mult: bool,
|
||||
pub(super) alpha_mode: AlphaMode,
|
||||
pub(super) eotf: u32,
|
||||
pub(super) inv_eotf: u32,
|
||||
pub(super) descriptor_set_layouts: ArrayVec<Rc<VulkanDescriptorSetLayout>, 2>,
|
||||
|
|
@ -76,8 +80,8 @@ impl VulkanDevice {
|
|||
};
|
||||
let destroy_layout =
|
||||
on_drop(|| unsafe { self.device.destroy_pipeline_layout(pipeline_layout, None) });
|
||||
let mut frag_spec_data = ArrayVec::<_, { 5 * 4 }>::new();
|
||||
let mut frag_spec_entries = ArrayVec::<_, 5>::new();
|
||||
let mut frag_spec_data = ArrayVec::<_, { 6 * 4 }>::new();
|
||||
let mut frag_spec_entries = ArrayVec::<_, 6>::new();
|
||||
let mut frag_spec_entry = |data: &[u8]| {
|
||||
let entry = SpecializationMapEntry::default()
|
||||
.constant_id(frag_spec_entries.len() as _)
|
||||
|
|
@ -91,6 +95,7 @@ impl VulkanDevice {
|
|||
frag_spec_entry(&info.eotf.to_ne_bytes());
|
||||
frag_spec_entry(&info.inv_eotf.to_ne_bytes());
|
||||
frag_spec_entry(&(info.has_color_management_data as u32).to_ne_bytes());
|
||||
frag_spec_entry(&info.alpha_mode.to_vulkan().to_ne_bytes());
|
||||
let frag_spec = SpecializationInfo::default()
|
||||
.map_entries(&frag_spec_entries)
|
||||
.data(&frag_spec_data);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use {
|
|||
},
|
||||
cpu_worker::PendingJob,
|
||||
gfx_api::{
|
||||
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxBlendBuffer, GfxFormat,
|
||||
GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile,
|
||||
AcquireSync, AlphaMode, BufferResv, BufferResvUser, GfxApiOpt, GfxBlendBuffer,
|
||||
GfxFormat, GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile,
|
||||
},
|
||||
gfx_apis::vulkan::{
|
||||
VulkanError,
|
||||
|
|
@ -209,6 +209,7 @@ struct VulkanTexOp {
|
|||
alpha: f32,
|
||||
source_type: TexSourceType,
|
||||
copy_type: TexCopyType,
|
||||
alpha_mode: AlphaMode,
|
||||
range_address: DeviceAddress,
|
||||
instances: u32,
|
||||
tex_cd: Rc<ColorDescription>,
|
||||
|
|
@ -258,6 +259,7 @@ type FillPipelines = Rc<StaticMap<TexSourceType, Rc<VulkanPipeline>>>;
|
|||
struct TexPipelineKey {
|
||||
tex_copy_type: TexCopyType,
|
||||
tex_source_type: TexSourceType,
|
||||
tex_alpha_mode: AlphaMode,
|
||||
eotf: VulkanEotf,
|
||||
has_color_management_data: bool,
|
||||
}
|
||||
|
|
@ -431,6 +433,7 @@ impl VulkanRenderer {
|
|||
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,
|
||||
|
|
@ -474,11 +477,16 @@ impl VulkanRenderer {
|
|||
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,
|
||||
};
|
||||
|
|
@ -505,6 +513,7 @@ impl VulkanRenderer {
|
|||
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(),
|
||||
|
|
@ -543,6 +552,7 @@ impl VulkanRenderer {
|
|||
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,
|
||||
|
|
@ -886,6 +896,7 @@ impl VulkanRenderer {
|
|||
alpha: ct.alpha.unwrap_or_default(),
|
||||
source_type,
|
||||
copy_type,
|
||||
alpha_mode: ct.alpha_mode,
|
||||
range_address: 0,
|
||||
instances: 0,
|
||||
tex_cd: ct.cd.clone(),
|
||||
|
|
@ -1333,6 +1344,7 @@ impl VulkanRenderer {
|
|||
&c.tex_cd,
|
||||
c.copy_type,
|
||||
c.source_type,
|
||||
c.alpha_mode,
|
||||
c.color_management_data_address.is_some(),
|
||||
)?;
|
||||
bind(&pipeline);
|
||||
|
|
|
|||
8
src/gfx_apis/vulkan/shaders/alpha_modes.glsl
Normal file
8
src/gfx_apis/vulkan/shaders/alpha_modes.glsl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef ALPHA_MODES_GLSL
|
||||
#define ALPHA_MODES_GLSL
|
||||
|
||||
#define AM_PREMULTIPLIED_ELECTRICAL 0
|
||||
#define AM_PREMULTIPLIED_OPTICAL 1
|
||||
#define AM_STRAIGHT 2
|
||||
|
||||
#endif
|
||||
|
|
@ -6,5 +6,6 @@ layout(constant_id = 1) const bool has_alpha_multiplier = false;
|
|||
layout(constant_id = 2) const uint eotf = 0;
|
||||
layout(constant_id = 3) const uint inv_eotf = 0;
|
||||
layout(constant_id = 4) const bool has_matrix = false;
|
||||
layout(constant_id = 5) const uint alpha_mode = 0;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "tex.common.glsl"
|
||||
#include "tex_set.glsl"
|
||||
#include "eotfs.glsl"
|
||||
#include "alpha_modes.glsl"
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler sam;
|
||||
layout(location = 0) in vec2 tex_pos;
|
||||
|
|
@ -15,12 +16,15 @@ layout(location = 0) out vec4 out_color;
|
|||
|
||||
void main() {
|
||||
vec4 c = textureLod(sampler2D(tex, sam), tex_pos, 0);
|
||||
if (eotf != inv_eotf || has_matrix) {
|
||||
if (eotf != inv_eotf || has_matrix || alpha_mode != AM_PREMULTIPLIED_ELECTRICAL) {
|
||||
vec3 rgb = c.rgb;
|
||||
if (src_has_alpha) {
|
||||
if (src_has_alpha && alpha_mode == AM_PREMULTIPLIED_ELECTRICAL) {
|
||||
rgb /= mix(c.a, 1.0, c.a == 0.0);
|
||||
}
|
||||
rgb = apply_eotf(rgb);
|
||||
if (src_has_alpha && alpha_mode == AM_PREMULTIPLIED_OPTICAL) {
|
||||
rgb /= mix(c.a, 1.0, c.a == 0.0);
|
||||
}
|
||||
if (has_matrix) {
|
||||
rgb = (cm_data.matrix * vec4(rgb, 1.0)).rgb;
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,8 +1,9 @@
|
|||
302a9f250bdc4f8e0e71a9f77c9a8a7aa55fd003bc91c2422a700c4abd83f54e src/gfx_apis/vulkan/shaders/alpha_modes.glsl
|
||||
b6a0df1e231fab533499329636b7a580384784418baee06c147af5fcc384cf5c src/gfx_apis/vulkan/shaders/eotfs.glsl
|
||||
8a38df18851cd13884499820f26939fb7319f45d913d867f254d8118d59fb117 src/gfx_apis/vulkan/shaders/fill.common.glsl
|
||||
21c488d12aa5ad2f109ec44cb856dfe837e02ea9025b5ed64439d742c17cbf30 src/gfx_apis/vulkan/shaders/fill.frag
|
||||
4fb481d8d73afdfb0d8f077eb8665d86f06c8a32a91e44ed369ef5dff554646d src/gfx_apis/vulkan/shaders/fill.vert
|
||||
63af15c4e00587a7bb8494934c88d9874712a511217829b50f3c08fa3c461082 src/gfx_apis/vulkan/shaders/frag_spec_const.glsl
|
||||
f93524fd077bc9984702b1e0f92232f80bfe28a0a92439dc164c1ea41fd16d64 src/gfx_apis/vulkan/shaders/frag_spec_const.glsl
|
||||
c315a064b48dd5bdb607a6b79c30d31b6e59ffec69e93d50ab875abf97c41bbf src/gfx_apis/vulkan/shaders/legacy/fill.common.glsl
|
||||
590d061b97446fc501158609eaf098b71bc7b328c008b586ff36613ce690d618 src/gfx_apis/vulkan/shaders/legacy/fill.frag
|
||||
ad22a79e1a88a12daa40c0a2b953084c129a408297c8ca544d60e0b6001470b9 src/gfx_apis/vulkan/shaders/legacy/fill.vert
|
||||
|
|
@ -13,6 +14,6 @@ e0a8769dd7938dd02e66db9e9048ed6bef8f8c42671f2e2c7a7976a6d498f685 src/gfx_apis/vu
|
|||
5069f619c7d722815a022e2d84720a2d8290af49a3ed49ea0cd26b52115cc39a src/gfx_apis/vulkan/shaders/out.frag
|
||||
0adc7e12328c15fb3e7e6c8b8701a182223c2f15337e14131f41dd247e697809 src/gfx_apis/vulkan/shaders/out.vert
|
||||
e22d4d3318a350def8ef19c7b27dc6a308a84c2fe9d7c02b81107f72073cd481 src/gfx_apis/vulkan/shaders/tex.common.glsl
|
||||
06993d4d882fe5c651e5ab54f0116b9622352a97f3575985076ef464b472dd39 src/gfx_apis/vulkan/shaders/tex.frag
|
||||
1f196cee646a934072beb3e5648a5042c035953d9a0c26b0a22e330c2f8bb994 src/gfx_apis/vulkan/shaders/tex.frag
|
||||
423cf327c9fcc4070dbf75321c1224a1589b6cf3d2f1ea5e8bd0362e1a9f3aa1 src/gfx_apis/vulkan/shaders/tex.vert
|
||||
b982f7101c22931a33b32dce3408387f3392c0f0ad0ca5852da265b0d12856bb src/gfx_apis/vulkan/shaders/tex_set.glsl
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue