@@ -1781,6 +1781,98 @@ impl Writer {
17811781
17821782 func_id
17831783 }
1784+
1785+ fn write_ray_query_terminate ( & mut self ) -> spirv:: Word {
1786+ if let Some ( & word) = self
1787+ . ray_query_functions
1788+ . get ( & LookupRayQueryFunction :: Terminate )
1789+ {
1790+ return word;
1791+ }
1792+
1793+ let ray_query_type_id = self . get_ray_query_pointer_id ( ) ;
1794+
1795+ let u32_ty = self . get_u32_type_id ( ) ;
1796+ let u32_ptr_ty = self . get_pointer_type_id ( u32_ty, spirv:: StorageClass :: Function ) ;
1797+
1798+ let bool_type_id = self . get_bool_type_id ( ) ;
1799+
1800+ let ( func_id, mut function, arg_ids) =
1801+ self . write_function_signature ( & [ ray_query_type_id, u32_ptr_ty] , self . void_type ) ;
1802+
1803+ let query_id = arg_ids[ 0 ] ;
1804+ let init_tracker_id = arg_ids[ 1 ] ;
1805+
1806+ let block_id = self . id_gen . next ( ) ;
1807+ let mut block = Block :: new ( block_id) ;
1808+
1809+ let initialized_tracker_id = self . id_gen . next ( ) ;
1810+ block. body . push ( Instruction :: load (
1811+ u32_ty,
1812+ initialized_tracker_id,
1813+ init_tracker_id,
1814+ None ,
1815+ ) ) ;
1816+
1817+ let merge_id = self . id_gen . next ( ) ;
1818+ let merge_block = Block :: new ( merge_id) ;
1819+
1820+ let valid_block_id = self . id_gen . next ( ) ;
1821+ let mut valid_block = Block :: new ( valid_block_id) ;
1822+
1823+ let instruction = if self . ray_query_initialization_tracking {
1824+ let has_proceeded = write_ray_flags_contains_flags (
1825+ self ,
1826+ & mut block,
1827+ initialized_tracker_id,
1828+ super :: RayQueryPoint :: PROCEED . bits ( ) ,
1829+ ) ;
1830+
1831+ let finished_proceed_id = write_ray_flags_contains_flags (
1832+ self ,
1833+ & mut block,
1834+ initialized_tracker_id,
1835+ super :: RayQueryPoint :: FINISHED_TRAVERSAL . bits ( ) ,
1836+ ) ;
1837+
1838+ // Can't find anything to suggest double calling this function is invalid.
1839+
1840+ let not_finished_id = self . id_gen . next ( ) ;
1841+ block. body . push ( Instruction :: unary (
1842+ spirv:: Op :: LogicalNot ,
1843+ bool_type_id,
1844+ not_finished_id,
1845+ finished_proceed_id,
1846+ ) ) ;
1847+
1848+ let valid_call = self . write_logical_and ( & mut block, not_finished_id, has_proceeded) ;
1849+
1850+ block. body . push ( Instruction :: selection_merge (
1851+ merge_id,
1852+ spirv:: SelectionControl :: NONE ,
1853+ ) ) ;
1854+
1855+ Instruction :: branch_conditional ( valid_call, valid_block_id, merge_id)
1856+ } else {
1857+ Instruction :: branch ( valid_block_id)
1858+ } ;
1859+
1860+ function. consume ( block, instruction) ;
1861+
1862+ valid_block
1863+ . body
1864+ . push ( Instruction :: ray_query_terminate ( query_id) ) ;
1865+
1866+ function. consume ( valid_block, Instruction :: branch ( merge_id) ) ;
1867+
1868+ function. consume ( merge_block, Instruction :: return_void ( ) ) ;
1869+
1870+ function. to_words ( & mut self . logical_layout . function_definitions ) ;
1871+
1872+ self . ray_query_functions
1873+ . insert ( LookupRayQueryFunction :: Proceed , func_id) ;
1874+ func_id
1875+ }
17841876}
17851877
17861878impl BlockContext < ' _ > {
@@ -1863,7 +1955,17 @@ impl BlockContext<'_> {
18631955 & [ query_id, tracker_ids. initialized_tracker ] ,
18641956 ) ) ;
18651957 }
1866- crate :: RayQueryFunction :: Terminate => { }
1958+ crate :: RayQueryFunction :: Terminate => {
1959+ let id = self . gen_id ( ) ;
1960+
1961+ let func_id = self . writer . write_ray_query_terminate ( ) ;
1962+ block. body . push ( Instruction :: function_call (
1963+ self . writer . void_type ,
1964+ id,
1965+ func_id,
1966+ & [ query_id, tracker_ids. initialized_tracker ] ,
1967+ ) ) ;
1968+ }
18671969 }
18681970 }
18691971
0 commit comments