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 {
|
||||
crate::{
|
||||
format::ARGB8888,
|
||||
gfx_apis::vulkan::{
|
||||
descriptor::VulkanDescriptorSetLayout, device::VulkanDevice, shaders::VulkanShader,
|
||||
util::OnDrop, VulkanError,
|
||||
},
|
||||
crate::gfx_apis::vulkan::{
|
||||
descriptor::VulkanDescriptorSetLayout, device::VulkanDevice, shaders::VulkanShader,
|
||||
util::OnDrop, VulkanError,
|
||||
},
|
||||
arrayvec::ArrayVec,
|
||||
ash::vk::{
|
||||
BlendFactor, BlendOp, ColorComponentFlags, CullModeFlags, DynamicState, FrontFace,
|
||||
GraphicsPipelineCreateInfo, Pipeline, PipelineCache, PipelineColorBlendAttachmentState,
|
||||
PipelineColorBlendStateCreateInfo, PipelineDynamicStateCreateInfo,
|
||||
PipelineInputAssemblyStateCreateInfo, PipelineLayout, PipelineLayoutCreateInfo,
|
||||
PipelineMultisampleStateCreateInfo, PipelineRasterizationStateCreateInfo,
|
||||
PipelineRenderingCreateInfo, PipelineShaderStageCreateInfo,
|
||||
PipelineVertexInputStateCreateInfo, PipelineViewportStateCreateInfo, PolygonMode,
|
||||
PrimitiveTopology, PushConstantRange, SampleCountFlags, ShaderStageFlags,
|
||||
ash::{
|
||||
vk,
|
||||
vk::{
|
||||
BlendFactor, BlendOp, ColorComponentFlags, CullModeFlags, DynamicState, FrontFace,
|
||||
GraphicsPipelineCreateInfo, Pipeline, PipelineCache, PipelineColorBlendAttachmentState,
|
||||
PipelineColorBlendStateCreateInfo, PipelineDynamicStateCreateInfo,
|
||||
PipelineInputAssemblyStateCreateInfo, PipelineLayout, PipelineLayoutCreateInfo,
|
||||
PipelineMultisampleStateCreateInfo, PipelineRasterizationStateCreateInfo,
|
||||
PipelineRenderingCreateInfo, PipelineShaderStageCreateInfo,
|
||||
PipelineVertexInputStateCreateInfo, PipelineViewportStateCreateInfo, PolygonMode,
|
||||
PrimitiveTopology, PushConstantRange, SampleCountFlags, ShaderStageFlags,
|
||||
},
|
||||
},
|
||||
std::{mem, rc::Rc, slice},
|
||||
};
|
||||
|
|
@ -30,6 +30,7 @@ pub(super) struct VulkanPipeline {
|
|||
}
|
||||
|
||||
pub(super) struct PipelineCreateInfo {
|
||||
pub(super) format: vk::Format,
|
||||
pub(super) vert: Rc<VulkanShader>,
|
||||
pub(super) frag: Rc<VulkanShader>,
|
||||
pub(super) alpha: bool,
|
||||
|
|
@ -128,7 +129,7 @@ impl VulkanDevice {
|
|||
.viewport_count(1)
|
||||
.scissor_count(1);
|
||||
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()
|
||||
.push_next(&mut pipeline_rendering_create_info)
|
||||
.stages(&stages)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
async_engine::{AsyncEngine, SpawnedFuture},
|
||||
format::Format,
|
||||
format::{Format, XRGB8888},
|
||||
gfx_api::{
|
||||
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
|
||||
GfxTexture, ReleaseSync, SyncFile,
|
||||
|
|
@ -9,6 +9,7 @@ use {
|
|||
gfx_apis::vulkan::{
|
||||
allocator::VulkanAllocator,
|
||||
command::{VulkanCommandBuffer, VulkanCommandPool},
|
||||
descriptor::VulkanDescriptorSetLayout,
|
||||
device::VulkanDevice,
|
||||
fence::VulkanFence,
|
||||
image::{VulkanImage, VulkanImageMemory},
|
||||
|
|
@ -28,6 +29,7 @@ use {
|
|||
},
|
||||
ahash::AHashMap,
|
||||
ash::{
|
||||
vk,
|
||||
vk::{
|
||||
AccessFlags2, AttachmentLoadOp, AttachmentStoreOp, BufferImageCopy,
|
||||
BufferMemoryBarrier2, ClearColorValue, ClearValue, CommandBuffer,
|
||||
|
|
@ -56,8 +58,7 @@ use {
|
|||
pub struct VulkanRenderer {
|
||||
pub(super) formats: Rc<AHashMap<u32, GfxFormat>>,
|
||||
pub(super) device: Rc<VulkanDevice>,
|
||||
pub(super) fill_pipeline: Rc<VulkanPipeline>,
|
||||
pub(super) tex_pipelines: EnumMap<TexCopyType, EnumMap<TexSourceType, Rc<VulkanPipeline>>>,
|
||||
pub(super) pipelines: CopyHashMap<vk::Format, Rc<VulkanFormatPipelines>>,
|
||||
pub(super) command_pool: Rc<VulkanCommandPool>,
|
||||
pub(super) command_buffers: Stack<Rc<VulkanCommandBuffer>>,
|
||||
pub(super) wait_semaphores: Stack<Rc<VulkanSemaphore>>,
|
||||
|
|
@ -70,6 +71,13 @@ pub struct VulkanRenderer {
|
|||
pub(super) buffer_resv_user: BufferResvUser,
|
||||
pub(super) eng: Rc<AsyncEngine>,
|
||||
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 {
|
||||
|
|
@ -112,46 +120,25 @@ pub(super) struct PendingFrame {
|
|||
_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 {
|
||||
pub fn create_renderer(
|
||||
self: &Rc<Self>,
|
||||
eng: &Rc<AsyncEngine>,
|
||||
ring: &Rc<IoUring>,
|
||||
) -> Result<Rc<VulkanRenderer>, VulkanError> {
|
||||
let fill_pipeline = self.create_pipeline::<FillVertPushConstants, FillFragPushConstants>(
|
||||
PipelineCreateInfo {
|
||||
vert: self.create_shader(FILL_VERT)?,
|
||||
frag: self.create_shader(FILL_FRAG)?,
|
||||
alpha: true,
|
||||
frag_descriptor_set_layout: None,
|
||||
},
|
||||
)?;
|
||||
let fill_vert_shader = self.create_shader(FILL_VERT)?;
|
||||
let fill_frag_shader = self.create_shader(FILL_FRAG)?;
|
||||
let sampler = self.create_sampler()?;
|
||||
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_opaque_shader = self.create_shader(TEX_FRAG_MULT_OPAQUE)?;
|
||||
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 formats: AHashMap<u32, _> = self
|
||||
.formats
|
||||
|
|
@ -178,20 +165,10 @@ impl VulkanDevice {
|
|||
})
|
||||
.collect();
|
||||
let allocator = self.create_allocator()?;
|
||||
Ok(Rc::new(VulkanRenderer {
|
||||
let render = Rc::new(VulkanRenderer {
|
||||
formats: Rc::new(formats),
|
||||
device: self.clone(),
|
||||
fill_pipeline,
|
||||
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(),
|
||||
},
|
||||
},
|
||||
pipelines: Default::default(),
|
||||
command_pool,
|
||||
command_buffers: Default::default(),
|
||||
wait_semaphores: Default::default(),
|
||||
|
|
@ -204,11 +181,79 @@ impl VulkanDevice {
|
|||
buffer_resv_user: Default::default(),
|
||||
eng: eng.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 {
|
||||
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 {
|
||||
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 mut current_pipeline = None;
|
||||
let mut bind = |pipeline: &VulkanPipeline| {
|
||||
|
|
@ -365,7 +416,7 @@ impl VulkanRenderer {
|
|||
match opt {
|
||||
GfxApiOpt::Sync => {}
|
||||
GfxApiOpt::FillRect(r) => {
|
||||
bind(&self.fill_pipeline);
|
||||
bind(&pipelines.fill);
|
||||
let vert = FillVertPushConstants {
|
||||
pos: r.rect.to_points(),
|
||||
};
|
||||
|
|
@ -375,16 +426,16 @@ impl VulkanRenderer {
|
|||
unsafe {
|
||||
dev.cmd_push_constants(
|
||||
buf,
|
||||
self.fill_pipeline.pipeline_layout,
|
||||
pipelines.fill.pipeline_layout,
|
||||
ShaderStageFlags::VERTEX,
|
||||
0,
|
||||
uapi::as_bytes(&vert),
|
||||
);
|
||||
dev.cmd_push_constants(
|
||||
buf,
|
||||
self.fill_pipeline.pipeline_layout,
|
||||
pipelines.fill.pipeline_layout,
|
||||
ShaderStageFlags::FRAGMENT,
|
||||
self.fill_pipeline.frag_push_offset,
|
||||
pipelines.fill.frag_push_offset,
|
||||
uapi::as_bytes(&frag),
|
||||
);
|
||||
dev.cmd_draw(buf, 4, 1, 0, 0);
|
||||
|
|
@ -400,7 +451,7 @@ impl VulkanRenderer {
|
|||
true => TexSourceType::HasAlpha,
|
||||
false => TexSourceType::Opaque,
|
||||
};
|
||||
let pipeline = &self.tex_pipelines[copy_type][source_type];
|
||||
let pipeline = &pipelines.tex[copy_type][source_type];
|
||||
bind(pipeline);
|
||||
let vert = TexVertPushConstants {
|
||||
pos: c.target.to_points(),
|
||||
|
|
@ -944,7 +995,7 @@ impl VulkanRenderer {
|
|||
self.initial_barriers(buf.buffer, fb);
|
||||
self.begin_rendering(buf.buffer, fb, clear);
|
||||
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.copy_bridge_to_dmabuf(buf.buffer, fb);
|
||||
self.final_barriers(buf.buffer, fb);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue