diff --git a/crates/gpui/src/platform/windows/directx_atlas.rs b/crates/gpui/src/platform/windows/directx_atlas.rs index 8ab4092efd..068d1b6461 100644 --- a/crates/gpui/src/platform/windows/directx_atlas.rs +++ b/crates/gpui/src/platform/windows/directx_atlas.rs @@ -7,7 +7,7 @@ use windows::Win32::Graphics::{ D3D11_USAGE_DEFAULT, ID3D11Device, ID3D11DeviceContext, ID3D11ShaderResourceView, ID3D11Texture2D, }, - Dxgi::Common::{DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_SAMPLE_DESC}, + Dxgi::Common::*, }; use crate::{ @@ -167,7 +167,7 @@ impl DirectXAtlasState { let bytes_per_pixel; match kind { AtlasTextureKind::Monochrome => { - pixel_format = DXGI_FORMAT_A8_UNORM; + pixel_format = DXGI_FORMAT_R8_UNORM; bind_flag = D3D11_BIND_SHADER_RESOURCE; bytes_per_pixel = 1; } diff --git a/crates/gpui/src/platform/windows/directx_renderer.rs b/crates/gpui/src/platform/windows/directx_renderer.rs index c62055d1d1..a429d2049b 100644 --- a/crates/gpui/src/platform/windows/directx_renderer.rs +++ b/crates/gpui/src/platform/windows/directx_renderer.rs @@ -149,6 +149,11 @@ impl DirectXRenderer { } fn pre_draw(&self) -> Result<()> { + #[cfg(not(feature = "enable-renderdoc"))] + let premultiplied_alpha = 1; + #[cfg(feature = "enable-renderdoc")] + let premultiplied_alpha = 0; + update_buffer( &self.devices.device_context, self.globals.global_params_buffer[0].as_ref().unwrap(), @@ -157,6 +162,7 @@ impl DirectXRenderer { self.resources.viewport[0].Width, self.resources.viewport[0].Height, ], + premultiplied_alpha, ..Default::default() }], )?; @@ -667,7 +673,8 @@ impl DirectXGlobalElements { #[repr(C)] struct GlobalParams { viewport_size: [f32; 2], - _pad: u64, + premultiplied_alpha: u32, + _pad: u32, } struct PipelineState { @@ -1093,7 +1100,7 @@ fn create_swap_chain( // Composition SwapChains only support the DXGI_SCALING_STRETCH Scaling. Scaling: DXGI_SCALING_STRETCH, SwapEffect: DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, - AlphaMode: DXGI_ALPHA_MODE_PREMULTIPLIED, + AlphaMode: DXGI_ALPHA_MODE_IGNORE, Flags: 0, }; Ok(unsafe { dxgi_factory.CreateSwapChainForComposition(device, &desc, None)? }) @@ -1262,7 +1269,7 @@ fn create_blend_state(device: &ID3D11Device) -> Result { desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; 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].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL.0 as u8; unsafe { let mut state = None; diff --git a/crates/gpui/src/platform/windows/shaders.hlsl b/crates/gpui/src/platform/windows/shaders.hlsl index f0c773a673..2533aa1885 100644 --- a/crates/gpui/src/platform/windows/shaders.hlsl +++ b/crates/gpui/src/platform/windows/shaders.hlsl @@ -1,6 +1,7 @@ cbuffer GlobalParams: register(b0) { float2 global_viewport_size; - uint2 _global_pad; + uint premultiplied_alpha; + uint _pad; }; Texture2D t_sprite: register(t0); @@ -256,7 +257,7 @@ float pick_corner_radius(float2 center_to_point, Corners corner_radii) { } } -float4 to_device_position_transformed(float2 unit_vertex, Bounds bounds, +float4 to_device_position_transformed(float2 unit_vertex, Bounds bounds, TransformationMatrix transformation) { float2 position = unit_vertex * bounds.size + bounds.origin; float2 transformed = mul(position, transformation.rotation_scale) + transformation.translation; @@ -970,7 +971,7 @@ UnderlineVertexOutput underline_vertex(uint vertex_id: SV_VertexID, uint underli float2 unit_vertex = float2(float(vertex_id & 1u), 0.5 * float(vertex_id & 2u)); Underline underline = underlines[underline_id]; float4 device_position = to_device_position(unit_vertex, underline.bounds); - float4 clip_distance = distance_from_clip_rect(unit_vertex, underline.bounds, + float4 clip_distance = distance_from_clip_rect(unit_vertex, underline.bounds, underline.content_mask); float4 color = hsla_to_rgba(underline.color); @@ -1031,6 +1032,7 @@ struct MonochromeSpriteFragmentInput { float4 position: SV_Position; float2 tile_position: POSITION; nointerpolation float4 color: COLOR; + float4 clip_distance: SV_ClipDistance; }; StructuredBuffer mono_sprites: register(t1); @@ -1052,11 +1054,21 @@ MonochromeSpriteVertexOutput monochrome_sprite_vertex(uint vertex_id: SV_VertexI return output; } +float4 blend_color(float4 color, float alpha_factor) { + float alpha = color.a * alpha_factor; + float multiplier = premultiplied_alpha != 0 ? alpha : 1.0; + return float4(color.rgb * multiplier, alpha); +} + float4 monochrome_sprite_fragment(MonochromeSpriteFragmentInput input): SV_Target { - float4 sample = t_sprite.Sample(s_sprite, input.tile_position); + float sample = t_sprite.Sample(s_sprite, input.tile_position).r; float4 color = input.color; - color.a *= sample.a; + color.a *= sample; return color; + // if (any(input.clip_distance < 0.0)) { + // return float4(0.0, 0.0, 0.0, 0.0); + // } + // return blend_color(input.color, sample); } /*