Skip to content

Commit

Permalink
rt(mtl): draw final pass to output targets
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyran committed Sep 13, 2024
1 parent 22b2118 commit e24beed
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 27 deletions.
16 changes: 0 additions & 16 deletions librashader-runtime-mtl/src/draw_quad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
28 changes: 25 additions & 3 deletions librashader-runtime-mtl/src/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand All @@ -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())?;
Expand All @@ -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(
Expand Down
26 changes: 20 additions & 6 deletions librashader-runtime-mtl/src/graphics_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use objc2_metal::{
MTLVertexFormat, MTLVertexStepFunction, MTLViewport,
};

use librashader_common::map::FastHashMap;
use objc2::rc::Retained;
use objc2::runtime::ProtocolObject;

Expand All @@ -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 {
Expand Down Expand Up @@ -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(())
}

Expand All @@ -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);
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion librashader-runtime-mtl/tests/hello_triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion librashader-runtime-mtl/tests/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ include!("./hello_triangle/main.rs");
#[test]
fn test_mtl() {
main()
}
}

0 comments on commit e24beed

Please sign in to comment.