Merge pull request #369 from mahkoh/jorth/unconditional-push-constants
vulkan: use single push constant range per pipeline
This commit is contained in:
commit
31b509d559
11 changed files with 71 additions and 140 deletions
|
|
@ -12,17 +12,7 @@ pub fn main() -> anyhow::Result<()> {
|
|||
compile_simple("fill.frag")?;
|
||||
compile_simple("fill.vert")?;
|
||||
compile_simple("tex.vert")?;
|
||||
compile_tex_frag("tex.frag.spv", false)?;
|
||||
compile_tex_frag("tex.frag.mult.spv", true)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_tex_frag(out: &str, alpha_multiplier: bool) -> anyhow::Result<()> {
|
||||
let mut opts = CompileOptions::new().unwrap();
|
||||
if alpha_multiplier {
|
||||
opts.add_macro_definition("ALPHA_MULTIPLIER", None);
|
||||
}
|
||||
compile_shader("tex.frag", out, Some(opts)).with_context(|| out.to_string())?;
|
||||
compile_simple("tex.frag")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ use {
|
|||
pub(super) struct VulkanPipeline {
|
||||
pub(super) vert: Rc<VulkanShader>,
|
||||
pub(super) _frag: Rc<VulkanShader>,
|
||||
pub(super) frag_push_offset: u32,
|
||||
pub(super) pipeline_layout: PipelineLayout,
|
||||
pub(super) pipeline: Pipeline,
|
||||
pub(super) _frag_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>,
|
||||
|
|
@ -39,46 +38,32 @@ pub(super) struct PipelineCreateInfo {
|
|||
pub(super) frag: Rc<VulkanShader>,
|
||||
pub(super) blend: bool,
|
||||
pub(super) src_has_alpha: bool,
|
||||
pub(super) has_alpha_mult: bool,
|
||||
pub(super) frag_descriptor_set_layout: Option<Rc<VulkanDescriptorSetLayout>>,
|
||||
}
|
||||
|
||||
impl VulkanDevice {
|
||||
pub(super) fn create_pipeline<V, F>(
|
||||
pub(super) fn create_pipeline<P>(
|
||||
&self,
|
||||
info: PipelineCreateInfo,
|
||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||
self.create_pipeline_(info, size_of::<V>() as _, size_of::<F>() as _)
|
||||
self.create_pipeline_(info, size_of::<P>() as _)
|
||||
}
|
||||
|
||||
fn create_pipeline_(
|
||||
&self,
|
||||
info: PipelineCreateInfo,
|
||||
vert_push_size: u32,
|
||||
frag_push_size: u32,
|
||||
push_size: u32,
|
||||
) -> Result<Rc<VulkanPipeline>, VulkanError> {
|
||||
let pipeline_layout = {
|
||||
let mut push_constant_ranges = ArrayVec::<_, 2>::new();
|
||||
let mut push_constant_offset = 0;
|
||||
if vert_push_size > 0 {
|
||||
let mut push_constant_ranges = ArrayVec::<_, 1>::new();
|
||||
if push_size > 0 {
|
||||
push_constant_ranges.push(
|
||||
PushConstantRange::default()
|
||||
.stage_flags(ShaderStageFlags::VERTEX)
|
||||
.stage_flags(ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT)
|
||||
.offset(0)
|
||||
.size(vert_push_size),
|
||||
.size(push_size),
|
||||
);
|
||||
push_constant_offset += vert_push_size;
|
||||
}
|
||||
if frag_push_size > 0 {
|
||||
push_constant_ranges.push(
|
||||
PushConstantRange::default()
|
||||
.stage_flags(ShaderStageFlags::FRAGMENT)
|
||||
.offset(push_constant_offset)
|
||||
.size(frag_push_size),
|
||||
);
|
||||
#[expect(unused_assignments)]
|
||||
{
|
||||
push_constant_offset += frag_push_size;
|
||||
}
|
||||
}
|
||||
let mut descriptor_set_layouts = ArrayVec::<_, 1>::new();
|
||||
descriptor_set_layouts
|
||||
|
|
@ -91,12 +76,18 @@ impl VulkanDevice {
|
|||
};
|
||||
let destroy_layout =
|
||||
OnDrop(|| unsafe { self.device.destroy_pipeline_layout(pipeline_layout, None) });
|
||||
let mut frag_spec_data = ArrayVec::<_, 4>::new();
|
||||
frag_spec_data.extend((info.src_has_alpha as u32).to_ne_bytes());
|
||||
let frag_spec_entries = [SpecializationMapEntry::default()
|
||||
.constant_id(0)
|
||||
.size(4)
|
||||
.offset(0)];
|
||||
let mut frag_spec_data = ArrayVec::<_, 8>::new();
|
||||
let mut frag_spec_entries = ArrayVec::<_, 2>::new();
|
||||
let mut frag_spec_entry = |data: &[u8]| {
|
||||
let entry = SpecializationMapEntry::default()
|
||||
.constant_id(frag_spec_entries.len() as _)
|
||||
.size(data.len() as _)
|
||||
.offset(frag_spec_data.len() as _);
|
||||
frag_spec_entries.push(entry);
|
||||
frag_spec_data.extend(data.iter().copied());
|
||||
};
|
||||
frag_spec_entry(&(info.src_has_alpha as u32).to_ne_bytes());
|
||||
frag_spec_entry(&(info.has_alpha_mult as u32).to_ne_bytes());
|
||||
let frag_spec = SpecializationInfo::default()
|
||||
.map_entries(&frag_spec_entries)
|
||||
.data(&frag_spec_data);
|
||||
|
|
@ -173,7 +164,6 @@ impl VulkanDevice {
|
|||
Ok(Rc::new(VulkanPipeline {
|
||||
vert: info.vert,
|
||||
_frag: info.frag,
|
||||
frag_push_offset: vert_push_size,
|
||||
pipeline_layout,
|
||||
pipeline,
|
||||
_frag_descriptor_set_layout: info.frag_descriptor_set_layout,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ use {
|
|||
pipeline::{PipelineCreateInfo, VulkanPipeline},
|
||||
semaphore::VulkanSemaphore,
|
||||
shaders::{
|
||||
FillFragPushConstants, FillVertPushConstants, TexFragPushConstants,
|
||||
TexVertPushConstants, VulkanShader, FILL_FRAG, FILL_VERT, TEX_FRAG, TEX_FRAG_MULT,
|
||||
FillPushConstants, TexPushConstants, VulkanShader, FILL_FRAG, FILL_VERT, TEX_FRAG,
|
||||
TEX_VERT,
|
||||
},
|
||||
VulkanError,
|
||||
|
|
@ -74,7 +73,6 @@ pub struct VulkanRenderer {
|
|||
pub(super) fill_frag_shader: Rc<VulkanShader>,
|
||||
pub(super) tex_vert_shader: Rc<VulkanShader>,
|
||||
pub(super) tex_frag_shader: Rc<VulkanShader>,
|
||||
pub(super) tex_frag_mult_shader: Rc<VulkanShader>,
|
||||
pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>,
|
||||
pub(super) defunct: Cell<bool>,
|
||||
pub(super) pending_cpu_jobs: CopyHashMap<u64, PendingJob>,
|
||||
|
|
@ -159,7 +157,6 @@ impl VulkanDevice {
|
|||
let tex_descriptor_set_layout = self.create_descriptor_set_layout(&sampler)?;
|
||||
let tex_vert_shader = self.create_shader(TEX_VERT)?;
|
||||
let tex_frag_shader = self.create_shader(TEX_FRAG)?;
|
||||
let tex_frag_mult_shader = self.create_shader(TEX_FRAG_MULT)?;
|
||||
let gfx_command_buffers = self.create_command_pool(self.graphics_queue_idx)?;
|
||||
let transfer_command_buffers = self
|
||||
.distinct_transfer_queue_family_idx
|
||||
|
|
@ -217,7 +214,6 @@ impl VulkanDevice {
|
|||
fill_frag_shader,
|
||||
tex_vert_shader,
|
||||
tex_frag_shader,
|
||||
tex_frag_mult_shader,
|
||||
tex_descriptor_set_layout,
|
||||
defunct: Cell::new(false),
|
||||
pending_cpu_jobs: Default::default(),
|
||||
|
|
@ -238,42 +234,31 @@ impl VulkanRenderer {
|
|||
}
|
||||
let fill = self
|
||||
.device
|
||||
.create_pipeline::<FillVertPushConstants, FillFragPushConstants>(
|
||||
PipelineCreateInfo {
|
||||
format,
|
||||
vert: self.fill_vert_shader.clone(),
|
||||
frag: self.fill_frag_shader.clone(),
|
||||
blend: true,
|
||||
src_has_alpha: true,
|
||||
frag_descriptor_set_layout: None,
|
||||
},
|
||||
)?;
|
||||
let create_tex_pipeline = |src_has_alpha| {
|
||||
.create_pipeline::<FillPushConstants>(PipelineCreateInfo {
|
||||
format,
|
||||
vert: self.fill_vert_shader.clone(),
|
||||
frag: self.fill_frag_shader.clone(),
|
||||
blend: true,
|
||||
src_has_alpha: true,
|
||||
has_alpha_mult: false,
|
||||
frag_descriptor_set_layout: None,
|
||||
})?;
|
||||
let create_tex_pipeline = |src_has_alpha, has_alpha_mult| {
|
||||
self.device
|
||||
.create_pipeline::<TexVertPushConstants, ()>(PipelineCreateInfo {
|
||||
.create_pipeline::<TexPushConstants>(PipelineCreateInfo {
|
||||
format,
|
||||
vert: self.tex_vert_shader.clone(),
|
||||
frag: self.tex_frag_shader.clone(),
|
||||
blend: src_has_alpha,
|
||||
blend: src_has_alpha || has_alpha_mult,
|
||||
src_has_alpha,
|
||||
has_alpha_mult,
|
||||
frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()),
|
||||
})
|
||||
};
|
||||
let create_tex_mult_pipeline = |src_has_alpha: bool| {
|
||||
self.device
|
||||
.create_pipeline::<TexVertPushConstants, TexFragPushConstants>(PipelineCreateInfo {
|
||||
format,
|
||||
vert: self.tex_vert_shader.clone(),
|
||||
frag: self.tex_frag_mult_shader.clone(),
|
||||
blend: true,
|
||||
src_has_alpha,
|
||||
frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()),
|
||||
})
|
||||
};
|
||||
let tex_opaque = create_tex_pipeline(false)?;
|
||||
let tex_alpha = create_tex_pipeline(true)?;
|
||||
let tex_mult_opaque = create_tex_mult_pipeline(false)?;
|
||||
let tex_mult_alpha = create_tex_mult_pipeline(true)?;
|
||||
let tex_opaque = create_tex_pipeline(false, false)?;
|
||||
let tex_alpha = create_tex_pipeline(true, false)?;
|
||||
let tex_mult_opaque = create_tex_pipeline(false, true)?;
|
||||
let tex_mult_alpha = create_tex_pipeline(true, true)?;
|
||||
let pipelines = Rc::new(VulkanFormatPipelines {
|
||||
fill,
|
||||
tex: static_map! {
|
||||
|
|
@ -514,26 +499,17 @@ impl VulkanRenderer {
|
|||
GfxApiOpt::Sync => {}
|
||||
GfxApiOpt::FillRect(r) => {
|
||||
bind(&pipelines.fill);
|
||||
let vert = FillVertPushConstants {
|
||||
let push = FillPushConstants {
|
||||
pos: r.rect.to_points(),
|
||||
};
|
||||
let frag = FillFragPushConstants {
|
||||
color: r.color.to_array_srgb(),
|
||||
};
|
||||
unsafe {
|
||||
dev.cmd_push_constants(
|
||||
buf,
|
||||
pipelines.fill.pipeline_layout,
|
||||
ShaderStageFlags::VERTEX,
|
||||
ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT,
|
||||
0,
|
||||
uapi::as_bytes(&vert),
|
||||
);
|
||||
dev.cmd_push_constants(
|
||||
buf,
|
||||
pipelines.fill.pipeline_layout,
|
||||
ShaderStageFlags::FRAGMENT,
|
||||
pipelines.fill.frag_push_offset,
|
||||
uapi::as_bytes(&frag),
|
||||
uapi::as_bytes(&push),
|
||||
);
|
||||
dev.cmd_draw(buf, 4, 1, 0, 0);
|
||||
}
|
||||
|
|
@ -559,9 +535,10 @@ impl VulkanRenderer {
|
|||
};
|
||||
let pipeline = &pipelines.tex[copy_type][source_type];
|
||||
bind(pipeline);
|
||||
let vert = TexVertPushConstants {
|
||||
let push = TexPushConstants {
|
||||
pos: c.target.to_points(),
|
||||
tex_pos: c.source.to_points(),
|
||||
alpha: c.alpha.unwrap_or_default(),
|
||||
};
|
||||
let image_info = DescriptorImageInfo::default()
|
||||
.image_view(tex.texture_view)
|
||||
|
|
@ -580,20 +557,10 @@ impl VulkanRenderer {
|
|||
dev.cmd_push_constants(
|
||||
buf,
|
||||
pipeline.pipeline_layout,
|
||||
ShaderStageFlags::VERTEX,
|
||||
ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT,
|
||||
0,
|
||||
uapi::as_bytes(&vert),
|
||||
uapi::as_bytes(&push),
|
||||
);
|
||||
if let Some(alpha) = c.alpha {
|
||||
let frag = TexFragPushConstants { alpha };
|
||||
dev.cmd_push_constants(
|
||||
buf,
|
||||
pipeline.pipeline_layout,
|
||||
ShaderStageFlags::FRAGMENT,
|
||||
size_of_val(&vert) as _,
|
||||
uapi::as_bytes(&frag),
|
||||
);
|
||||
}
|
||||
dev.cmd_draw(buf, 4, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ pub const FILL_VERT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/fill.vert
|
|||
pub const FILL_FRAG: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/fill.frag.spv"));
|
||||
pub const TEX_VERT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/tex.vert.spv"));
|
||||
pub const TEX_FRAG: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/tex.frag.spv"));
|
||||
pub const TEX_FRAG_MULT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/tex.frag.mult.spv"));
|
||||
|
||||
pub struct VulkanShader {
|
||||
pub(super) device: Rc<VulkanDevice>,
|
||||
|
|
@ -18,35 +17,22 @@ pub struct VulkanShader {
|
|||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct FillVertPushConstants {
|
||||
pub struct FillPushConstants {
|
||||
pub pos: [[f32; 2]; 4],
|
||||
}
|
||||
|
||||
unsafe impl Packed for FillVertPushConstants {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct FillFragPushConstants {
|
||||
pub color: [f32; 4],
|
||||
}
|
||||
|
||||
unsafe impl Packed for FillFragPushConstants {}
|
||||
unsafe impl Packed for FillPushConstants {}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct TexVertPushConstants {
|
||||
pub struct TexPushConstants {
|
||||
pub pos: [[f32; 2]; 4],
|
||||
pub tex_pos: [[f32; 2]; 4],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[repr(C)]
|
||||
pub struct TexFragPushConstants {
|
||||
pub alpha: f32,
|
||||
}
|
||||
|
||||
unsafe impl Packed for TexVertPushConstants {}
|
||||
unsafe impl Packed for TexFragPushConstants {}
|
||||
unsafe impl Packed for TexPushConstants {}
|
||||
|
||||
impl VulkanDevice {
|
||||
pub(super) fn create_shader(
|
||||
|
|
|
|||
4
src/gfx_apis/vulkan/shaders/fill.common.glsl
Normal file
4
src/gfx_apis/vulkan/shaders/fill.common.glsl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 0) vec2 pos[4];
|
||||
layout(offset = 32) vec4 color;
|
||||
} data;
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
#version 450
|
||||
|
||||
#include "frag_spec_const.glsl"
|
||||
|
||||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 32) vec4 color;
|
||||
} data;
|
||||
#include "fill.common.glsl"
|
||||
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
#version 450
|
||||
//#extension GL_EXT_debug_printf : enable
|
||||
|
||||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 0) vec2 pos[4];
|
||||
} data;
|
||||
#include "fill.common.glsl"
|
||||
|
||||
void main() {
|
||||
vec2 pos;
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
layout(constant_id = 0) const bool src_has_alpha = false;
|
||||
layout(constant_id = 1) const bool has_alpha_multiplier = false;
|
||||
|
|
|
|||
5
src/gfx_apis/vulkan/shaders/tex.common.glsl
Normal file
5
src/gfx_apis/vulkan/shaders/tex.common.glsl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 0) vec2 pos[4];
|
||||
layout(offset = 32) vec2 tex_pos[4];
|
||||
layout(offset = 64) float mul;
|
||||
} data;
|
||||
|
|
@ -1,24 +1,20 @@
|
|||
#version 450
|
||||
|
||||
#include "frag_spec_const.glsl"
|
||||
#include "tex.common.glsl"
|
||||
|
||||
#ifdef ALPHA_MULTIPLIER
|
||||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 64) float mul;
|
||||
} data;
|
||||
#endif
|
||||
layout(set = 0, binding = 0) uniform sampler2D tex;
|
||||
layout(location = 0) in vec2 tex_pos;
|
||||
layout(location = 0) out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
#ifdef ALPHA_MULTIPLIER
|
||||
if (src_has_alpha) {
|
||||
out_color = textureLod(tex, tex_pos, 0) * data.mul;
|
||||
if (has_alpha_multiplier) {
|
||||
if (src_has_alpha) {
|
||||
out_color = textureLod(tex, tex_pos, 0) * data.mul;
|
||||
} else {
|
||||
out_color = vec4(textureLod(tex, tex_pos, 0).rgb * data.mul, data.mul);
|
||||
}
|
||||
} else {
|
||||
out_color = vec4(textureLod(tex, tex_pos, 0).rgb * data.mul, data.mul);
|
||||
out_color = textureLod(tex, tex_pos, 0);
|
||||
}
|
||||
#else // !ALPHA_MULTIPLIER
|
||||
out_color = textureLod(tex, tex_pos, 0);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
#version 450
|
||||
//#extension GL_EXT_debug_printf : enable
|
||||
|
||||
layout(push_constant, std430) uniform Data {
|
||||
layout(offset = 0) vec2 pos[4];
|
||||
layout(offset = 32) vec2 tex_pos[4];
|
||||
} data;
|
||||
#include "tex.common.glsl"
|
||||
|
||||
layout(location = 0) out vec2 tex_pos;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue