wip

Junkui Zhang created

Change summary

crates/gpui/src/platform/windows/directx_renderer.rs | 195 ++++++++++++-
1 file changed, 175 insertions(+), 20 deletions(-)

Detailed changes

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::<PathSprite>(),
             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_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_indirect_draw_buffer,
+            &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::<DrawInstancedIndirectArgs>()) as u32,
             );
         }
@@ -488,13 +503,14 @@ impl DirectXRenderPipelines {
             std::mem::size_of::<Quad>(),
             32,
         )?;
-        let paths_pipeline = create_pipieline(
-            device,
-            "paths_vertex",
-            "paths_fragment",
-            std::mem::size_of::<PathSprite>(),
-            32,
-        )?;
+        // let paths_pipeline = create_pipieline(
+        //     device,
+        //     "paths_vertex",
+        //     "paths_fragment",
+        //     std::mem::size_of::<PathSprite>(),
+        //     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::<PolychromeSprite>(),
             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<ID3D11ShaderResourceView>; 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<ID3D11ShaderResourceView>; 1],
+    vertex_view: [Option<ID3D11ShaderResourceView>; 1],
+}
+
+impl PathsPipelineState {
+    fn new(device: &ID3D11Device) -> Result<Self> {
+        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::<PathSprite>(), 32)?;
+        let view = create_buffer_view(device, &buffer)?;
+        let vertex_buffer =
+            create_buffer(device, std::mem::size_of::<PathVertex<ScaledPixels>>(), 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<ID3D11ShaderResourceView>; 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::<PathSprite>(), 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<ID3D11ShaderResourceView>; 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::<PathVertex<ScaledPixels>>(),
+        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<ID3D11ShaderResourceView>; 1]),
@@ -1005,6 +1136,29 @@ fn update_pipeline(
     pipeline.view = input.2;
 }
 
+fn update_paths_pipeline_buffer(
+    pipeline: &mut PathsPipelineState,
+    input: (ID3D11Buffer, usize, [Option<ID3D11ShaderResourceView>; 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<ID3D11ShaderResourceView>; 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<T>(
     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<ID3D11Buffer>],
     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);