@@ -1737,276 +1737,15 @@ impl Global {
1737
1737
device_id : DeviceId ,
1738
1738
config : & wgt:: SurfaceConfiguration < Vec < TextureFormat > > ,
1739
1739
) -> Option < present:: ConfigureSurfaceError > {
1740
- use present:: ConfigureSurfaceError as E ;
1741
- profiling:: scope!( "surface_configure" ) ;
1742
-
1743
- fn validate_surface_configuration (
1744
- config : & mut hal:: SurfaceConfiguration ,
1745
- caps : & hal:: SurfaceCapabilities ,
1746
- max_texture_dimension_2d : u32 ,
1747
- ) -> Result < ( ) , E > {
1748
- let width = config. extent . width ;
1749
- let height = config. extent . height ;
1750
-
1751
- if width > max_texture_dimension_2d || height > max_texture_dimension_2d {
1752
- return Err ( E :: TooLarge {
1753
- width,
1754
- height,
1755
- max_texture_dimension_2d,
1756
- } ) ;
1757
- }
1758
-
1759
- if !caps. present_modes . contains ( & config. present_mode ) {
1760
- // Automatic present mode checks.
1761
- //
1762
- // The "Automatic" modes are never supported by the backends.
1763
- let fallbacks = match config. present_mode {
1764
- wgt:: PresentMode :: AutoVsync => {
1765
- & [ wgt:: PresentMode :: FifoRelaxed , wgt:: PresentMode :: Fifo ] [ ..]
1766
- }
1767
- // Always end in FIFO to make sure it's always supported
1768
- wgt:: PresentMode :: AutoNoVsync => & [
1769
- wgt:: PresentMode :: Immediate ,
1770
- wgt:: PresentMode :: Mailbox ,
1771
- wgt:: PresentMode :: Fifo ,
1772
- ] [ ..] ,
1773
- _ => {
1774
- return Err ( E :: UnsupportedPresentMode {
1775
- requested : config. present_mode ,
1776
- available : caps. present_modes . clone ( ) ,
1777
- } ) ;
1778
- }
1779
- } ;
1780
-
1781
- let new_mode = fallbacks
1782
- . iter ( )
1783
- . copied ( )
1784
- . find ( |fallback| caps. present_modes . contains ( fallback) )
1785
- . unwrap_or_else ( || {
1786
- unreachable ! (
1787
- "Fallback system failed to choose present mode. \
1788
- This is a bug. Mode: {:?}, Options: {:?}",
1789
- config. present_mode, & caps. present_modes
1790
- ) ;
1791
- } ) ;
1792
-
1793
- api_log ! (
1794
- "Automatically choosing presentation mode by rule {:?}. Chose {new_mode:?}" ,
1795
- config. present_mode
1796
- ) ;
1797
- config. present_mode = new_mode;
1798
- }
1799
- if !caps. formats . contains ( & config. format ) {
1800
- return Err ( E :: UnsupportedFormat {
1801
- requested : config. format ,
1802
- available : caps. formats . clone ( ) ,
1803
- } ) ;
1804
- }
1805
- if !caps
1806
- . composite_alpha_modes
1807
- . contains ( & config. composite_alpha_mode )
1808
- {
1809
- let new_alpha_mode = ' alpha: {
1810
- // Automatic alpha mode checks.
1811
- let fallbacks = match config. composite_alpha_mode {
1812
- wgt:: CompositeAlphaMode :: Auto => & [
1813
- wgt:: CompositeAlphaMode :: Opaque ,
1814
- wgt:: CompositeAlphaMode :: Inherit ,
1815
- ] [ ..] ,
1816
- _ => {
1817
- return Err ( E :: UnsupportedAlphaMode {
1818
- requested : config. composite_alpha_mode ,
1819
- available : caps. composite_alpha_modes . clone ( ) ,
1820
- } ) ;
1821
- }
1822
- } ;
1823
-
1824
- for & fallback in fallbacks {
1825
- if caps. composite_alpha_modes . contains ( & fallback) {
1826
- break ' alpha fallback;
1827
- }
1828
- }
1829
-
1830
- unreachable ! (
1831
- "Fallback system failed to choose alpha mode. This is a bug. \
1832
- AlphaMode: {:?}, Options: {:?}",
1833
- config. composite_alpha_mode, & caps. composite_alpha_modes
1834
- ) ;
1835
- } ;
1740
+ let device = self . hub . devices . get ( device_id) ;
1741
+ let surface = self . surfaces . get ( surface_id) ;
1836
1742
1837
- api_log ! (
1838
- "Automatically choosing alpha mode by rule {:?}. Chose {new_alpha_mode:?}" ,
1839
- config. composite_alpha_mode
1840
- ) ;
1841
- config. composite_alpha_mode = new_alpha_mode;
1842
- }
1843
- if !caps. usage . contains ( config. usage ) {
1844
- return Err ( E :: UnsupportedUsage {
1845
- requested : config. usage ,
1846
- available : caps. usage ,
1847
- } ) ;
1848
- }
1849
- if width == 0 || height == 0 {
1850
- return Err ( E :: ZeroArea ) ;
1851
- }
1852
- Ok ( ( ) )
1743
+ #[ cfg( feature = "trace" ) ]
1744
+ if let Some ( ref mut trace) = * device. trace . lock ( ) {
1745
+ trace. add ( trace:: Action :: ConfigureSurface ( surface_id, config. clone ( ) ) ) ;
1853
1746
}
1854
1747
1855
- log:: debug!( "configuring surface with {config:?}" ) ;
1856
-
1857
- let error = ' error: {
1858
- // User callbacks must not be called while we are holding locks.
1859
- let user_callbacks;
1860
- {
1861
- let device = self . hub . devices . get ( device_id) ;
1862
-
1863
- #[ cfg( feature = "trace" ) ]
1864
- if let Some ( ref mut trace) = * device. trace . lock ( ) {
1865
- trace. add ( trace:: Action :: ConfigureSurface ( surface_id, config. clone ( ) ) ) ;
1866
- }
1867
-
1868
- if let Err ( e) = device. check_is_valid ( ) {
1869
- break ' error e. into ( ) ;
1870
- }
1871
-
1872
- let surface = self . surfaces . get ( surface_id) ;
1873
-
1874
- let caps = match surface. get_capabilities ( & device. adapter ) {
1875
- Ok ( caps) => caps,
1876
- Err ( _) => break ' error E :: UnsupportedQueueFamily ,
1877
- } ;
1878
-
1879
- let mut hal_view_formats = Vec :: new ( ) ;
1880
- for format in config. view_formats . iter ( ) {
1881
- if * format == config. format {
1882
- continue ;
1883
- }
1884
- if !caps. formats . contains ( & config. format ) {
1885
- break ' error E :: UnsupportedFormat {
1886
- requested : config. format ,
1887
- available : caps. formats ,
1888
- } ;
1889
- }
1890
- if config. format . remove_srgb_suffix ( ) != format. remove_srgb_suffix ( ) {
1891
- break ' error E :: InvalidViewFormat ( * format, config. format ) ;
1892
- }
1893
- hal_view_formats. push ( * format) ;
1894
- }
1895
-
1896
- if !hal_view_formats. is_empty ( ) {
1897
- if let Err ( missing_flag) =
1898
- device. require_downlevel_flags ( wgt:: DownlevelFlags :: SURFACE_VIEW_FORMATS )
1899
- {
1900
- break ' error E :: MissingDownlevelFlags ( missing_flag) ;
1901
- }
1902
- }
1903
-
1904
- let maximum_frame_latency = config. desired_maximum_frame_latency . clamp (
1905
- * caps. maximum_frame_latency . start ( ) ,
1906
- * caps. maximum_frame_latency . end ( ) ,
1907
- ) ;
1908
- let mut hal_config = hal:: SurfaceConfiguration {
1909
- maximum_frame_latency,
1910
- present_mode : config. present_mode ,
1911
- composite_alpha_mode : config. alpha_mode ,
1912
- format : config. format ,
1913
- extent : wgt:: Extent3d {
1914
- width : config. width ,
1915
- height : config. height ,
1916
- depth_or_array_layers : 1 ,
1917
- } ,
1918
- usage : conv:: map_texture_usage (
1919
- config. usage ,
1920
- hal:: FormatAspects :: COLOR ,
1921
- wgt:: TextureFormatFeatureFlags :: STORAGE_READ_ONLY
1922
- | wgt:: TextureFormatFeatureFlags :: STORAGE_WRITE_ONLY
1923
- | wgt:: TextureFormatFeatureFlags :: STORAGE_READ_WRITE ,
1924
- ) ,
1925
- view_formats : hal_view_formats,
1926
- } ;
1927
-
1928
- if let Err ( error) = validate_surface_configuration (
1929
- & mut hal_config,
1930
- & caps,
1931
- device. limits . max_texture_dimension_2d ,
1932
- ) {
1933
- break ' error error;
1934
- }
1935
-
1936
- // Wait for all work to finish before configuring the surface.
1937
- let snatch_guard = device. snatchable_lock . read ( ) ;
1938
- let fence = device. fence . read ( ) ;
1939
-
1940
- let maintain_result;
1941
- ( user_callbacks, maintain_result) =
1942
- device. maintain ( fence, wgt:: PollType :: wait_indefinitely ( ) , snatch_guard) ;
1943
-
1944
- match maintain_result {
1945
- // We're happy
1946
- Ok ( wgt:: PollStatus :: QueueEmpty ) => { }
1947
- Ok ( wgt:: PollStatus :: WaitSucceeded ) => {
1948
- // After the wait, the queue should be empty. It can only be non-empty
1949
- // if another thread is submitting at the same time.
1950
- break ' error E :: GpuWaitTimeout ;
1951
- }
1952
- Ok ( wgt:: PollStatus :: Poll ) => {
1953
- unreachable ! ( "Cannot get a Poll result from a Wait action." )
1954
- }
1955
- Err ( WaitIdleError :: Timeout ) if cfg ! ( target_arch = "wasm32" ) => {
1956
- // On wasm, you cannot actually successfully wait for the surface.
1957
- // However WebGL does not actually require you do this, so ignoring
1958
- // the failure is totally fine. See https://github.com/gfx-rs/wgpu/issues/7363
1959
- }
1960
- Err ( e) => {
1961
- break ' error e. into ( ) ;
1962
- }
1963
- }
1964
-
1965
- // All textures must be destroyed before the surface can be re-configured.
1966
- if let Some ( present) = surface. presentation . lock ( ) . take ( ) {
1967
- if present. acquired_texture . is_some ( ) {
1968
- break ' error E :: PreviousOutputExists ;
1969
- }
1970
- }
1971
-
1972
- // TODO: Texture views may still be alive that point to the texture.
1973
- // this will allow the user to render to the surface texture, long after
1974
- // it has been removed.
1975
- //
1976
- // https://github.com/gfx-rs/wgpu/issues/4105
1977
-
1978
- let surface_raw = surface. raw ( device. backend ( ) ) . unwrap ( ) ;
1979
- match unsafe { surface_raw. configure ( device. raw ( ) , & hal_config) } {
1980
- Ok ( ( ) ) => ( ) ,
1981
- Err ( error) => {
1982
- break ' error match error {
1983
- hal:: SurfaceError :: Outdated | hal:: SurfaceError :: Lost => {
1984
- E :: InvalidSurface
1985
- }
1986
- hal:: SurfaceError :: Device ( error) => {
1987
- E :: Device ( device. handle_hal_error ( error) )
1988
- }
1989
- hal:: SurfaceError :: Other ( message) => {
1990
- log:: error!( "surface configuration failed: {message}" ) ;
1991
- E :: InvalidSurface
1992
- }
1993
- }
1994
- }
1995
- }
1996
-
1997
- let mut presentation = surface. presentation . lock ( ) ;
1998
- * presentation = Some ( present:: Presentation {
1999
- device,
2000
- config : config. clone ( ) ,
2001
- acquired_texture : None ,
2002
- } ) ;
2003
- }
2004
-
2005
- user_callbacks. fire ( ) ;
2006
- return None ;
2007
- } ;
2008
-
2009
- Some ( error)
1748
+ device. configure_surface ( & surface, config)
2010
1749
}
2011
1750
2012
1751
/// Check `device_id` for freeable resources and completed buffer mappings.
0 commit comments