vulkan: don't hardcode argb8888 in pipelines
This commit is contained in:
parent
19dffba7d4
commit
c81f35bdf1
2 changed files with 119 additions and 67 deletions
|
|
@ -1,21 +1,21 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::gfx_apis::vulkan::{
|
||||||
format::ARGB8888,
|
descriptor::VulkanDescriptorSetLayout, device::VulkanDevice, shaders::VulkanShader,
|
||||||
gfx_apis::vulkan::{
|
util::OnDrop, VulkanError,
|
||||||
descriptor::VulkanDescriptorSetLayout, device::VulkanDevice, shaders::VulkanShader,
|
|
||||||
util::OnDrop, VulkanError,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
arrayvec::ArrayVec,
|
arrayvec::ArrayVec,
|
||||||
ash::vk::{
|
ash::{
|
||||||
BlendFactor, BlendOp, ColorComponentFlags, CullModeFlags, DynamicState, FrontFace,
|
vk,
|
||||||
GraphicsPipelineCreateInfo, Pipeline, PipelineCache, PipelineColorBlendAttachmentState,
|
vk::{
|
||||||
PipelineColorBlendStateCreateInfo, PipelineDynamicStateCreateInfo,
|
BlendFactor, BlendOp, ColorComponentFlags, CullModeFlags, DynamicState, FrontFace,
|
||||||
PipelineInputAssemblyStateCreateInfo, PipelineLayout, PipelineLayoutCreateInfo,
|
GraphicsPipelineCreateInfo, Pipeline, PipelineCache, PipelineColorBlendAttachmentState,
|
||||||
PipelineMultisampleStateCreateInfo, PipelineRasterizationStateCreateInfo,
|
PipelineColorBlendStateCreateInfo, PipelineDynamicStateCreateInfo,
|
||||||
PipelineRenderingCreateInfo, PipelineShaderStageCreateInfo,
|
PipelineInputAssemblyStateCreateInfo, PipelineLayout, PipelineLayoutCreateInfo,
|
||||||
PipelineVertexInputStateCreateInfo, PipelineViewportStateCreateInfo, PolygonMode,
|
PipelineMultisampleStateCreateInfo, PipelineRasterizationStateCreateInfo,
|
||||||
PrimitiveTopology, PushConstantRange, SampleCountFlags, ShaderStageFlags,
|
PipelineRenderingCreateInfo, PipelineShaderStageCreateInfo,
|
||||||
|
PipelineVertexInputStateCreateInfo, PipelineViewportStateCreateInfo, PolygonMode,
|
||||||
|
PrimitiveTopology, PushConstantRange, SampleCountFlags, ShaderStageFlags,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
std::{mem, rc::Rc, slice},
|
std::{mem, rc::Rc, slice},
|
||||||
};
|
};
|
||||||
|
|
@ -30,6 +30,7 @@ pub(super) struct VulkanPipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct PipelineCreateInfo {
|
pub(super) struct PipelineCreateInfo {
|
||||||
|
pub(super) format: vk::Format,
|
||||||
pub(super) vert: Rc<VulkanShader>,
|
pub(super) vert: Rc<VulkanShader>,
|
||||||
pub(super) frag: Rc<VulkanShader>,
|
pub(super) frag: Rc<VulkanShader>,
|
||||||
pub(super) alpha: bool,
|
pub(super) alpha: bool,
|
||||||
|
|
@ -128,7 +129,7 @@ impl VulkanDevice {
|
||||||
.viewport_count(1)
|
.viewport_count(1)
|
||||||
.scissor_count(1);
|
.scissor_count(1);
|
||||||
let mut pipeline_rendering_create_info = PipelineRenderingCreateInfo::default()
|
let mut pipeline_rendering_create_info = PipelineRenderingCreateInfo::default()
|
||||||
.color_attachment_formats(slice::from_ref(&ARGB8888.vk_format));
|
.color_attachment_formats(slice::from_ref(&info.format));
|
||||||
let create_info = GraphicsPipelineCreateInfo::default()
|
let create_info = GraphicsPipelineCreateInfo::default()
|
||||||
.push_next(&mut pipeline_rendering_create_info)
|
.push_next(&mut pipeline_rendering_create_info)
|
||||||
.stages(&stages)
|
.stages(&stages)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{AsyncEngine, SpawnedFuture},
|
async_engine::{AsyncEngine, SpawnedFuture},
|
||||||
format::Format,
|
format::{Format, XRGB8888},
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
|
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
|
||||||
GfxTexture, ReleaseSync, SyncFile,
|
GfxTexture, ReleaseSync, SyncFile,
|
||||||
|
|
@ -9,6 +9,7 @@ use {
|
||||||
gfx_apis::vulkan::{
|
gfx_apis::vulkan::{
|
||||||
allocator::VulkanAllocator,
|
allocator::VulkanAllocator,
|
||||||
command::{VulkanCommandBuffer, VulkanCommandPool},
|
command::{VulkanCommandBuffer, VulkanCommandPool},
|
||||||
|
descriptor::VulkanDescriptorSetLayout,
|
||||||
device::VulkanDevice,
|
device::VulkanDevice,
|
||||||
fence::VulkanFence,
|
fence::VulkanFence,
|
||||||
image::{VulkanImage, VulkanImageMemory},
|
image::{VulkanImage, VulkanImageMemory},
|
||||||
|
|
@ -28,6 +29,7 @@ use {
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
ash::{
|
ash::{
|
||||||
|
vk,
|
||||||
vk::{
|
vk::{
|
||||||
AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferImageCopy,
|
AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferImageCopy,
|
||||||
BufferMemoryBarrier2, ClearColorValue, ClearValue, CommandBuffer,
|
BufferMemoryBarrier2, ClearColorValue, ClearValue, CommandBuffer,
|
||||||
|
|
@ -56,8 +58,7 @@ use {
|
||||||
pub struct VulkanRenderer {
|
pub struct VulkanRenderer {
|
||||||
pub(super) formats: Rc<AHashMap<u32, GfxFormat>>,
|
pub(super) formats: Rc<AHashMap<u32, GfxFormat>>,
|
||||||
pub(super) device: Rc<VulkanDevice>,
|
pub(super) device: Rc<VulkanDevice>,
|
||||||
pub(super) fill_pipeline: Rc<VulkanPipeline>,
|
pub(super) pipelines: CopyHashMap<vk::Format, Rc<VulkanFormatPipelines>>,
|
||||||
pub(super) tex_pipelines: EnumMap<TexCopyType, EnumMap<TexSourceType, Rc<VulkanPipeline>>>,
|
|
||||||
pub(super) command_pool: Rc<VulkanCommandPool>,
|
pub(super) command_pool: Rc<VulkanCommandPool>,
|
||||||
pub(super) command_buffers: Stack<Rc<VulkanCommandBuffer>>,
|
pub(super) command_buffers: Stack<Rc<VulkanCommandBuffer>>,
|
||||||
pub(super) wait_semaphores: Stack<Rc<VulkanSemaphore>>,
|
pub(super) wait_semaphores: Stack<Rc<VulkanSemaphore>>,
|
||||||
|
|
@ -70,6 +71,13 @@ pub struct VulkanRenderer {
|
||||||
pub(super) buffer_resv_user: BufferResvUser,
|
pub(super) buffer_resv_user: BufferResvUser,
|
||||||
pub(super) eng: Rc<AsyncEngine>,
|
pub(super) eng: Rc<AsyncEngine>,
|
||||||
pub(super) ring: Rc<IoUring>,
|
pub(super) ring: Rc<IoUring>,
|
||||||
|
pub(super) fill_vert_shader: Rc<VulkanShader>,
|
||||||
|
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_opaque_shader: Rc<VulkanShader>,
|
||||||
|
pub(super) tex_frag_mult_alpha_shader: Rc<VulkanShader>,
|
||||||
|
pub(super) tex_descriptor_set_layout: Rc<VulkanDescriptorSetLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct UsedTexture {
|
pub(super) struct UsedTexture {
|
||||||
|
|
@ -112,46 +120,25 @@ pub(super) struct PendingFrame {
|
||||||
_release_fence: Option<Rc<VulkanFence>>,
|
_release_fence: Option<Rc<VulkanFence>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) struct VulkanFormatPipelines {
|
||||||
|
pub(super) fill: Rc<VulkanPipeline>,
|
||||||
|
pub(super) tex: EnumMap<TexCopyType, EnumMap<TexSourceType, Rc<VulkanPipeline>>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl VulkanDevice {
|
impl VulkanDevice {
|
||||||
pub fn create_renderer(
|
pub fn create_renderer(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
eng: &Rc<AsyncEngine>,
|
eng: &Rc<AsyncEngine>,
|
||||||
ring: &Rc<IoUring>,
|
ring: &Rc<IoUring>,
|
||||||
) -> Result<Rc<VulkanRenderer>, VulkanError> {
|
) -> Result<Rc<VulkanRenderer>, VulkanError> {
|
||||||
let fill_pipeline = self.create_pipeline::<FillVertPushConstants, FillFragPushConstants>(
|
let fill_vert_shader = self.create_shader(FILL_VERT)?;
|
||||||
PipelineCreateInfo {
|
let fill_frag_shader = self.create_shader(FILL_FRAG)?;
|
||||||
vert: self.create_shader(FILL_VERT)?,
|
|
||||||
frag: self.create_shader(FILL_FRAG)?,
|
|
||||||
alpha: true,
|
|
||||||
frag_descriptor_set_layout: None,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
let sampler = self.create_sampler()?;
|
let sampler = self.create_sampler()?;
|
||||||
let tex_descriptor_set_layout = self.create_descriptor_set_layout(&sampler)?;
|
let tex_descriptor_set_layout = self.create_descriptor_set_layout(&sampler)?;
|
||||||
let tex_vert_shader = self.create_shader(TEX_VERT)?;
|
let tex_vert_shader = self.create_shader(TEX_VERT)?;
|
||||||
let tex_frag_shader = self.create_shader(TEX_FRAG)?;
|
let tex_frag_shader = self.create_shader(TEX_FRAG)?;
|
||||||
let tex_frag_mult_opaque_shader = self.create_shader(TEX_FRAG_MULT_OPAQUE)?;
|
let tex_frag_mult_opaque_shader = self.create_shader(TEX_FRAG_MULT_OPAQUE)?;
|
||||||
let tex_frag_mult_alpha_shader = self.create_shader(TEX_FRAG_MULT_ALPHA)?;
|
let tex_frag_mult_alpha_shader = self.create_shader(TEX_FRAG_MULT_ALPHA)?;
|
||||||
let create_tex_pipeline = |alpha| {
|
|
||||||
self.create_pipeline::<TexVertPushConstants, ()>(PipelineCreateInfo {
|
|
||||||
vert: tex_vert_shader.clone(),
|
|
||||||
frag: tex_frag_shader.clone(),
|
|
||||||
alpha,
|
|
||||||
frag_descriptor_set_layout: Some(tex_descriptor_set_layout.clone()),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let create_tex_mult_pipeline = |frag: &Rc<VulkanShader>| {
|
|
||||||
self.create_pipeline::<TexVertPushConstants, TexFragPushConstants>(PipelineCreateInfo {
|
|
||||||
vert: tex_vert_shader.clone(),
|
|
||||||
frag: frag.clone(),
|
|
||||||
alpha: true,
|
|
||||||
frag_descriptor_set_layout: Some(tex_descriptor_set_layout.clone()),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
let tex_opaque_pipeline = create_tex_pipeline(false)?;
|
|
||||||
let tex_alpha_pipeline = create_tex_pipeline(true)?;
|
|
||||||
let tex_mult_opaque_pipeline = create_tex_mult_pipeline(&tex_frag_mult_opaque_shader)?;
|
|
||||||
let tex_mult_alpha_pipeline = create_tex_mult_pipeline(&tex_frag_mult_alpha_shader)?;
|
|
||||||
let command_pool = self.create_command_pool()?;
|
let command_pool = self.create_command_pool()?;
|
||||||
let formats: AHashMap<u32, _> = self
|
let formats: AHashMap<u32, _> = self
|
||||||
.formats
|
.formats
|
||||||
|
|
@ -178,20 +165,10 @@ impl VulkanDevice {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let allocator = self.create_allocator()?;
|
let allocator = self.create_allocator()?;
|
||||||
Ok(Rc::new(VulkanRenderer {
|
let render = Rc::new(VulkanRenderer {
|
||||||
formats: Rc::new(formats),
|
formats: Rc::new(formats),
|
||||||
device: self.clone(),
|
device: self.clone(),
|
||||||
fill_pipeline,
|
pipelines: Default::default(),
|
||||||
tex_pipelines: enum_map! {
|
|
||||||
TexCopyType::Identity => enum_map! {
|
|
||||||
TexSourceType::HasAlpha => tex_alpha_pipeline.clone(),
|
|
||||||
TexSourceType::Opaque => tex_opaque_pipeline.clone(),
|
|
||||||
},
|
|
||||||
TexCopyType::Multiply => enum_map! {
|
|
||||||
TexSourceType::HasAlpha => tex_mult_alpha_pipeline.clone(),
|
|
||||||
TexSourceType::Opaque => tex_mult_opaque_pipeline.clone(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
command_pool,
|
command_pool,
|
||||||
command_buffers: Default::default(),
|
command_buffers: Default::default(),
|
||||||
wait_semaphores: Default::default(),
|
wait_semaphores: Default::default(),
|
||||||
|
|
@ -204,11 +181,79 @@ impl VulkanDevice {
|
||||||
buffer_resv_user: Default::default(),
|
buffer_resv_user: Default::default(),
|
||||||
eng: eng.clone(),
|
eng: eng.clone(),
|
||||||
ring: ring.clone(),
|
ring: ring.clone(),
|
||||||
}))
|
fill_vert_shader,
|
||||||
|
fill_frag_shader,
|
||||||
|
tex_vert_shader,
|
||||||
|
tex_frag_shader,
|
||||||
|
tex_frag_mult_opaque_shader,
|
||||||
|
tex_frag_mult_alpha_shader,
|
||||||
|
tex_descriptor_set_layout,
|
||||||
|
});
|
||||||
|
render.get_or_create_pipelines(XRGB8888.vk_format)?;
|
||||||
|
Ok(render)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanRenderer {
|
impl VulkanRenderer {
|
||||||
|
fn get_or_create_pipelines(
|
||||||
|
&self,
|
||||||
|
format: vk::Format,
|
||||||
|
) -> Result<Rc<VulkanFormatPipelines>, VulkanError> {
|
||||||
|
if let Some(pl) = self.pipelines.get(&format) {
|
||||||
|
return Ok(pl);
|
||||||
|
}
|
||||||
|
let fill = self
|
||||||
|
.device
|
||||||
|
.create_pipeline::<FillVertPushConstants, FillFragPushConstants>(
|
||||||
|
PipelineCreateInfo {
|
||||||
|
format,
|
||||||
|
vert: self.fill_vert_shader.clone(),
|
||||||
|
frag: self.fill_frag_shader.clone(),
|
||||||
|
alpha: true,
|
||||||
|
frag_descriptor_set_layout: None,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
let create_tex_pipeline = |alpha| {
|
||||||
|
self.device
|
||||||
|
.create_pipeline::<TexVertPushConstants, ()>(PipelineCreateInfo {
|
||||||
|
format,
|
||||||
|
vert: self.tex_vert_shader.clone(),
|
||||||
|
frag: self.tex_frag_shader.clone(),
|
||||||
|
alpha,
|
||||||
|
frag_descriptor_set_layout: Some(self.tex_descriptor_set_layout.clone()),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let create_tex_mult_pipeline = |frag: &Rc<VulkanShader>| {
|
||||||
|
self.device
|
||||||
|
.create_pipeline::<TexVertPushConstants, TexFragPushConstants>(PipelineCreateInfo {
|
||||||
|
format,
|
||||||
|
vert: self.tex_vert_shader.clone(),
|
||||||
|
frag: frag.clone(),
|
||||||
|
alpha: true,
|
||||||
|
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(&self.tex_frag_mult_opaque_shader)?;
|
||||||
|
let tex_mult_alpha = create_tex_mult_pipeline(&self.tex_frag_mult_alpha_shader)?;
|
||||||
|
let pipelines = Rc::new(VulkanFormatPipelines {
|
||||||
|
fill,
|
||||||
|
tex: enum_map! {
|
||||||
|
TexCopyType::Identity => enum_map! {
|
||||||
|
TexSourceType::HasAlpha => tex_alpha.clone(),
|
||||||
|
TexSourceType::Opaque => tex_opaque.clone(),
|
||||||
|
},
|
||||||
|
TexCopyType::Multiply => enum_map! {
|
||||||
|
TexSourceType::HasAlpha => tex_mult_alpha.clone(),
|
||||||
|
TexSourceType::Opaque => tex_mult_opaque.clone(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
self.pipelines.set(format, pipelines.clone());
|
||||||
|
Ok(pipelines)
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +395,13 @@ impl VulkanRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_draws(&self, buf: CommandBuffer, opts: &[GfxApiOpt]) -> Result<(), VulkanError> {
|
fn record_draws(
|
||||||
|
&self,
|
||||||
|
buf: CommandBuffer,
|
||||||
|
fb: &VulkanImage,
|
||||||
|
opts: &[GfxApiOpt],
|
||||||
|
) -> Result<(), VulkanError> {
|
||||||
|
let pipelines = self.get_or_create_pipelines(fb.format.vk_format)?;
|
||||||
let dev = &self.device.device;
|
let dev = &self.device.device;
|
||||||
let mut current_pipeline = None;
|
let mut current_pipeline = None;
|
||||||
let mut bind = |pipeline: &VulkanPipeline| {
|
let mut bind = |pipeline: &VulkanPipeline| {
|
||||||
|
|
@ -365,7 +416,7 @@ impl VulkanRenderer {
|
||||||
match opt {
|
match opt {
|
||||||
GfxApiOpt::Sync => {}
|
GfxApiOpt::Sync => {}
|
||||||
GfxApiOpt::FillRect(r) => {
|
GfxApiOpt::FillRect(r) => {
|
||||||
bind(&self.fill_pipeline);
|
bind(&pipelines.fill);
|
||||||
let vert = FillVertPushConstants {
|
let vert = FillVertPushConstants {
|
||||||
pos: r.rect.to_points(),
|
pos: r.rect.to_points(),
|
||||||
};
|
};
|
||||||
|
|
@ -375,16 +426,16 @@ impl VulkanRenderer {
|
||||||
unsafe {
|
unsafe {
|
||||||
dev.cmd_push_constants(
|
dev.cmd_push_constants(
|
||||||
buf,
|
buf,
|
||||||
self.fill_pipeline.pipeline_layout,
|
pipelines.fill.pipeline_layout,
|
||||||
ShaderStageFlags::VERTEX,
|
ShaderStageFlags::VERTEX,
|
||||||
0,
|
0,
|
||||||
uapi::as_bytes(&vert),
|
uapi::as_bytes(&vert),
|
||||||
);
|
);
|
||||||
dev.cmd_push_constants(
|
dev.cmd_push_constants(
|
||||||
buf,
|
buf,
|
||||||
self.fill_pipeline.pipeline_layout,
|
pipelines.fill.pipeline_layout,
|
||||||
ShaderStageFlags::FRAGMENT,
|
ShaderStageFlags::FRAGMENT,
|
||||||
self.fill_pipeline.frag_push_offset,
|
pipelines.fill.frag_push_offset,
|
||||||
uapi::as_bytes(&frag),
|
uapi::as_bytes(&frag),
|
||||||
);
|
);
|
||||||
dev.cmd_draw(buf, 4, 1, 0, 0);
|
dev.cmd_draw(buf, 4, 1, 0, 0);
|
||||||
|
|
@ -400,7 +451,7 @@ impl VulkanRenderer {
|
||||||
true => TexSourceType::HasAlpha,
|
true => TexSourceType::HasAlpha,
|
||||||
false => TexSourceType::Opaque,
|
false => TexSourceType::Opaque,
|
||||||
};
|
};
|
||||||
let pipeline = &self.tex_pipelines[copy_type][source_type];
|
let pipeline = &pipelines.tex[copy_type][source_type];
|
||||||
bind(pipeline);
|
bind(pipeline);
|
||||||
let vert = TexVertPushConstants {
|
let vert = TexVertPushConstants {
|
||||||
pos: c.target.to_points(),
|
pos: c.target.to_points(),
|
||||||
|
|
@ -944,7 +995,7 @@ impl VulkanRenderer {
|
||||||
self.initial_barriers(buf.buffer, fb);
|
self.initial_barriers(buf.buffer, fb);
|
||||||
self.begin_rendering(buf.buffer, fb, clear);
|
self.begin_rendering(buf.buffer, fb, clear);
|
||||||
self.set_viewport(buf.buffer, fb);
|
self.set_viewport(buf.buffer, fb);
|
||||||
self.record_draws(buf.buffer, opts)?;
|
self.record_draws(buf.buffer, fb, opts)?;
|
||||||
self.end_rendering(buf.buffer);
|
self.end_rendering(buf.buffer);
|
||||||
self.copy_bridge_to_dmabuf(buf.buffer, fb);
|
self.copy_bridge_to_dmabuf(buf.buffer, fb);
|
||||||
self.final_barriers(buf.buffer, fb);
|
self.final_barriers(buf.buffer, fb);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue