This commit is contained in:
Antonio Scandurra
2023-09-23 15:24:01 -06:00
parent 91c1768939
commit c4abd93b9b
3 changed files with 49 additions and 6 deletions
@@ -1,11 +1,11 @@
use crate::{point, size, Pixels, PointF, Quad, Scene, Size};
use crate::{point, size, Pixels, Quad, Scene, Size};
use bytemuck::{Pod, Zeroable};
use cocoa::{
base::{NO, YES},
foundation::NSUInteger,
quartzcore::AutoresizingMask,
};
use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
use metal::{CommandQueue, DepthStencilDescriptor, MTLPixelFormat, MTLResourceOptions, NSRange};
use objc::{self, msg_send, sel, sel_impl};
use std::{ffi::c_void, mem, ptr};
@@ -13,9 +13,11 @@ const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shader
const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value.
pub struct MetalRenderer {
device: metal::Device,
layer: metal::MetalLayer,
command_queue: CommandQueue,
quad_pipeline_state: metal::RenderPipelineState,
depth_state: metal::DepthStencilState,
unit_vertices: metal::Buffer,
instances: metal::Buffer,
}
@@ -86,10 +88,18 @@ impl MetalRenderer {
PIXEL_FORMAT,
);
let depth_stencil_descriptor = DepthStencilDescriptor::new();
depth_stencil_descriptor.set_depth_compare_function(metal::MTLCompareFunction::LessEqual);
depth_stencil_descriptor.set_depth_write_enabled(true);
let depth_state = device.new_depth_stencil_state(&depth_stencil_descriptor);
let command_queue = device.new_command_queue();
Self {
device,
layer,
command_queue: device.new_command_queue(),
command_queue,
quad_pipeline_state,
depth_state,
unit_vertices,
instances,
}
@@ -115,17 +125,32 @@ impl MetalRenderer {
};
let command_queue = self.command_queue.clone();
let command_buffer = command_queue.new_command_buffer();
let render_pass_descriptor = metal::RenderPassDescriptor::new();
let depth_texture_desc = metal::TextureDescriptor::new();
depth_texture_desc.set_pixel_format(metal::MTLPixelFormat::Depth32Float);
depth_texture_desc.set_storage_mode(metal::MTLStorageMode::Private);
depth_texture_desc.set_usage(metal::MTLTextureUsage::RenderTarget);
let depth_texture = self.device.new_texture(&depth_texture_desc);
let depth_attachment = render_pass_descriptor.depth_attachment().unwrap();
// depth_attachment.set_texture(Some(&depth_texture));
// depth_attachment.set_clear_depth(1.);
// depth_attachment.set_store_action(metal::MTLStoreAction::Store);
let color_attachment = render_pass_descriptor
.color_attachments()
.object_at(0)
.unwrap();
color_attachment.set_texture(Some(drawable.texture()));
color_attachment.set_load_action(metal::MTLLoadAction::Clear);
color_attachment.set_store_action(metal::MTLStoreAction::Store);
let alpha = if self.layer.is_opaque() { 1. } else { 0. };
color_attachment.set_clear_color(metal::MTLClearColor::new(0., 0., 0., alpha));
let command_encoder = command_buffer.new_render_command_encoder(render_pass_descriptor);
command_encoder.set_depth_stencil_state(&self.depth_state);
command_encoder.set_viewport(metal::MTLViewport {
originX: 0.0,
@@ -248,6 +273,7 @@ fn build_pipeline_state(
color_attachment.set_source_alpha_blend_factor(metal::MTLBlendFactor::One);
color_attachment.set_destination_rgb_blend_factor(metal::MTLBlendFactor::OneMinusSourceAlpha);
color_attachment.set_destination_alpha_blend_factor(metal::MTLBlendFactor::One);
// descriptor.set_depth_attachment_pixel_format(MTLPixelFormat::Depth32Float);
device
.new_render_pipeline_state(&descriptor)
+2 -1
View File
@@ -143,5 +143,6 @@ float4 hsla_to_rgba(Hsla hsla) {
}
float4 to_device_position(float2 pixel_position, uint order, uint max_order, float2 viewport_size) {
return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), (1. - order / max_order), 1.);
float z = 1. - ((float)order / ((float)max_order + 1.));
return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), z, 1.);
}
+18 -2
View File
@@ -18,7 +18,7 @@ use cocoa::{
};
use core_graphics::display::CGRect;
use ctor::ctor;
use foreign_types::{ForeignType, ForeignTypeRef};
use foreign_types::ForeignTypeRef;
use futures::channel::oneshot;
use objc::{
class,
@@ -1351,7 +1351,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
let scale_factor = window_state.scale_factor();
let mut scene = crate::Scene::new(scale_factor);
scene.insert(crate::Quad {
order: 0,
order: 2,
bounds: Bounds {
origin: point(10., 10.).map(px),
size: size(100., 100.).map(px),
@@ -1366,6 +1366,22 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
corner_radii: Default::default(),
border_widths: Default::default(),
});
scene.insert(crate::Quad {
order: 1,
bounds: Bounds {
origin: point(50., 10.).map(px),
size: size(100., 100.).map(px),
},
clip_bounds: Bounds {
origin: point(10., 10.).map(px),
size: size(100., 100.).map(px),
},
clip_corner_radii: Default::default(),
background: crate::rgb(0xff0000).into(),
border_color: Default::default(),
corner_radii: Default::default(),
border_widths: Default::default(),
});
dbg!("!!!!!!!!!");
window_state.renderer.draw(&scene);
}