1
+ use itertools:: Itertools ;
1
2
use rspirv:: spirv:: MemoryModel ;
3
+ use rustc_codegen_spirv_target_specs:: Targets ;
2
4
use rustc_target:: spec:: { Cc , LinkerFlavor , PanicStrategy , Target , TargetOptions } ;
3
- use spirv_tools:: TargetEnv ;
4
5
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 ;
10
11
}
11
12
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
+ }
37
38
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 ,
45
61
}
46
62
}
47
63
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 ( )
50
66
}
51
67
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
+
53
75
let mut o = TargetOptions :: default ( ) ;
54
76
o. simd_types_indirect = false ;
55
77
o. allows_weak_linkage = false ;
@@ -61,69 +83,18 @@ impl SpirvTarget {
61
83
o. linker_flavor = LinkerFlavor :: Unix ( Cc :: No ) ;
62
84
o. panic_strategy = PanicStrategy :: Abort ;
63
85
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 ( ) ;
66
88
// TODO: Investigate if main_needs_argc_argv is useful (for building exes)
67
89
o. main_needs_argc_argv = false ;
68
- o
69
- }
70
90
71
- pub fn rustc_target ( & self ) -> Target {
72
91
Target {
73
- llvm_target : self . to_string ( ) . into ( ) ,
92
+ llvm_target : target . into ( ) ,
74
93
metadata : Default :: default ( ) ,
75
94
pointer_width : 32 ,
76
95
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,
103
98
}
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 )
128
99
}
129
100
}
0 commit comments