fix

Junkui Zhang created

Change summary

crates/gpui/src/platform/windows/directx_renderer.rs | 222 ++++---------
1 file changed, 78 insertions(+), 144 deletions(-)

Detailed changes

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

@@ -79,7 +79,6 @@ struct DirectXRenderPipelines {
 struct DirectXGlobalElements {
     global_params_buffer: [Option<ID3D11Buffer>; 1],
     sampler: [Option<ID3D11SamplerState>; 1],
-    blend_state: ID3D11BlendState,
 }
 
 #[repr(C)]
@@ -171,11 +170,6 @@ impl DirectXRenderer {
             self.devices
                 .device_context
                 .RSSetViewports(Some(&self.resources.viewport));
-            self.devices.device_context.OMSetBlendState(
-                &self.globals.blend_state,
-                None,
-                0xFFFFFFFF,
-            );
         }
         Ok(())
     }
@@ -653,30 +647,54 @@ impl DirectXResources {
 
 impl DirectXRenderPipelines {
     pub fn new(device: &ID3D11Device) -> Result<Self> {
-        let shadow_pipeline =
-            PipelineState::new(device, "shadow_pipeline", ShaderModule::Shadow, 4)?;
-        let quad_pipeline = PipelineState::new(device, "quad_pipeline", ShaderModule::Quad, 64)?;
+        let shadow_pipeline = PipelineState::new(
+            device,
+            "shadow_pipeline",
+            ShaderModule::Shadow,
+            4,
+            create_blend_state(device)?,
+        )?;
+        let quad_pipeline = PipelineState::new(
+            device,
+            "quad_pipeline",
+            ShaderModule::Quad,
+            64,
+            create_blend_state(device)?,
+        )?;
         let path_rasterization_pipeline = PipelineState::new(
             device,
             "path_rasterization_pipeline",
             ShaderModule::PathRasterization,
             32,
+            create_blend_state_for_path_rasterization(device)?,
+        )?;
+        let path_sprite_pipeline = PipelineState::new(
+            device,
+            "path_sprite_pipeline",
+            ShaderModule::PathSprite,
+            4,
+            create_blend_state_for_path_sprite(device)?,
+        )?;
+        let underline_pipeline = PipelineState::new(
+            device,
+            "underline_pipeline",
+            ShaderModule::Underline,
+            4,
+            create_blend_state(device)?,
         )?;
-        let path_sprite_pipeline =
-            PipelineState::new(device, "path_sprite_pipeline", ShaderModule::PathSprite, 1)?;
-        let underline_pipeline =
-            PipelineState::new(device, "underline_pipeline", ShaderModule::Underline, 4)?;
         let mono_sprites = PipelineState::new(
             device,
             "monochrome_sprite_pipeline",
             ShaderModule::MonochromeSprite,
             512,
+            create_blend_state(device)?,
         )?;
         let poly_sprites = PipelineState::new(
             device,
             "polychrome_sprite_pipeline",
             ShaderModule::PolychromeSprite,
             16,
+            create_blend_state(device)?,
         )?;
 
         Ok(Self {
@@ -748,12 +766,9 @@ impl DirectXGlobalElements {
             [output]
         };
 
-        let blend_state = create_blend_state(device)?;
-
         Ok(Self {
             global_params_buffer,
             sampler,
-            blend_state,
         })
     }
 }
@@ -772,26 +787,17 @@ struct PipelineState<T> {
     buffer: ID3D11Buffer,
     buffer_size: usize,
     view: [Option<ID3D11ShaderResourceView>; 1],
+    blend_state: ID3D11BlendState,
     _marker: std::marker::PhantomData<T>,
 }
 
-// struct PathRasterizationPipelineState {
-//     vertex: ID3D11VertexShader,
-//     fragment: ID3D11PixelShader,
-//     buffer: ID3D11Buffer,
-//     buffer_size: usize,
-//     view: [Option<ID3D11ShaderResourceView>; 1],
-//     vertex_buffer: Option<ID3D11Buffer>,
-//     vertex_buffer_size: usize,
-//     input_layout: ID3D11InputLayout,
-// }
-
 impl<T> PipelineState<T> {
     fn new(
         device: &ID3D11Device,
         label: &'static str,
         shader_module: ShaderModule,
         buffer_size: usize,
+        blend_state: ID3D11BlendState,
     ) -> Result<Self> {
         let vertex = {
             let raw_shader = RawShaderBytes::new(shader_module, ShaderTarget::Vertex)?;
@@ -811,6 +817,7 @@ impl<T> PipelineState<T> {
             buffer,
             buffer_size,
             view,
+            blend_state,
             _marker: std::marker::PhantomData,
         })
     }
@@ -855,6 +862,7 @@ impl<T> PipelineState<T> {
             &self.vertex,
             &self.fragment,
             global_params,
+            &self.blend_state,
         );
         unsafe {
             device_context.DrawInstanced(vertex_count, instance_count, 0, 0);
@@ -879,6 +887,7 @@ impl<T> PipelineState<T> {
             &self.vertex,
             &self.fragment,
             global_params,
+            &self.blend_state,
         );
         unsafe {
             device_context.PSSetSamplers(0, Some(sampler));
@@ -891,123 +900,6 @@ impl<T> PipelineState<T> {
     }
 }
 
-// impl PathRasterizationPipelineState {
-//     fn new(device: &ID3D11Device) -> Result<Self> {
-//         let (vertex, vertex_shader) = {
-//             let raw_vertex_shader =
-//                 RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Vertex)?;
-//             (
-//                 create_vertex_shader(device, raw_vertex_shader.as_bytes())?,
-//                 raw_vertex_shader,
-//             )
-//         };
-//         let fragment = {
-//             let raw_shader =
-//                 RawShaderBytes::new(ShaderModule::PathRasterization, ShaderTarget::Fragment)?;
-//             create_fragment_shader(device, raw_shader.as_bytes())?
-//         };
-//         let buffer = create_buffer(device, std::mem::size_of::<PathRasterizationSprite>(), 32)?;
-//         let view = create_buffer_view(device, &buffer)?;
-//         let vertex_buffer = Some(create_buffer(
-//             device,
-//             std::mem::size_of::<PathRasterizationSprite>(),
-//             32,
-//         )?);
-
-//         Ok(Self {
-//             vertex,
-//             fragment,
-//             buffer,
-//             buffer_size: 32,
-//             view,
-//             vertex_buffer,
-//             vertex_buffer_size: 32,
-//         })
-//     }
-
-//     fn update_buffer(
-//         &mut self,
-//         device: &ID3D11Device,
-//         device_context: &ID3D11DeviceContext,
-//         sprites: &[PathRasterizationSprite],
-//         vertices_data: &[DirectXPathVertex],
-//     ) -> Result<()> {
-//         if self.buffer_size < sprites.len() {
-//             let new_buffer_size = sprites.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::<PathRasterizationSprite>(),
-//                 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, sprites)?;
-
-//         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::<DirectXPathVertex>(),
-//                 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,
-//         )?;
-
-//         Ok(())
-//     }
-
-//     fn draw(
-//         &self,
-//         device_context: &ID3D11DeviceContext,
-//         vertex_count: u32,
-//         viewport: &[D3D11_VIEWPORT],
-//         global_params: &[Option<ID3D11Buffer>],
-//     ) -> Result<()> {
-//         set_pipeline_state(
-//             device_context,
-//             &self.view,
-//             D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
-//             viewport,
-//             &self.vertex,
-//             &self.fragment,
-//             global_params,
-//         );
-//         unsafe {
-//             const STRIDE: u32 = std::mem::size_of::<DirectXPathVertex>() as u32;
-//             const OFFSET: u32 = 0;
-//             device_context.IASetInputLayout(&self.input_layout);
-//             device_context.IASetVertexBuffers(
-//                 0,
-//                 1,
-//                 Some(&self.vertex_buffer),
-//                 Some(&STRIDE),
-//                 Some(&OFFSET),
-//             );
-//             device_context.Draw(vertex_count, 0);
-//         }
-//         Ok(())
-//     }
-// }
-
 #[derive(Clone, Copy)]
 #[repr(C)]
 struct PathRasterizationSprite {
@@ -1354,6 +1246,46 @@ fn create_blend_state(device: &ID3D11Device) -> Result<ID3D11BlendState> {
     }
 }
 
+#[inline]
+fn create_blend_state_for_path_rasterization(device: &ID3D11Device) -> Result<ID3D11BlendState> {
+    // If the feature level is set to greater than D3D_FEATURE_LEVEL_9_3, the display
+    // device performs the blend in linear space, which is ideal.
+    let mut desc = D3D11_BLEND_DESC::default();
+    desc.RenderTarget[0].BlendEnable = true.into();
+    desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+    desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+    desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+    desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
+    desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+    desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
+    desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8;
+    unsafe {
+        let mut state = None;
+        device.CreateBlendState(&desc, Some(&mut state))?;
+        Ok(state.unwrap())
+    }
+}
+
+#[inline]
+fn create_blend_state_for_path_sprite(device: &ID3D11Device) -> Result<ID3D11BlendState> {
+    // If the feature level is set to greater than D3D_FEATURE_LEVEL_9_3, the display
+    // device performs the blend in linear space, which is ideal.
+    let mut desc = D3D11_BLEND_DESC::default();
+    desc.RenderTarget[0].BlendEnable = true.into();
+    desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+    desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+    desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+    desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
+    desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+    desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
+    desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8;
+    unsafe {
+        let mut state = None;
+        device.CreateBlendState(&desc, Some(&mut state))?;
+        Ok(state.unwrap())
+    }
+}
+
 #[inline]
 fn create_vertex_shader(device: &ID3D11Device, bytes: &[u8]) -> Result<ID3D11VertexShader> {
     unsafe {
@@ -1425,6 +1357,7 @@ fn set_pipeline_state(
     vertex_shader: &ID3D11VertexShader,
     fragment_shader: &ID3D11PixelShader,
     global_params: &[Option<ID3D11Buffer>],
+    blend_state: &ID3D11BlendState,
 ) {
     unsafe {
         device_context.VSSetShaderResources(1, Some(buffer_view));
@@ -1435,6 +1368,7 @@ fn set_pipeline_state(
         device_context.PSSetShader(fragment_shader, None);
         device_context.VSSetConstantBuffers(0, Some(global_params));
         device_context.PSSetConstantBuffers(0, Some(global_params));
+        device_context.OMSetBlendState(blend_state, None, 0xFFFFFFFF);
     }
 }