1+ use itertools:: Itertools ;
12use rspirv:: spirv:: MemoryModel ;
3+ use rustc_codegen_spirv_target_specs:: Targets ;
24use rustc_target:: spec:: { Cc , LinkerFlavor , PanicStrategy , Target , TargetOptions } ;
3- use spirv_tools:: TargetEnv ;
45
5- const ARCH : & str = "spirv" ;
6-
7- pub struct SpirvTarget {
8- env : TargetEnv ,
9- vendor : String ,
6+ pub trait TargetsExt {
7+ fn memory_model ( & self ) -> MemoryModel ;
8+ fn to_spirv_tools ( & self ) -> spirv_tools :: TargetEnv ;
9+ fn spirv_version ( & self ) -> ( u8 , u8 ) ;
10+ fn rustc_target ( & self ) -> Target ;
1011}
1112
12- impl SpirvTarget {
13- pub fn memory_model ( & self ) -> MemoryModel {
14- match self . env {
15- TargetEnv :: Universal_1_0
16- | TargetEnv :: Universal_1_1
17- | TargetEnv :: Universal_1_2
18- | TargetEnv :: Universal_1_3
19- | TargetEnv :: Universal_1_4
20- | TargetEnv :: Universal_1_5
21- | TargetEnv :: Universal_1_6 => MemoryModel :: Simple ,
22-
23- TargetEnv :: OpenGL_4_0
24- | TargetEnv :: OpenGL_4_1
25- | TargetEnv :: OpenGL_4_2
26- | TargetEnv :: OpenGL_4_3
27- | TargetEnv :: OpenGL_4_5 => MemoryModel :: GLSL450 ,
28-
29- TargetEnv :: OpenCL_2_1
30- | TargetEnv :: OpenCL_2_2
31- | TargetEnv :: OpenCL_1_2
32- | TargetEnv :: OpenCLEmbedded_1_2
33- | TargetEnv :: OpenCL_2_0
34- | TargetEnv :: OpenCLEmbedded_2_0
35- | TargetEnv :: OpenCLEmbedded_2_1
36- | TargetEnv :: OpenCLEmbedded_2_2 => MemoryModel :: OpenCL ,
13+ impl TargetsExt for Targets {
14+ fn memory_model ( & self ) -> MemoryModel {
15+ match self {
16+ Targets :: spirv_unknown_spv_1_0
17+ | Targets :: spirv_unknown_spv_1_1
18+ | Targets :: spirv_unknown_spv_1_2
19+ | Targets :: spirv_unknown_spv_1_3
20+ | Targets :: spirv_unknown_spv_1_4
21+ | Targets :: spirv_unknown_spv_1_5
22+ | Targets :: spirv_unknown_spv_1_6 => MemoryModel :: Simple ,
23+
24+ Targets :: spirv_unknown_opengl_4_0
25+ | Targets :: spirv_unknown_opengl_4_1
26+ | Targets :: spirv_unknown_opengl_4_2
27+ | Targets :: spirv_unknown_opengl_4_3
28+ | Targets :: spirv_unknown_opengl_4_5 => MemoryModel :: GLSL450 ,
29+
30+ Targets :: spirv_unknown_vulkan_1_0
31+ | Targets :: spirv_unknown_vulkan_1_1
32+ | Targets :: spirv_unknown_vulkan_1_1_spv_1_4
33+ | Targets :: spirv_unknown_vulkan_1_2
34+ | Targets :: spirv_unknown_vulkan_1_3
35+ | Targets :: spirv_unknown_vulkan_1_4 => MemoryModel :: Vulkan ,
36+ }
37+ }
3738
38- TargetEnv :: Vulkan_1_0
39- | TargetEnv :: Vulkan_1_1
40- | TargetEnv :: WebGPU_0
41- | TargetEnv :: Vulkan_1_1_Spirv_1_4
42- | TargetEnv :: Vulkan_1_2
43- | TargetEnv :: Vulkan_1_3
44- | TargetEnv :: Vulkan_1_4 => MemoryModel :: Vulkan ,
39+ fn to_spirv_tools ( & self ) -> spirv_tools:: TargetEnv {
40+ match self {
41+ Targets :: spirv_unknown_opengl_4_0 => spirv_tools:: TargetEnv :: OpenGL_4_0 ,
42+ Targets :: spirv_unknown_opengl_4_1 => spirv_tools:: TargetEnv :: OpenGL_4_1 ,
43+ Targets :: spirv_unknown_opengl_4_2 => spirv_tools:: TargetEnv :: OpenGL_4_2 ,
44+ Targets :: spirv_unknown_opengl_4_3 => spirv_tools:: TargetEnv :: OpenGL_4_3 ,
45+ Targets :: spirv_unknown_opengl_4_5 => spirv_tools:: TargetEnv :: OpenGL_4_5 ,
46+ Targets :: spirv_unknown_spv_1_0 => spirv_tools:: TargetEnv :: Universal_1_0 ,
47+ Targets :: spirv_unknown_spv_1_1 => spirv_tools:: TargetEnv :: Universal_1_1 ,
48+ Targets :: spirv_unknown_spv_1_2 => spirv_tools:: TargetEnv :: Universal_1_2 ,
49+ Targets :: spirv_unknown_spv_1_3 => spirv_tools:: TargetEnv :: Universal_1_3 ,
50+ Targets :: spirv_unknown_spv_1_4 => spirv_tools:: TargetEnv :: Universal_1_4 ,
51+ Targets :: spirv_unknown_spv_1_5 => spirv_tools:: TargetEnv :: Universal_1_5 ,
52+ Targets :: spirv_unknown_spv_1_6 => spirv_tools:: TargetEnv :: Universal_1_6 ,
53+ Targets :: spirv_unknown_vulkan_1_0 => spirv_tools:: TargetEnv :: Vulkan_1_0 ,
54+ Targets :: spirv_unknown_vulkan_1_1 => spirv_tools:: TargetEnv :: Vulkan_1_1 ,
55+ Targets :: spirv_unknown_vulkan_1_1_spv_1_4 => {
56+ spirv_tools:: TargetEnv :: Vulkan_1_1_Spirv_1_4
57+ }
58+ Targets :: spirv_unknown_vulkan_1_2 => spirv_tools:: TargetEnv :: Vulkan_1_2 ,
59+ Targets :: spirv_unknown_vulkan_1_3 => spirv_tools:: TargetEnv :: Vulkan_1_3 ,
60+ Targets :: spirv_unknown_vulkan_1_4 => spirv_tools:: TargetEnv :: Vulkan_1_4 ,
4561 }
4662 }
4763
48- pub fn spirv_version ( & self ) -> ( u8 , u8 ) {
49- self . env . spirv_version ( )
64+ fn spirv_version ( & self ) -> ( u8 , u8 ) {
65+ self . to_spirv_tools ( ) . spirv_version ( )
5066 }
5167
52- fn init_target_opts ( & self ) -> TargetOptions {
68+ fn rustc_target ( & self ) -> Target {
69+ let target = self . as_str ( ) ;
70+ let mut split = target. split ( "-" ) ;
71+ let arch = split. next ( ) . unwrap ( ) ;
72+ let vendor = split. next ( ) . unwrap ( ) ;
73+ let env = split. join ( "-" ) ;
74+
5375 let mut o = TargetOptions :: default ( ) ;
5476 o. simd_types_indirect = false ;
5577 o. allows_weak_linkage = false ;
@@ -61,69 +83,18 @@ impl SpirvTarget {
6183 o. linker_flavor = LinkerFlavor :: Unix ( Cc :: No ) ;
6284 o. panic_strategy = PanicStrategy :: Abort ;
6385 o. os = "unknown" . into ( ) ;
64- o. env = self . env . to_string ( ) . into ( ) ;
65- o. vendor = self . vendor . clone ( ) . into ( ) ;
86+ o. env = env. into ( ) ;
87+ o. vendor = vendor. into ( ) ;
6688 // TODO: Investigate if main_needs_argc_argv is useful (for building exes)
6789 o. main_needs_argc_argv = false ;
68- o
69- }
7090
71- pub fn rustc_target ( & self ) -> Target {
7291 Target {
73- llvm_target : self . to_string ( ) . into ( ) ,
92+ llvm_target : target . into ( ) ,
7493 metadata : Default :: default ( ) ,
7594 pointer_width : 32 ,
7695 data_layout : "e-m:e-p:32:32:32-i64:64-n8:16:32:64" . into ( ) ,
77- arch : ARCH . into ( ) ,
78- options : self . init_target_opts ( ) ,
79- }
80- }
81- }
82-
83- impl std:: str:: FromStr for SpirvTarget {
84- type Err = InvalidTarget ;
85-
86- fn from_str ( target : & str ) -> Result < Self , Self :: Err > {
87- let mut iter = target. split ( '-' ) ;
88- let error = || InvalidTarget ( target. into ( ) ) ;
89-
90- if iter. next ( ) != Some ( ARCH ) {
91- return Err ( error ( ) ) ;
92- }
93-
94- let vendor = iter. next ( ) . map ( From :: from) . ok_or_else ( error) ?;
95-
96- let env = iter
97- . next ( )
98- . and_then ( |env| env. parse ( ) . ok ( ) )
99- . ok_or_else ( error) ?;
100-
101- if iter. next ( ) . is_some ( ) {
102- return Err ( error ( ) ) ;
96+ arch : arch. into ( ) ,
97+ options : o,
10398 }
104-
105- let result = Self { env, vendor } ;
106-
107- if result. memory_model ( ) == MemoryModel :: OpenCL {
108- return Err ( error ( ) ) ;
109- }
110-
111- Ok ( result)
112- }
113- }
114-
115- impl std:: fmt:: Display for SpirvTarget {
116- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
117- write ! ( f, "{}-{}-{}" , ARCH , self . vendor, self . env)
118- }
119- }
120-
121- #[ derive( Debug ) ]
122- pub struct InvalidTarget ( String ) ;
123-
124- impl std:: error:: Error for InvalidTarget { }
125- impl std:: fmt:: Display for InvalidTarget {
126- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
127- write ! ( f, "Invalid target `{}`." , self . 0 )
12899 }
129100}
0 commit comments