rt(mtl): draw final pass to output targets
This commit is contained in:
parent
22b2118e97
commit
e24beede0b
|
@ -58,22 +58,6 @@ pub struct DrawQuad {
|
|||
impl DrawQuad {
|
||||
pub fn new(device: &ProtocolObject<dyn MTLDevice>) -> Result<DrawQuad> {
|
||||
let vbo_data: &'static [u8] = bytemuck::cast_slice(&VBO_DATA);
|
||||
// let buffer = unsafe {
|
||||
// device
|
||||
// .newBufferWithBytes_length_options(
|
||||
// // SAFETY: this pointer is const.
|
||||
// // https://developer.apple.com/documentation/metal/mtldevice/1433429-newbufferwithbytes
|
||||
// NonNull::new_unchecked(vbo_data.as_ptr() as *mut c_void),
|
||||
// vbo_data.len(),
|
||||
// if cfg!(target_os = "ios") {
|
||||
// MTLResourceStorageModeShared
|
||||
// } else {
|
||||
// MTLResourceStorageModeManaged
|
||||
// },
|
||||
// )
|
||||
// .ok_or(FilterChainError::BufferError)?
|
||||
// };
|
||||
|
||||
let buffer = unsafe {
|
||||
device
|
||||
.newBufferWithBytes_length_options(
|
||||
|
|
|
@ -27,7 +27,7 @@ use librashader_runtime::quad::QuadType;
|
|||
use librashader_runtime::render_target::RenderTarget;
|
||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use objc2::rc::{Id, Retained};
|
||||
use objc2::rc::Id;
|
||||
use objc2::runtime::ProtocolObject;
|
||||
use objc2_foundation::NSString;
|
||||
use objc2_metal::{
|
||||
|
@ -206,7 +206,6 @@ impl FilterChainMetal {
|
|||
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||
input: &ProtocolObject<dyn MTLTexture>,
|
||||
) -> error::Result<()> {
|
||||
|
||||
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||
let mipmapper = cmd
|
||||
.blitCommandEncoder()
|
||||
|
@ -436,6 +435,8 @@ impl FilterChainMetal {
|
|||
target.generate_mipmaps(&cmd)?;
|
||||
}
|
||||
|
||||
self.common.output_textures[index] =
|
||||
Some(target.as_input(pass.config.filter, pass.config.wrap_mode)?);
|
||||
source = self.common.output_textures[index]
|
||||
.as_ref()
|
||||
.map(InputTexture::try_clone)
|
||||
|
@ -446,7 +447,10 @@ impl FilterChainMetal {
|
|||
assert_eq!(last.len(), 1);
|
||||
|
||||
if let Some(pass) = last.iter_mut().next() {
|
||||
if pass.graphics_pipeline.render_pass_format != viewport.output.pixelFormat() {
|
||||
if !pass
|
||||
.graphics_pipeline
|
||||
.has_format(viewport.output.pixelFormat())
|
||||
{
|
||||
// need to recompile
|
||||
pass.graphics_pipeline
|
||||
.recompile(&self.common.device, viewport.output.pixelFormat())?;
|
||||
|
@ -455,6 +459,24 @@ impl FilterChainMetal {
|
|||
source.filter_mode = pass.config.filter;
|
||||
source.wrap_mode = pass.config.wrap_mode;
|
||||
source.mip_filter = pass.config.filter;
|
||||
let index = passes_len - 1;
|
||||
|
||||
let output_image = &self.output_framebuffers[index].texture;
|
||||
|
||||
let out = RenderTarget::viewport_with_output(output_image.as_ref(), viewport);
|
||||
pass.draw(
|
||||
&cmd,
|
||||
passes_len - 1,
|
||||
&self.common,
|
||||
pass.config.get_frame_count(frame_count),
|
||||
options,
|
||||
viewport,
|
||||
&original,
|
||||
&source,
|
||||
&out,
|
||||
QuadType::Final,
|
||||
)?;
|
||||
|
||||
let output_image = viewport.output;
|
||||
let out = RenderTarget::viewport_with_output(output_image, viewport);
|
||||
pass.draw(
|
||||
|
|
|
@ -15,6 +15,7 @@ use objc2_metal::{
|
|||
MTLVertexFormat, MTLVertexStepFunction, MTLViewport,
|
||||
};
|
||||
|
||||
use librashader_common::map::FastHashMap;
|
||||
use objc2::rc::Retained;
|
||||
use objc2::runtime::ProtocolObject;
|
||||
|
||||
|
@ -23,8 +24,8 @@ pub const VERTEX_BUFFER_INDEX: usize = 4;
|
|||
|
||||
pub struct MetalGraphicsPipeline {
|
||||
pub layout: PipelineLayoutObjects,
|
||||
render_pipeline: Retained<ProtocolObject<dyn MTLRenderPipelineState>>,
|
||||
pub render_pass_format: MTLPixelFormat,
|
||||
render_pipelines:
|
||||
FastHashMap<MTLPixelFormat, Retained<ProtocolObject<dyn MTLRenderPipelineState>>>,
|
||||
}
|
||||
|
||||
pub struct PipelineLayoutObjects {
|
||||
|
@ -154,20 +155,25 @@ impl MetalGraphicsPipeline {
|
|||
) -> Result<Self> {
|
||||
let layout = PipelineLayoutObjects::new(shader_assembly, device)?;
|
||||
let pipeline = layout.create_pipeline(device, render_pass_format)?;
|
||||
let mut pipelines = FastHashMap::default();
|
||||
pipelines.insert(render_pass_format, pipeline);
|
||||
Ok(Self {
|
||||
layout,
|
||||
render_pipeline: pipeline,
|
||||
render_pass_format,
|
||||
render_pipelines: pipelines,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn has_format(&self, format: MTLPixelFormat) -> bool {
|
||||
self.render_pipelines.contains_key(&format)
|
||||
}
|
||||
|
||||
pub fn recompile(
|
||||
&mut self,
|
||||
device: &ProtocolObject<dyn MTLDevice>,
|
||||
format: MTLPixelFormat,
|
||||
) -> Result<()> {
|
||||
let render_pipeline = self.layout.create_pipeline(device, format)?;
|
||||
self.render_pipeline = render_pipeline;
|
||||
self.render_pipelines.insert(format, render_pipeline);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -177,6 +183,14 @@ impl MetalGraphicsPipeline {
|
|||
buffer: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||
) -> Result<Retained<ProtocolObject<dyn MTLRenderCommandEncoder>>> {
|
||||
unsafe {
|
||||
let Some(pipeline) = self
|
||||
.render_pipelines
|
||||
.get(&output.output.pixelFormat())
|
||||
.or_else(|| self.render_pipelines.values().next())
|
||||
else {
|
||||
panic!("No render available pipeline found");
|
||||
};
|
||||
|
||||
let descriptor = MTLRenderPassDescriptor::new();
|
||||
let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0);
|
||||
ca.setLoadAction(MTLLoadAction::DontCare);
|
||||
|
@ -188,7 +202,7 @@ impl MetalGraphicsPipeline {
|
|||
.ok_or(FilterChainError::FailedToCreateRenderPass)?;
|
||||
|
||||
rpass.setLabel(Some(&*NSString::from_str("librashader rpass")));
|
||||
rpass.setRenderPipelineState(&self.render_pipeline);
|
||||
rpass.setRenderPipelineState(pipeline);
|
||||
|
||||
rpass.setScissorRect(MTLScissorRect {
|
||||
x: output.x as usize,
|
||||
|
|
|
@ -220,7 +220,7 @@ declare_class!(
|
|||
.expect("Failed to create a pipeline state.");
|
||||
|
||||
let preset =
|
||||
ShaderPreset::try_parse("../test/shaders_slang/crt/crt-royale.slangp").unwrap();
|
||||
ShaderPreset::try_parse("../test/shaders_slang/test/feedback.slangp").unwrap();
|
||||
|
||||
let filter_chain = FilterChainMetal::load_from_preset(
|
||||
preset,
|
||||
|
|
|
@ -3,4 +3,4 @@ include!("./hello_triangle/main.rs");
|
|||
#[test]
|
||||
fn test_mtl() {
|
||||
main()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue