rt(mtl): implement clear textures

This commit is contained in:
chyyran 2024-02-13 02:29:54 -05:00 committed by Ronny Chan
parent ab31abb3d7
commit bceb0623a3
3 changed files with 44 additions and 22 deletions

View file

@ -27,9 +27,9 @@ array-concat = "0.5.2"
bytemuck = { version = "1.12.3", features = ["derive"] }
rayon = "1.8.1"
#[dependencies.icrate]
#version = "0.1.0"
#features = ["AppKit", "AppKit_all", "Foundation", "Foundation_all", "MetalKit", "MetalKit_all", "Metal", "Metal_all"]
[dependencies.icrate]
version = "0.1.0"
features = ["AppKit", "AppKit_all", "Foundation", "Foundation_all", "MetalKit", "MetalKit_all", "Metal", "Metal_all"]
[[test]]
name = "triangle"
@ -40,7 +40,7 @@ harness = false
features = ["librashader-cache/docsrs"]
[target.'cfg(target_vendor="apple")'.dependencies]
icrate = { version = "0.1.0" , features = [ "Metal", "Metal_all" ]}
#icrate = { version = "0.1.0" , features = [ "Metal", "Metal_all" ]}
objc2 = { version = "0.5.0", features = ["apple"] }
#
#[lib]

View file

@ -10,8 +10,9 @@ use crate::samplers::SamplerSet;
use crate::texture::{get_texture_size, InputTexture, MetalOutputView, OwnedTexture};
use icrate::Foundation::NSString;
use icrate::Metal::{
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLPixelFormat,
MTLPixelFormatRGBA8Unorm, MTLResource, MTLTexture,
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLLoadActionClear,
MTLPixelFormat, MTLPixelFormatRGBA8Unorm, MTLRenderPassDescriptor, MTLResource,
MTLStoreActionDontCare, MTLStoreActionStore, MTLTexture,
};
use librashader_common::{ImageFormat, Size, Viewport};
use librashader_presets::context::VideoDriver;
@ -320,23 +321,50 @@ impl FilterChainMetal {
}
/// Records shader rendering commands to the provided command encoder.
///
/// SAFETY: The `MTLCommandBuffer` provided must not have an active encoder.
pub fn frame(
&mut self,
input: &ProtocolObject<dyn MTLTexture>,
viewport: &Viewport<MetalOutputView>,
cmd_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
frame_count: usize,
options: Option<&FrameOptionsMetal>,
) -> error::Result<()> {
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
let passes = &mut self.passes[0..max];
if let Some(options) = &options {
let desc = unsafe {
let desc = MTLRenderPassDescriptor::new();
desc.colorAttachments()
.objectAtIndexedSubscript(0)
.setLoadAction(MTLLoadActionClear);
desc.colorAttachments()
.objectAtIndexedSubscript(0)
.setStoreAction(MTLStoreActionDontCare);
desc
};
let clear_desc = unsafe { MTLRenderPassDescriptor::new() };
if options.clear_history {
for history in &mut self.history_framebuffers {
history.clear(cmd_buffer);
for (index, history) in self.history_framebuffers.iter().enumerate() {
unsafe {
let ca = clear_desc
.colorAttachments()
.objectAtIndexedSubscript(index);
ca.setTexture(Some(&history.texture));
ca.setLoadAction(MTLLoadActionClear);
ca.setStoreAction(MTLStoreActionStore);
}
}
}
let clearpass = cmd
.renderCommandEncoderWithDescriptor(&desc)
.ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
clearpass.endEncoding();
}
if passes.is_empty() {
return Ok(());
}
@ -410,7 +438,7 @@ impl FilterChainMetal {
let out = RenderTarget::identity(target.texture.as_ref());
pass.draw(
&cmd_buffer,
&cmd,
index,
&self.common,
pass.config.get_frame_count(frame_count),
@ -423,7 +451,7 @@ impl FilterChainMetal {
)?;
if target.max_miplevels > 1 && !self.disable_mipmaps {
target.generate_mipmaps(&cmd_buffer)?;
target.generate_mipmaps(&cmd)?;
}
source = self.common.output_textures[index]
@ -448,7 +476,7 @@ impl FilterChainMetal {
let output_image = viewport.output;
let out = RenderTarget::viewport_with_output(output_image, viewport);
pass.draw(
&cmd_buffer,
&cmd,
passes_len - 1,
&self.common,
pass.config.get_frame_count(frame_count),
@ -461,7 +489,7 @@ impl FilterChainMetal {
)?;
}
self.push_history(&input, &cmd_buffer)?;
self.push_history(&input, &cmd)?;
self.common.internal_frame_count = self.common.internal_frame_count.wrapping_add(1);
Ok(())
}

View file

@ -1,8 +1,9 @@
use crate::error::{FilterChainError, Result};
use crate::select_optimal_pixel_format;
use icrate::Metal::{
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLDevice, MTLPixelFormat,
MTLTexture, MTLTextureDescriptor, MTLTextureUsageRenderTarget, MTLTextureUsageShaderRead,
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLDevice,
MTLParallelRenderCommandEncoder, MTLPixelFormat, MTLRenderCommandEncoder, MTLTexture,
MTLTextureDescriptor, MTLTextureUsageRenderTarget, MTLTextureUsageShaderRead,
MTLTextureUsageShaderWrite,
};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
@ -137,13 +138,6 @@ impl OwnedTexture {
Ok(())
}
pub fn clear(&self, cmd: &ProtocolObject<dyn MTLCommandBuffer>) {
// let render = cmd.renderCommandEncoder()
// .ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
// render.
// cmd.clear_texture(&self.image, &wgpu::ImageSubresourceRange::default());
}
pub fn generate_mipmaps(&self, cmd: &ProtocolObject<dyn MTLCommandBuffer>) -> Result<()> {
let mipmapper = cmd
.blitCommandEncoder()