From c4abd93b9ba9bb0d6fc283c8cb21e6aa2f452218 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 23 Sep 2023 15:24:01 -0600 Subject: [PATCH] WIP --- .../gpui3/src/platform/mac/metal_renderer.rs | 32 +++++++++++++++++-- crates/gpui3/src/platform/mac/shaders.metal | 3 +- crates/gpui3/src/platform/mac/window.rs | 20 ++++++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/crates/gpui3/src/platform/mac/metal_renderer.rs b/crates/gpui3/src/platform/mac/metal_renderer.rs index ac301b24d67ad2ecd4363c1a58a2261f34e8141d..a4f51d9b33fa2fb2a0b4965c517e9583222f61a9 100644 --- a/crates/gpui3/src/platform/mac/metal_renderer.rs +++ b/crates/gpui3/src/platform/mac/metal_renderer.rs @@ -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) diff --git a/crates/gpui3/src/platform/mac/shaders.metal b/crates/gpui3/src/platform/mac/shaders.metal index 1506d8f05240d5e7c62a8d663c9370cff0d1a663..0bd5abd8f6a595b9ccff3f611df7c2c1b7ccd97e 100644 --- a/crates/gpui3/src/platform/mac/shaders.metal +++ b/crates/gpui3/src/platform/mac/shaders.metal @@ -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.); } diff --git a/crates/gpui3/src/platform/mac/window.rs b/crates/gpui3/src/platform/mac/window.rs index 59fc750daedd2ac7ab968fd31004cbea99c79eac..3c14129f03d15a04dcc6c4f0c50ac013ecfd2f59 100644 --- a/crates/gpui3/src/platform/mac/window.rs +++ b/crates/gpui3/src/platform/mac/window.rs @@ -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); }