refactor

Junkui Zhang created

Change summary

crates/gpui/src/platform/windows/directx_renderer.rs | 285 +++++--------
1 file changed, 112 insertions(+), 173 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/directx_renderer.rs 🔗

@@ -285,59 +285,19 @@ impl DirectXRenderer {
             });
         }
 
-        update_paths_buffer_capacity(
-            &self.pipelines.paths_pipeline,
-            sprites.len(),
+        self.pipelines.paths_pipeline.update_buffer(
             &self.devices.device,
-        )
-        .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_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
-                .as_ref()
-                .unwrap(),
             &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(
+        self.pipelines.paths_pipeline.draw(
             &self.devices.device_context,
-            &self.pipelines.paths_pipeline,
+            paths.len(),
             &self.context.viewport,
             &self.globals.global_params_buffer,
-            D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
-        )?;
-
-        for i in 0..paths.len() {
-            draw_indirect(
-                &self.devices.device_context,
-                &self.pipelines.paths_pipeline.indirect_draw_buffer,
-                (i * std::mem::size_of::<DrawInstancedIndirectArgs>()) as u32,
-            );
-        }
-        Ok(())
+        )
     }
 
     fn draw_underlines(&mut self, underlines: &[Underline]) -> Result<()> {
@@ -634,18 +594,19 @@ impl<T> PipelineState<T> {
     ) -> Result<()> {
         if self.buffer_size < data.len() {
             let new_buffer_size = data.len().next_power_of_two();
+            log::info!(
+                "Updating {} buffer size from {} to {}",
+                self.label,
+                self.buffer_size,
+                new_buffer_size
+            );
             let buffer = create_buffer(device, std::mem::size_of::<T>(), new_buffer_size)?;
             let view = create_buffer_view(device, &buffer)?;
             self.buffer = buffer;
             self.view = view;
+            self.buffer_size = new_buffer_size;
         }
-        unsafe {
-            let mut dest = std::mem::zeroed();
-            device_context.Map(&self.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut dest))?;
-            std::ptr::copy_nonoverlapping(data.as_ptr(), dest.pData as _, data.len());
-            device_context.Unmap(&self.buffer, 0);
-        }
-        Ok(())
+        update_buffer(device_context, &self.buffer, data)
     }
 
     fn draw(
@@ -784,6 +745,101 @@ impl PathsPipelineState {
             view,
         })
     }
+
+    fn update_buffer(
+        &mut self,
+        device: &ID3D11Device,
+        device_context: &ID3D11DeviceContext,
+        buffer_data: &[PathSprite],
+        vertices_data: &[PathVertex<ScaledPixels>],
+        draw_commands: &[DrawInstancedIndirectArgs],
+    ) -> Result<()> {
+        if self.buffer_size < buffer_data.len() {
+            let new_buffer_size = buffer_data.len().next_power_of_two();
+            log::info!(
+                "Updating Paths Pipeline buffer size from {} to {}",
+                self.buffer_size,
+                new_buffer_size
+            );
+            let buffer = create_buffer(device, std::mem::size_of::<PathSprite>(), new_buffer_size)?;
+            let view = create_buffer_view(device, &buffer)?;
+            self.buffer = buffer;
+            self.view = view;
+            self.buffer_size = new_buffer_size;
+        }
+        update_buffer(device_context, &self.buffer, buffer_data)?;
+        if self.vertex_buffer_size < vertices_data.len() {
+            let new_vertex_buffer_size = vertices_data.len().next_power_of_two();
+            log::info!(
+                "Updating Paths Pipeline vertex buffer size from {} to {}",
+                self.vertex_buffer_size,
+                new_vertex_buffer_size
+            );
+            let vertex_buffer = create_buffer(
+                device,
+                std::mem::size_of::<PathVertex<ScaledPixels>>(),
+                new_vertex_buffer_size,
+            )?;
+            self.vertex_buffer = Some(vertex_buffer);
+            self.vertex_buffer_size = new_vertex_buffer_size;
+        }
+        update_buffer(
+            device_context,
+            self.vertex_buffer.as_ref().unwrap(),
+            vertices_data,
+        )?;
+        if self.indirect_buffer_size < draw_commands.len() {
+            let new_indirect_buffer_size = draw_commands.len().next_power_of_two();
+            log::info!(
+                "Updating Paths Pipeline indirect buffer size from {} to {}",
+                self.indirect_buffer_size,
+                new_indirect_buffer_size
+            );
+            let indirect_draw_buffer =
+                create_indirect_draw_buffer(device, new_indirect_buffer_size)?;
+            self.indirect_draw_buffer = indirect_draw_buffer;
+            self.indirect_buffer_size = new_indirect_buffer_size;
+        }
+        update_buffer(device_context, &self.indirect_draw_buffer, draw_commands)?;
+        Ok(())
+    }
+
+    fn draw(
+        &self,
+        device_context: &ID3D11DeviceContext,
+        count: usize,
+        viewport: &[D3D11_VIEWPORT],
+        global_params: &[Option<ID3D11Buffer>],
+    ) -> Result<()> {
+        unsafe {
+            device_context.VSSetShaderResources(1, Some(&self.view));
+            device_context.PSSetShaderResources(1, Some(&self.view));
+            device_context.IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+            device_context.RSSetViewports(Some(viewport));
+            device_context.VSSetShader(&self.vertex, None);
+            device_context.PSSetShader(&self.fragment, None);
+            device_context.VSSetConstantBuffers(0, Some(global_params));
+            device_context.PSSetConstantBuffers(0, Some(global_params));
+            const STRIDE: u32 = std::mem::size_of::<PathVertex<ScaledPixels>>() as u32;
+            device_context.IASetVertexBuffers(
+                0,
+                1,
+                Some(&self.vertex_buffer),
+                Some(&STRIDE),
+                Some(&0),
+            );
+            device_context.IASetInputLayout(&self.input_layout);
+        }
+        for i in 0..count {
+            unsafe {
+                device_context.DrawInstancedIndirect(
+                    &self.indirect_draw_buffer,
+                    (i * std::mem::size_of::<DrawInstancedIndirectArgs>()) as u32,
+                );
+            }
+        }
+        Ok(())
+    }
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -1048,21 +1104,6 @@ fn create_indirect_draw_buffer(device: &ID3D11Device, buffer_size: usize) -> Res
     Ok(buffer.unwrap())
 }
 
-fn update_global_params(
-    device_context: &ID3D11DeviceContext,
-    buffer: &[Option<ID3D11Buffer>; 1],
-    globals: GlobalParams,
-) -> Result<()> {
-    let buffer = buffer[0].as_ref().unwrap();
-    unsafe {
-        let mut data = std::mem::zeroed();
-        device_context.Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut data))?;
-        std::ptr::copy_nonoverlapping(&globals, data.pData as *mut _, 1);
-        device_context.Unmap(buffer, 0);
-    }
-    Ok(())
-}
-
 fn pre_draw(
     device_context: &ID3D11DeviceContext,
     global_params_buffer: &[Option<ID3D11Buffer>; 1],
@@ -1071,13 +1112,14 @@ fn pre_draw(
     clear_color: [f32; 4],
     blend_state: &ID3D11BlendState,
 ) -> Result<()> {
-    update_global_params(
+    let global_params = global_params_buffer[0].as_ref().unwrap();
+    update_buffer(
         device_context,
-        global_params_buffer,
-        GlobalParams {
+        global_params,
+        &[GlobalParams {
             viewport_size: [view_port[0].Width, view_port[0].Height],
             ..Default::default()
-        },
+        }],
     )?;
     unsafe {
         device_context.RSSetViewports(Some(view_port));
@@ -1088,70 +1130,6 @@ fn pre_draw(
     Ok(())
 }
 
-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;
-    }
-    let buffer_size = data_size.next_power_of_two();
-    let buffer = create_buffer(device, std::mem::size_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)> {
-    if pipeline.vertex_buffer_size >= vertex_size {
-        return None;
-    }
-    let vertex_size = vertex_size.next_power_of_two();
-    let buffer = create_buffer(
-        device,
-        std::mem::size_of::<PathVertex<ScaledPixels>>(),
-        vertex_size,
-    )
-    .unwrap();
-    Some((buffer, vertex_size))
-}
-
-fn update_indirect_buffer_capacity(
-    pipeline: &PathsPipelineState,
-    data_size: usize,
-    device: &ID3D11Device,
-) -> Option<(ID3D11Buffer, usize)> {
-    if pipeline.indirect_buffer_size >= data_size {
-        return None;
-    }
-    let buffer_size = data_size.next_power_of_two();
-    let buffer = create_indirect_draw_buffer(device, data_size).unwrap();
-    Some((buffer, buffer_size))
-}
-
-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)) {
-    pipeline.vertex_buffer = Some(input.0);
-    pipeline.vertex_buffer_size = input.1;
-}
-
-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,
@@ -1166,45 +1144,6 @@ fn update_buffer<T>(
     Ok(())
 }
 
-fn prepare_indirect_draws(
-    device_context: &ID3D11DeviceContext,
-    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.IASetPrimitiveTopology(topology);
-        device_context.RSSetViewports(Some(viewport));
-        device_context.VSSetShader(&pipeline.vertex, None);
-        device_context.PSSetShader(&pipeline.fragment, None);
-        device_context.VSSetConstantBuffers(0, Some(global_params));
-        device_context.PSSetConstantBuffers(0, Some(global_params));
-        const STRIDE: u32 = std::mem::size_of::<PathVertex<ScaledPixels>>() as u32;
-        device_context.IASetVertexBuffers(
-            0,
-            1,
-            Some(&pipeline.vertex_buffer),
-            Some(&STRIDE),
-            Some(&0),
-        );
-        device_context.IASetInputLayout(&pipeline.input_layout);
-    }
-    Ok(())
-}
-
-fn draw_indirect(
-    device_context: &ID3D11DeviceContext,
-    indirect_draw_buffer: &ID3D11Buffer,
-    offset: u32,
-) {
-    unsafe {
-        device_context.DrawInstancedIndirect(indirect_draw_buffer, offset);
-    }
-}
-
 const BUFFER_COUNT: usize = 3;
 
 mod shader_resources {