7173c4a4d444 — Leonard Ritter a month ago
* `compile-spirv` now requires a version argument; passing `0` uses the best possible version
M include/scopes/scopes.h +1 -1
@@ 168,7 168,7 @@ SCOPES_LIBEXPORT sc_valueref_raises_t sc
 SCOPES_LIBEXPORT sc_valueref_raises_t sc_typify(const sc_closure_t *f, int numtypes, const sc_type_t **typeargs);
 SCOPES_LIBEXPORT sc_valueref_raises_t sc_typify_template(sc_valueref_t f, int numtypes, const sc_type_t **typeargs);
 SCOPES_LIBEXPORT sc_valueref_raises_t sc_compile(sc_valueref_t srcl, uint64_t flags);
-SCOPES_LIBEXPORT sc_string_raises_t sc_compile_spirv(sc_symbol_t target, sc_valueref_t srcl, uint64_t flags);
+SCOPES_LIBEXPORT sc_string_raises_t sc_compile_spirv(int version, sc_symbol_t target, sc_valueref_t srcl, uint64_t flags);
 SCOPES_LIBEXPORT sc_string_raises_t sc_compile_glsl(int version, sc_symbol_t target, sc_valueref_t srcl, uint64_t flags);
 SCOPES_LIBEXPORT const sc_string_t *sc_spirv_to_glsl(const sc_string_t *binary);
 SCOPES_LIBEXPORT const sc_string_t *sc_default_target_triple();

          
M lib/scopes/core.sc +5 -4
@@ 4593,8 4593,8 @@ spice-quote
     inline compile-glsl (version target func flags...)
         sc_compile_glsl version target func (parse-compile-flags flags...)
 
-    inline compile-spirv (target func flags...)
-        sc_compile_spirv target func (parse-compile-flags flags...)
+    inline compile-spirv (version target func flags...)
+        sc_compile_spirv version target func (parse-compile-flags flags...)
 
     inline compile-object (target file-kind path table flags...)
         sc_compile_object target file-kind path table (parse-compile-flags flags...)

          
@@ 5923,11 5923,12 @@ spice _static-compile-glsl (version targ
     hide-traceback;
     'tag `[(sc_compile_glsl version target func flags)] ('anchor args)
 
-spice _static-compile-spirv (target func flags)
+spice _static-compile-spirv (version target func flags)
+    version as:= i32
     target as:= Symbol
     flags as:= u64
     hide-traceback;
-    'tag `[(sc_compile_spirv target func flags)] ('anchor args)
+    'tag `[(sc_compile_spirv version target func flags)] ('anchor args)
 
 spice-quote
     inline static-compile (func flags...)

          
M src/gen_spirv.cpp +16 -7
@@ 250,6 250,7 @@ struct SPIRVGenerator {
     FunctionRef active_function;
     int functions_generated;
     spv_target_env env;
+    int version;
     bool use_combined_image_samplers = false;
 
     spv::Id get_op_ex(Symbol name) {

          
@@ 370,13 371,14 @@ struct SPIRVGenerator {
     }
 #endif
 
-    SPIRVGenerator(spv_target_env _env) :
+    SPIRVGenerator(spv_target_env _env, int _version) :
         builder('S' << 24 | 'C' << 16 | 'O' << 8 | 'P', &logger),
         entry_point(nullptr),
         glsl_ext_inst(0),
         use_debug_info(true),
         functions_generated(0),
-        env(_env) {
+        env(_env),
+        version(_version) {
         static_init();
         #if 0
         for (int i = 0; i < NumIntrinsics; ++i) {

          
@@ 2342,8 2344,15 @@ struct SPIRVGenerator {
             }
         }
 
-        // fixed: Invalid SPIR-V binary version 1.3 for target environment SPIR-V 1.0 (under OpenGL 4.5 semantics).
-        builder.dump((env == SPV_ENV_OPENGL_4_5)?0x10000:spv::Version, result);
+        int version = spv::Version;
+        if (env == SPV_ENV_OPENGL_4_5) {
+            // fixed: Invalid SPIR-V binary version 1.3 for target environment SPIR-V 1.0 (under OpenGL 4.5 semantics).
+            version = 0x10000; // SPIR-V 1.0
+        }
+        if (this->version != 0) {
+            version = this->version;
+        }
+        builder.dump(version, result);
 
         SCOPES_CHECK_RESULT(verify_spirv(env, result));
 

          
@@ 2425,14 2434,14 @@ SCOPES_RESULT(void) optimize_spirv(spv_t
     return {};
 }
 
-SCOPES_RESULT(const String *) compile_spirv(Symbol target, const FunctionRef &fn, uint64_t flags) {
+SCOPES_RESULT(const String *) compile_spirv(int version, Symbol target, const FunctionRef &fn, uint64_t flags) {
     SCOPES_RESULT_TYPE(const String *);
     Timer sum_compile_time(TIMER_CompileSPIRV);
 
     //SCOPES_CHECK_RESULT(fn->verify_compilable());
 
     const spv_target_env env = SPV_ENV_VULKAN_1_1_SPIRV_1_4;
-    SPIRVGenerator ctx(env);
+    SPIRVGenerator ctx(env, version);
     if (flags & CF_NoDebugInfo) {
         ctx.use_debug_info = false;
     }

          
@@ 2497,7 2506,7 @@ SCOPES_RESULT(const String *) compile_gl
 
     const spv_target_env env = SPV_ENV_OPENGL_4_5;
 
-    SPIRVGenerator ctx(env);
+    SPIRVGenerator ctx(env, 0);
     if (flags & CF_NoDebugInfo) {
         ctx.use_debug_info = false;
     }

          
M src/gen_spirv.hpp +1 -1
@@ 18,7 18,7 @@ namespace scopes {
 struct Function;
 
 //SCOPES_RESULT(void) optimize_spirv(std::vector<unsigned int> &result, int opt_level);
-SCOPES_RESULT(const String *) compile_spirv(Symbol target, const FunctionRef &fn, uint64_t flags);
+SCOPES_RESULT(const String *) compile_spirv(int version, Symbol target, const FunctionRef &fn, uint64_t flags);
 SCOPES_RESULT(const String *) compile_glsl(int version, Symbol target, const FunctionRef &fn, uint64_t flags);
 
 const String *spirv_to_glsl(const String *binary);

          
M src/globals.cpp +3 -3
@@ 281,11 281,11 @@ sc_valueref_raises_t sc_compile(sc_value
     return convert_result(compile(result, flags));
 }
 
-sc_string_raises_t sc_compile_spirv(sc_symbol_t target, sc_valueref_t srcl, uint64_t flags) {
+sc_string_raises_t sc_compile_spirv(int version, sc_symbol_t target, sc_valueref_t srcl, uint64_t flags) {
     using namespace scopes;
     SCOPES_RESULT_TYPE(const String *);
     auto result = SCOPES_C_GET_RESULT(extract_function_constant(srcl));
-    return convert_result(compile_spirv(target, result, flags));
+    return convert_result(compile_spirv(version, target, result, flags));
 }
 
 sc_string_raises_t sc_compile_glsl(int version, sc_symbol_t target, sc_valueref_t srcl, uint64_t flags) {

          
@@ 2325,7 2325,7 @@ void init_globals(int argc, char *argv[]
     DEFINE_RAISING_EXTERN_C_FUNCTION(sc_typify_template, TYPE_ValueRef, TYPE_ValueRef, TYPE_I32, native_ro_pointer_type(TYPE_Type));
     DEFINE_RAISING_EXTERN_C_FUNCTION(sc_typify, TYPE_ValueRef, TYPE_Closure, TYPE_I32, native_ro_pointer_type(TYPE_Type));
     DEFINE_RAISING_EXTERN_C_FUNCTION(sc_compile, TYPE_ValueRef, TYPE_ValueRef, TYPE_U64);
-    DEFINE_RAISING_EXTERN_C_FUNCTION(sc_compile_spirv, TYPE_String, TYPE_Symbol, TYPE_ValueRef, TYPE_U64);
+    DEFINE_RAISING_EXTERN_C_FUNCTION(sc_compile_spirv, TYPE_String, TYPE_I32, TYPE_Symbol, TYPE_ValueRef, TYPE_U64);
     DEFINE_RAISING_EXTERN_C_FUNCTION(sc_compile_glsl, TYPE_String, TYPE_I32, TYPE_Symbol, TYPE_ValueRef, TYPE_U64);
     DEFINE_EXTERN_C_FUNCTION(sc_spirv_to_glsl, TYPE_String, TYPE_String);
     DEFINE_EXTERN_C_FUNCTION(sc_default_target_triple, TYPE_String);

          
M testing/test_glsl.sc +1 -1
@@ 163,7 163,7 @@ do
                 v_tex_coords
 
     let bin =
-        compile-spirv 'fragment
+        compile-spirv 0 'fragment
             typify main
             'dump-disassembly
             #'no-opts

          
M testing/test_spirv_loop.sc +1 -1
@@ 20,7 20,7 @@ fn main ()
     return;
 
 let s =
-    compile-spirv 'fragment
+    compile-spirv 0 'fragment
         typify main
         'O2
         'dump-disassembly