From dcdd7404e46d97f1a4e7ed7b74c7caa018227772 Mon Sep 17 00:00:00 2001 From: Junkui Zhang <364772080@qq.com> Date: Mon, 14 Jul 2025 16:47:45 +0800 Subject: [PATCH] wip --- .../src/platform/windows/directx_renderer.rs | 195 ++++++++++++++++-- 1 file changed, 175 insertions(+), 20 deletions(-) diff --git a/crates/gpui/src/platform/windows/directx_renderer.rs b/crates/gpui/src/platform/windows/directx_renderer.rs index 36c68c8eb4..ed2ec0a8c9 100644 --- a/crates/gpui/src/platform/windows/directx_renderer.rs +++ b/crates/gpui/src/platform/windows/directx_renderer.rs @@ -48,8 +48,7 @@ struct DirectXContext { struct DirectXRenderPipelines { shadow_pipeline: PipelineState, quad_pipeline: PipelineState, - paths_pipeline: PipelineState, - paths_indirect_draw_buffer: ID3D11Buffer, + paths_pipeline: PathsPipelineState, underline_pipeline: PipelineState, mono_sprites: PipelineState, poly_sprites: PipelineState, @@ -309,21 +308,37 @@ impl DirectXRenderer { }); } - update_buffer_capacity( + update_paths_buffer_capacity( &self.pipelines.paths_pipeline, - std::mem::size_of::(), sprites.len(), &self.devices.device, ) - .map(|input| update_pipeline(&mut self.pipelines.paths_pipeline, input)); + .map(|input| update_paths_pipeline_buffer(&mut self.pipelines.paths_pipeline, input)); update_buffer( &self.devices.device_context, &self.pipelines.paths_pipeline.buffer, &sprites, )?; - update_indirect_buffer( + update_paths_vertex_capacity( + &mut self.pipelines.paths_pipeline, + vertices.len(), + &self.devices.device, + ) + .map(|input| update_paths_pipeline_vertex(&mut self.pipelines.paths_pipeline, input)); + update_buffer( &self.devices.device_context, - &self.pipelines.paths_indirect_draw_buffer, + &self.pipelines.paths_pipeline.vertex_buffer, + &vertices, + )?; + update_indirect_buffer_capacity( + &self.pipelines.paths_pipeline, + draw_indirect_commands.len(), + &self.devices.device, + ) + .map(|input| update_paths_indirect_buffer(&mut self.pipelines.paths_pipeline, input)); + update_buffer( + &self.devices.device_context, + &self.pipelines.paths_pipeline.indirect_draw_buffer, &draw_indirect_commands, )?; prepare_indirect_draws( @@ -337,7 +352,7 @@ impl DirectXRenderer { for i in 0..paths.len() { draw_indirect( &self.devices.device_context, - &self.pipelines.paths_indirect_draw_buffer, + &self.pipelines.paths_pipeline.indirect_draw_buffer, (i * std::mem::size_of::()) as u32, ); } @@ -488,13 +503,14 @@ impl DirectXRenderPipelines { std::mem::size_of::(), 32, )?; - let paths_pipeline = create_pipieline( - device, - "paths_vertex", - "paths_fragment", - std::mem::size_of::(), - 32, - )?; + // let paths_pipeline = create_pipieline( + // device, + // "paths_vertex", + // "paths_fragment", + // std::mem::size_of::(), + // 32, + // )?; + let paths_pipeline = PathsPipelineState::new(device)?; let underline_pipeline = create_pipieline( device, "underline_vertex", @@ -516,13 +532,11 @@ impl DirectXRenderPipelines { std::mem::size_of::(), 32, )?; - let paths_indirect_draw_buffer = create_indirect_draw_buffer(device, 32)?; Ok(Self { shadow_pipeline, quad_pipeline, paths_pipeline, - paths_indirect_draw_buffer, underline_pipeline, mono_sprites, poly_sprites, @@ -614,6 +628,62 @@ struct PipelineState { view: [Option; 1], } +struct PathsPipelineState { + vertex: ID3D11VertexShader, + fragment: ID3D11PixelShader, + buffer: ID3D11Buffer, + buffer_size: usize, + vertex_buffer: ID3D11Buffer, + vertex_buffer_size: usize, + indirect_draw_buffer: ID3D11Buffer, + indirect_buffer_size: usize, + view: [Option; 1], + vertex_view: [Option; 1], +} + +impl PathsPipelineState { + fn new(device: &ID3D11Device) -> Result { + let vertex = { + let shader_blob = shader_resources::build_shader_blob("paths_vertex", "vs_5_0")?; + let bytes = unsafe { + std::slice::from_raw_parts( + shader_blob.GetBufferPointer() as *mut u8, + shader_blob.GetBufferSize(), + ) + }; + create_vertex_shader(device, bytes)? + }; + let fragment = { + let shader_blob = shader_resources::build_shader_blob("paths_fragment", "ps_5_0")?; + let bytes = unsafe { + std::slice::from_raw_parts( + shader_blob.GetBufferPointer() as *mut u8, + shader_blob.GetBufferSize(), + ) + }; + create_fragment_shader(device, bytes)? + }; + let buffer = create_buffer(device, std::mem::size_of::(), 32)?; + let view = create_buffer_view(device, &buffer)?; + let vertex_buffer = + create_buffer(device, std::mem::size_of::>(), 32)?; + let vertex_view = create_buffer_view(device, &vertex_buffer)?; + let indirect_draw_buffer = create_indirect_draw_buffer(device, 32)?; + Ok(Self { + vertex, + fragment, + buffer, + buffer_size: 32, + vertex_buffer, + vertex_buffer_size: 32, + indirect_draw_buffer, + indirect_buffer_size: 32, + view, + vertex_view, + }) + } +} + #[derive(Clone, Debug, Eq, PartialEq)] #[repr(C)] struct PathSprite { @@ -996,6 +1066,67 @@ fn update_buffer_capacity( Some((buffer, buffer_size, view)) } +fn update_paths_buffer_capacity( + pipeline: &PathsPipelineState, + data_size: usize, + device: &ID3D11Device, +) -> Option<(ID3D11Buffer, usize, [Option; 1])> { + if pipeline.buffer_size >= data_size { + return None; + } + println!( + "Paths buffer too small: {} < {}", + pipeline.buffer_size, data_size + ); + let buffer_size = data_size.next_power_of_two(); + println!("Paths New size: {}", buffer_size); + let buffer = create_buffer(device, std::mem::align_of::(), buffer_size).unwrap(); + let view = create_buffer_view(device, &buffer).unwrap(); + Some((buffer, buffer_size, view)) +} + +fn update_paths_vertex_capacity( + pipeline: &PathsPipelineState, + vertex_size: usize, + device: &ID3D11Device, +) -> Option<(ID3D11Buffer, usize, [Option; 1])> { + if pipeline.vertex_buffer_size >= vertex_size { + return None; + } + println!( + "Paths vertex buffer too small: {} < {}", + pipeline.vertex_buffer_size, vertex_size + ); + let vertex_size = vertex_size.next_power_of_two(); + println!("Paths vertex New size: {}", vertex_size); + let buffer = create_buffer( + device, + std::mem::size_of::>(), + vertex_size, + ) + .unwrap(); + let view = create_buffer_view(device, &buffer).unwrap(); + Some((buffer, vertex_size, view)) +} + +fn update_indirect_buffer_capacity( + pipeline: &PathsPipelineState, + data_size: usize, + device: &ID3D11Device, +) -> Option<(ID3D11Buffer, usize)> { + if pipeline.indirect_buffer_size >= data_size { + return None; + } + println!( + "Indirect buffer too small: {} < {}", + pipeline.indirect_buffer_size, data_size + ); + let buffer_size = data_size.next_power_of_two(); + println!("Indirect New size: {}", buffer_size); + let buffer = create_indirect_draw_buffer(device, data_size as u32).unwrap(); + Some((buffer, buffer_size)) +} + fn update_pipeline( pipeline: &mut PipelineState, input: (ID3D11Buffer, usize, [Option; 1]), @@ -1005,6 +1136,29 @@ fn update_pipeline( pipeline.view = input.2; } +fn update_paths_pipeline_buffer( + pipeline: &mut PathsPipelineState, + input: (ID3D11Buffer, usize, [Option; 1]), +) { + pipeline.buffer = input.0; + pipeline.buffer_size = input.1; + pipeline.view = input.2; +} + +fn update_paths_pipeline_vertex( + pipeline: &mut PathsPipelineState, + input: (ID3D11Buffer, usize, [Option; 1]), +) { + pipeline.vertex_buffer = input.0; + pipeline.vertex_buffer_size = input.1; + pipeline.vertex_view = input.2; +} + +fn update_paths_indirect_buffer(pipeline: &mut PathsPipelineState, input: (ID3D11Buffer, usize)) { + pipeline.indirect_draw_buffer = input.0; + pipeline.indirect_buffer_size = input.1; +} + fn update_buffer( device_context: &ID3D11DeviceContext, buffer: &ID3D11Buffer, @@ -1035,14 +1189,15 @@ fn update_indirect_buffer( fn prepare_indirect_draws( device_context: &ID3D11DeviceContext, - pipeline: &PipelineState, + pipeline: &PathsPipelineState, viewport: &[D3D11_VIEWPORT], global_params: &[Option], topology: D3D_PRIMITIVE_TOPOLOGY, ) -> Result<()> { unsafe { - device_context.VSSetShaderResources(1, Some(&pipeline.view)); - device_context.PSSetShaderResources(1, Some(&pipeline.view)); + device_context.VSSetShaderResources(1, Some(&pipeline.vertex_view)); + device_context.VSSetShaderResources(2, Some(&pipeline.view)); + device_context.PSSetShaderResources(2, Some(&pipeline.view)); device_context.IASetPrimitiveTopology(topology); device_context.RSSetViewports(Some(viewport)); device_context.VSSetShader(&pipeline.vertex, None);