rt(mtl): properly bind push buffer and select bgra8 in place of rgba8
This commit is contained in:
parent
43da6e60c6
commit
05f634a9b9
9 changed files with 80 additions and 39 deletions
|
@ -1,8 +1,8 @@
|
|||
use crate::error;
|
||||
use crate::error::FilterChainError;
|
||||
use icrate::Foundation::NSRange;
|
||||
use icrate::Foundation::{NSRange, NSString};
|
||||
use icrate::Metal::{
|
||||
MTLBuffer, MTLDevice, MTLResourceStorageModeManaged, MTLResourceStorageModeShared,
|
||||
MTLBuffer, MTLDevice, MTLResource, MTLResourceStorageModeManaged, MTLResourceStorageModeShared,
|
||||
};
|
||||
use objc2::rc::Id;
|
||||
use objc2::runtime::ProtocolObject;
|
||||
|
@ -20,7 +20,11 @@ impl AsRef<ProtocolObject<dyn MTLBuffer>> for MetalBuffer {
|
|||
}
|
||||
|
||||
impl MetalBuffer {
|
||||
pub fn new(device: &ProtocolObject<dyn MTLDevice>, size: usize) -> error::Result<Self> {
|
||||
pub fn new(
|
||||
device: &ProtocolObject<dyn MTLDevice>,
|
||||
size: usize,
|
||||
label: &str,
|
||||
) -> error::Result<Self> {
|
||||
let resource_mode = if cfg!(target_os = "ios") {
|
||||
MTLResourceStorageModeShared
|
||||
} else {
|
||||
|
@ -30,6 +34,9 @@ impl MetalBuffer {
|
|||
let buffer = device
|
||||
.newBufferWithLength_options(size, resource_mode)
|
||||
.ok_or(FilterChainError::BufferError)?;
|
||||
|
||||
buffer.setLabel(Some(&*NSString::from_str(label)));
|
||||
|
||||
Ok(Self { buffer, size })
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ const OFFSCREEN_VBO_DATA: [MetalVertex; 4] = [
|
|||
},
|
||||
];
|
||||
|
||||
|
||||
const FINAL_VBO_DATA: [MetalVertex; 4] = [
|
||||
MetalVertex {
|
||||
position: [0.0, 0.0, 0.0, 1.0],
|
||||
|
@ -130,9 +129,7 @@ impl DrawQuad {
|
|||
|
||||
unsafe {
|
||||
cmd.setVertexBuffer_offset_atIndex(Some(&self.buffer), 0, VERTEX_BUFFER_INDEX);
|
||||
cmd.drawPrimitives_vertexStart_vertexCount(MTLPrimitiveTypeTriangleStrip,
|
||||
offset,
|
||||
4);
|
||||
cmd.drawPrimitives_vertexStart_vertexCount(MTLPrimitiveTypeTriangleStrip, offset, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,10 @@ use crate::luts::LutTexture;
|
|||
use crate::options::{FilterChainOptionsMetal, FrameOptionsMetal};
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{get_texture_size, InputTexture, OwnedTexture};
|
||||
use icrate::Foundation::NSString;
|
||||
use icrate::Metal::{
|
||||
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice,
|
||||
MTLPixelFormat, MTLPixelFormatRGBA8Unorm, MTLTexture,
|
||||
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLPixelFormat,
|
||||
MTLPixelFormatRGBA8Unorm, MTLResource, MTLTexture,
|
||||
};
|
||||
use librashader_common::{ImageFormat, Size, Viewport};
|
||||
use librashader_presets::context::VideoDriver;
|
||||
|
@ -59,7 +60,7 @@ pub struct FilterChainMetal {
|
|||
feedback_framebuffers: Box<[OwnedTexture]>,
|
||||
history_framebuffers: VecDeque<OwnedTexture>,
|
||||
disable_mipmaps: bool,
|
||||
default_options: FrameOptionsMetal
|
||||
default_options: FrameOptionsMetal,
|
||||
}
|
||||
|
||||
impl Debug for FilterChainMetal {
|
||||
|
@ -160,8 +161,8 @@ impl FilterChainMetal {
|
|||
.map_or(0, |push| push.size);
|
||||
|
||||
let uniform_storage = UniformStorage::new_with_storage(
|
||||
MetalBuffer::new(&device, ubo_size)?,
|
||||
MetalBuffer::new(&device, push_size as usize)?,
|
||||
MetalBuffer::new(&device, ubo_size, "ubo")?,
|
||||
MetalBuffer::new(&device, push_size as usize, "pcb")?,
|
||||
);
|
||||
|
||||
let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset());
|
||||
|
@ -366,6 +367,9 @@ impl FilterChainMetal {
|
|||
|
||||
let mut source = original.try_clone()?;
|
||||
|
||||
source
|
||||
.texture
|
||||
.setLabel(Some(&*NSString::from_str("sourcetex")));
|
||||
// swap output and feedback **before** recording command buffers
|
||||
std::mem::swap(
|
||||
&mut self.output_framebuffers,
|
||||
|
@ -404,8 +408,7 @@ impl FilterChainMetal {
|
|||
source.wrap_mode = pass.config.wrap_mode;
|
||||
source.mip_filter = pass.config.filter;
|
||||
|
||||
let out =
|
||||
RenderTarget::identity(target.texture.as_ref());
|
||||
let out = RenderTarget::identity(target.texture.as_ref());
|
||||
pass.draw(
|
||||
&cmd_buffer,
|
||||
index,
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::buffer::MetalBuffer;
|
|||
use crate::error;
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::graphics_pipeline::MetalGraphicsPipeline;
|
||||
use crate::options::FrameOptionsMetal;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{get_texture_size, InputTexture};
|
||||
use icrate::Metal::{MTLCommandBuffer, MTLCommandEncoder, MTLRenderCommandEncoder, MTLTexture};
|
||||
|
@ -17,7 +18,6 @@ use librashader_runtime::render_target::RenderTarget;
|
|||
use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage};
|
||||
use objc2::runtime::ProtocolObject;
|
||||
use rustc_hash::FxHashMap;
|
||||
use crate::options::FrameOptionsMetal;
|
||||
|
||||
impl TextureInput for InputTexture {
|
||||
fn size(&self) -> Size<u32> {
|
||||
|
@ -106,12 +106,12 @@ impl FilterPass {
|
|||
unsafe {
|
||||
// SPIRV-Cross always has PCB bound to 1. Naga is arbitrary but their compilation provides the next free binding for drawquad.
|
||||
cmd.setVertexBuffer_offset_atIndex(
|
||||
Some(self.uniform_storage.inner_ubo().as_ref()),
|
||||
Some(self.uniform_storage.inner_push().as_ref()),
|
||||
0,
|
||||
pcb.binding.unwrap_or(1) as usize,
|
||||
);
|
||||
cmd.setFragmentBuffer_offset_atIndex(
|
||||
Some(self.uniform_storage.inner_ubo().as_ref()),
|
||||
Some(self.uniform_storage.inner_push().as_ref()),
|
||||
0,
|
||||
pcb.binding.unwrap_or(1) as usize,
|
||||
)
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
use std::mem::offset_of;
|
||||
use crate::draw_quad::MetalVertex;
|
||||
use crate::error::{FilterChainError, Result};
|
||||
use crate::select_optimal_pixel_format;
|
||||
use icrate::Foundation::NSString;
|
||||
use icrate::Metal::{MTLBlendFactorOneMinusSourceAlpha, MTLBlendFactorSourceAlpha, MTLClearColor, MTLCommandBuffer, MTLDevice, MTLFunction, MTLLibrary, MTLLoadActionDontCare, MTLPixelFormat, MTLPrimitiveTopologyClassTriangle, MTLRenderCommandEncoder, MTLRenderPassDescriptor, MTLRenderPipelineColorAttachmentDescriptor, MTLRenderPipelineDescriptor, MTLRenderPipelineState, MTLScissorRect, MTLStoreActionStore, MTLTexture, MTLVertexAttributeDescriptor, MTLVertexBufferLayoutDescriptor, MTLVertexDescriptor, MTLVertexFormatFloat2, MTLVertexFormatFloat4, MTLVertexStepFunctionPerVertex, MTLViewport};
|
||||
use icrate::Metal::{
|
||||
MTLBlendFactorOneMinusSourceAlpha, MTLBlendFactorSourceAlpha, MTLClearColor, MTLCommandBuffer,
|
||||
MTLCommandEncoder, MTLDevice, MTLFunction, MTLLibrary, MTLLoadActionDontCare, MTLPixelFormat,
|
||||
MTLPrimitiveTopologyClassTriangle, MTLRenderCommandEncoder, MTLRenderPassDescriptor,
|
||||
MTLRenderPipelineColorAttachmentDescriptor, MTLRenderPipelineDescriptor,
|
||||
MTLRenderPipelineState, MTLScissorRect, MTLStoreActionStore, MTLTexture,
|
||||
MTLVertexAttributeDescriptor, MTLVertexBufferLayoutDescriptor, MTLVertexDescriptor,
|
||||
MTLVertexFormatFloat2, MTLVertexFormatFloat4, MTLVertexStepFunctionPerVertex, MTLViewport,
|
||||
};
|
||||
use librashader_reflect::back::msl::{CrossMslContext, NagaMslContext};
|
||||
use librashader_reflect::back::ShaderCompilerOutput;
|
||||
use librashader_runtime::render_target::RenderTarget;
|
||||
use objc2::rc::Id;
|
||||
use objc2::runtime::ProtocolObject;
|
||||
use crate::draw_quad::MetalVertex;
|
||||
use std::mem::offset_of;
|
||||
|
||||
/// This is only really plausible for SPIRV-Cross, for Naga we need to supply the next plausible binding.
|
||||
pub const VERTEX_BUFFER_INDEX: usize = 4;
|
||||
|
@ -99,10 +108,10 @@ impl PipelineLayoutObjects {
|
|||
}
|
||||
|
||||
unsafe fn create_color_attachments(
|
||||
ca: Id<MTLRenderPipelineColorAttachmentDescriptor>,
|
||||
format: MTLPixelFormat,
|
||||
) -> Id<MTLRenderPipelineColorAttachmentDescriptor> {
|
||||
let ca = MTLRenderPipelineColorAttachmentDescriptor::new();
|
||||
ca.setPixelFormat(format);
|
||||
ca.setPixelFormat(select_optimal_pixel_format(format));
|
||||
ca.setBlendingEnabled(false);
|
||||
ca.setSourceAlphaBlendFactor(MTLBlendFactorSourceAlpha);
|
||||
ca.setSourceRGBBlendFactor(MTLBlendFactorSourceAlpha);
|
||||
|
@ -121,14 +130,11 @@ impl PipelineLayoutObjects {
|
|||
|
||||
unsafe {
|
||||
let vertex = Self::create_vertex_descriptor();
|
||||
let ca = Self::create_color_attachments(format);
|
||||
|
||||
descriptor.setInputPrimitiveTopology(MTLPrimitiveTopologyClassTriangle);
|
||||
descriptor.setVertexDescriptor(Some(&vertex));
|
||||
|
||||
descriptor
|
||||
.colorAttachments()
|
||||
.setObject_atIndexedSubscript(Some(&ca), 0);
|
||||
let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0);
|
||||
Self::create_color_attachments(ca, format);
|
||||
|
||||
descriptor.setRasterSampleCount(1);
|
||||
|
||||
|
@ -172,8 +178,7 @@ impl MetalGraphicsPipeline {
|
|||
) -> Result<Id<ProtocolObject<dyn MTLRenderCommandEncoder>>> {
|
||||
unsafe {
|
||||
let descriptor = MTLRenderPassDescriptor::new();
|
||||
let ca = descriptor.colorAttachments()
|
||||
.objectAtIndexedSubscript(0);
|
||||
let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0);
|
||||
ca.setLoadAction(MTLLoadActionDontCare);
|
||||
ca.setStoreAction(MTLStoreActionStore);
|
||||
ca.setTexture(Some(output.output));
|
||||
|
@ -182,6 +187,9 @@ impl MetalGraphicsPipeline {
|
|||
.renderCommandEncoderWithDescriptor(&descriptor)
|
||||
.ok_or(FilterChainError::FailedToCreateRenderPass)?;
|
||||
|
||||
rpass.setLabel(Some(&*NSString::from_str("librashader rpass")));
|
||||
rpass.setRenderPipelineState(&self.render_pipeline);
|
||||
|
||||
rpass.setScissorRect(MTLScissorRect {
|
||||
x: output.x as usize,
|
||||
y: output.y as usize,
|
||||
|
@ -198,8 +206,6 @@ impl MetalGraphicsPipeline {
|
|||
zfar: 1.0,
|
||||
});
|
||||
|
||||
rpass.setRenderPipelineState(&self.render_pipeline);
|
||||
|
||||
Ok(rpass)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,23 @@ mod samplers;
|
|||
mod texture;
|
||||
|
||||
pub use filter_chain::FilterChainMetal;
|
||||
use icrate::Metal::{
|
||||
MTLPixelFormat, MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB,
|
||||
MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB,
|
||||
};
|
||||
|
||||
pub mod error;
|
||||
pub mod options;
|
||||
use librashader_runtime::impl_filter_chain_parameters;
|
||||
impl_filter_chain_parameters!(FilterChainMetal);
|
||||
|
||||
fn select_optimal_pixel_format(format: MTLPixelFormat) -> MTLPixelFormat {
|
||||
if format == MTLPixelFormatRGBA8Unorm {
|
||||
return MTLPixelFormatBGRA8Unorm;
|
||||
}
|
||||
|
||||
if format == MTLPixelFormatRGBA8Unorm_sRGB {
|
||||
return MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,12 @@
|
|||
use core::{cell::OnceCell, ptr::NonNull};
|
||||
use std::sync::RwLock;
|
||||
|
||||
use icrate::Metal::{MTLBlitCommandEncoder, MTLClearColor, MTLPixelFormatRGBA8Unorm, MTLTexture, MTLTextureDescriptor, MTLTextureUsagePixelFormatView, MTLTextureUsageRenderTarget, MTLTextureUsageShaderRead};
|
||||
use icrate::Foundation::NSString;
|
||||
use icrate::Metal::{
|
||||
MTLBlitCommandEncoder, MTLClearColor, MTLPixelFormatRGBA8Unorm, MTLResource, MTLTexture,
|
||||
MTLTextureDescriptor, MTLTextureUsagePixelFormatView, MTLTextureUsageRenderTarget,
|
||||
MTLTextureUsageShaderRead,
|
||||
};
|
||||
use icrate::{
|
||||
AppKit::{
|
||||
NSApplication, NSApplicationActivationPolicyRegular, NSApplicationDelegate,
|
||||
|
@ -218,11 +223,10 @@ declare_class!(
|
|||
let pipeline_state = device
|
||||
.newRenderPipelineStateWithDescriptor_error(&pipeline_descriptor)
|
||||
.expect("Failed to create a pipeline state.");
|
||||
|
||||
// let preset = ShaderPreset::try_parse("./test/shaders_slang/crt/crt-lottes.slangp").unwrap();
|
||||
|
||||
// let preset = ShaderPreset::try_parse("./test/shaders_slang/crt/crt-lottes.slangp").unwrap();
|
||||
let preset = ShaderPreset::try_parse("./test/basic.slangp").unwrap();
|
||||
let preset = ShaderPreset::try_parse("./test/shaders_slang/crt/crt-royale.slangp").unwrap();
|
||||
// let preset = ShaderPreset::try_parse("./test/basic.slangp").unwrap();
|
||||
|
||||
let filter_chain = FilterChainMetal::load_from_preset(
|
||||
preset,
|
||||
|
@ -389,11 +393,16 @@ declare_class!(
|
|||
.newTextureWithDescriptor(&tex_desc)
|
||||
.unwrap();
|
||||
|
||||
frontbuffer
|
||||
.setLabel(Some(&*NSString::from_str("librashader frontbuffer")));
|
||||
|
||||
let backbuffer = command_queue
|
||||
.device()
|
||||
.newTextureWithDescriptor(&tex_desc)
|
||||
.unwrap();
|
||||
|
||||
backbuffer
|
||||
.setLabel(Some(&*NSString::from_str("librashader backbuffer")));
|
||||
let blit = command_buffer
|
||||
.blitCommandEncoder()
|
||||
.unwrap();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::error::{FilterChainError, Result};
|
||||
use crate::select_optimal_pixel_format;
|
||||
use icrate::Metal::{
|
||||
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLDevice, MTLPixelFormat,
|
||||
MTLTexture, MTLTextureDescriptor, MTLTextureUsageRenderTarget, MTLTextureUsageShaderRead,
|
||||
|
@ -54,7 +55,7 @@ impl OwnedTexture {
|
|||
let descriptor = unsafe {
|
||||
let descriptor =
|
||||
MTLTextureDescriptor::texture2DDescriptorWithPixelFormat_width_height_mipmapped(
|
||||
format,
|
||||
select_optimal_pixel_format(format),
|
||||
size.width as usize,
|
||||
size.height as usize,
|
||||
max_miplevels <= 1,
|
||||
|
@ -102,7 +103,7 @@ impl OwnedTexture {
|
|||
if self.size != size
|
||||
|| (mipmap && self.max_miplevels == 1)
|
||||
|| (!mipmap && self.max_miplevels != 1)
|
||||
|| format != self.texture.pixelFormat()
|
||||
|| format != select_optimal_pixel_format(format)
|
||||
{
|
||||
let mut new = OwnedTexture::new(device, size, self.max_miplevels, format)?;
|
||||
std::mem::swap(self, &mut new);
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
use core::{cell::OnceCell, ptr::NonNull};
|
||||
use std::sync::RwLock;
|
||||
|
||||
use icrate::Metal::{MTLBlitCommandEncoder, MTLClearColor, MTLTexture, MTLTextureDescriptor, MTLTextureUsageRenderTarget};
|
||||
use icrate::Metal::{
|
||||
MTLBlitCommandEncoder, MTLClearColor, MTLTexture, MTLTextureDescriptor,
|
||||
MTLTextureUsageRenderTarget,
|
||||
};
|
||||
use icrate::{
|
||||
AppKit::{
|
||||
NSApplication, NSApplicationActivationPolicyRegular, NSApplicationDelegate,
|
||||
|
|
Loading…
Add table
Reference in a new issue