diff --git a/crates/gpui/src/platform/windows/directx_renderer.rs b/crates/gpui/src/platform/windows/directx_renderer.rs index 80195bf93e18cce59a2d923488bdd4cc61aa7308..73ecd7cfcaf34a2e51bf8002fd4c95abdd3d74fb 100644 --- a/crates/gpui/src/platform/windows/directx_renderer.rs +++ b/crates/gpui/src/platform/windows/directx_renderer.rs @@ -79,7 +79,6 @@ struct DirectXRenderPipelines { struct DirectXGlobalElements { global_params_buffer: [Option; 1], sampler: [Option; 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 { - 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 { buffer: ID3D11Buffer, buffer_size: usize, view: [Option; 1], + blend_state: ID3D11BlendState, _marker: std::marker::PhantomData, } -// struct PathRasterizationPipelineState { -// vertex: ID3D11VertexShader, -// fragment: ID3D11PixelShader, -// buffer: ID3D11Buffer, -// buffer_size: usize, -// view: [Option; 1], -// vertex_buffer: Option, -// vertex_buffer_size: usize, -// input_layout: ID3D11InputLayout, -// } - impl PipelineState { fn new( device: &ID3D11Device, label: &'static str, shader_module: ShaderModule, buffer_size: usize, + blend_state: ID3D11BlendState, ) -> Result { let vertex = { let raw_shader = RawShaderBytes::new(shader_module, ShaderTarget::Vertex)?; @@ -811,6 +817,7 @@ impl PipelineState { buffer, buffer_size, view, + blend_state, _marker: std::marker::PhantomData, }) } @@ -855,6 +862,7 @@ impl PipelineState { &self.vertex, &self.fragment, global_params, + &self.blend_state, ); unsafe { device_context.DrawInstanced(vertex_count, instance_count, 0, 0); @@ -879,6 +887,7 @@ impl PipelineState { &self.vertex, &self.fragment, global_params, + &self.blend_state, ); unsafe { device_context.PSSetSamplers(0, Some(sampler)); @@ -891,123 +900,6 @@ impl PipelineState { } } -// impl PathRasterizationPipelineState { -// fn new(device: &ID3D11Device) -> Result { -// 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::(), 32)?; -// let view = create_buffer_view(device, &buffer)?; -// let vertex_buffer = Some(create_buffer( -// device, -// std::mem::size_of::(), -// 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::(), -// 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::(), -// 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], -// ) -> 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::() 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 { } } +#[inline] +fn create_blend_state_for_path_rasterization(device: &ID3D11Device) -> Result { + // 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 { + // 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 { unsafe { @@ -1425,6 +1357,7 @@ fn set_pipeline_state( vertex_shader: &ID3D11VertexShader, fragment_shader: &ID3D11PixelShader, global_params: &[Option], + 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); } }