[sksl] Emit SPIR-V 1.3 Bump the SPIR-V version emitted by SkSL from 1.0 to 1.3. SPIR-V 1.3 is the newest version Vulkan 1.1 (Skia's minimum) is required to accept, and the first version with GroupNonUniform (subgroup) operations. The SPIRV-Tools target environment used for validation (SkSL validator, skslc golden disassembly, and viewer) moves from SPV_ENV_VULKAN_1_0 to SPV_ENV_VULKAN_1_1 accordingly. Storage buffers still use Uniform + BufferBlock, which is deprecated but valid through SPIR-V 1.3. No change in generated golden output. Clients must create their VkInstance with apiVersion >= 1.1 and set VulkanBackendContext::fMaxAPIVersion to match; see the release note. Change-Id: Ifa6d0853e8035f58142d1ba0afe573cd1c9b9823 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/1378479 Reviewed-by: Nathan Sanchez <nathanasanchez@google.com> Commit-Queue: Thomas Smith <thomsmit@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp index d981436..1d3677e 100644 --- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.cpp
@@ -131,10 +131,11 @@ case StorageClass::kUniform: return SpvStorageClassUniform; // Note: In SPIR-V 1.3, a storage buffer can be declared with the "StorageBuffer" // storage class and the "Block" decoration and the <1.3 approach we use here ("Uniform" - // storage class and the "BufferBlock" decoration) is deprecated. Since we target SPIR-V - // 1.0, we have to use the deprecated approach which is well supported in Vulkan and + // storage class and the "BufferBlock" decoration) is deprecated. The deprecated approach + // is still valid in SPIR-V 1.3 (which we target), is well supported in Vulkan, and // addresses SkSL use cases (notably SkSL currently doesn't support pointer features that - // would benefit from SPV_KHR_variable_pointers capabilities). + // would benefit from SPV_KHR_variable_pointers capabilities). BufferBlock is removed in + // SPIR-V 1.4, so targeting 1.4+ will require switching to the StorageBuffer approach. case StorageClass::kStorageBuffer: return SpvStorageClassUniform; case StorageClass::kOutput: return SpvStorageClassOutput; case StorageClass::kWorkgroup: return SpvStorageClassWorkgroup;
diff --git a/src/sksl/codegen/SkSLSPIRVCodeGenerator.h b/src/sksl/codegen/SkSLSPIRVCodeGenerator.h index 41a41b5..6ab600f 100644 --- a/src/sksl/codegen/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/codegen/SkSLSPIRVCodeGenerator.h
@@ -27,7 +27,12 @@ // This is intentionally independent of SpvVersion in spirv.h, which tracks the newest version the // header describes. Tools that validate or disassemble SkSL's SPIR-V output must use a // spvtools target environment that accepts this version. -inline constexpr uint32_t kSPIRVVersion = 0x00010000; // SPIR-V 1.0 +// +// SPIR-V 1.3 is the newest version a Vulkan 1.1 device (Skia's minimum) is required to accept, and +// the first to include GroupNonUniform (subgroup) operations. Note that the device's effective API +// version is min(VkApplicationInfo::apiVersion, VkPhysicalDeviceProperties::apiVersion), which is +// why VulkanBackendContext::fMaxAPIVersion must match the instance's apiVersion. +inline constexpr uint32_t kSPIRVVersion = 0x00010300; // SPIR-V 1.3 /** * Converts a Program into a SPIR-V binary. Prefer the std::vector<uint32_t> variant bacause the
diff --git a/src/sksl/codegen/SkSLSPIRVValidator.cpp b/src/sksl/codegen/SkSLSPIRVValidator.cpp index 4585218..ac07f20 100644 --- a/src/sksl/codegen/SkSLSPIRVValidator.cpp +++ b/src/sksl/codegen/SkSLSPIRVValidator.cpp
@@ -17,7 +17,8 @@ static bool validate_spirv(ErrorReporter& reporter, SkSpan<const uint32_t> program, bool disassemble) { - spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); + // Vulkan 1.1 accepts SPIR-V 1.0-1.3. This must accept SkSL::kSPIRVVersion. + spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1); std::string errors; auto msgFn = [&errors](spv_message_level_t, const char*, const spv_position_t&, const char* m) { errors += "SPIR-V validation error: ";
diff --git a/tools/skslc/Main.cpp b/tools/skslc/Main.cpp index 3209377..cd2aa70 100644 --- a/tools/skslc/Main.cpp +++ b/tools/skslc/Main.cpp
@@ -657,7 +657,9 @@ return false; } // Convert the string-stream to a SPIR-V disassembly. - spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); + static_assert(SkSL::kSPIRVVersion <= 0x00010300, + "SPV_ENV_VULKAN_1_1 only accepts SPIR-V up to 1.3"); + spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1); std::string disassembly; uint32_t options = spvtools::SpirvTools::kDefaultDisassembleOption; options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT |
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 0b94e93..8a305f8 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp
@@ -3221,7 +3221,8 @@ #if defined(SK_VULKAN) if (isVulkan && !sksl) { // Disassemble the SPIR-V into its textual form. - spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0); + // Vulkan 1.1 accepts SPIR-V 1.0-1.3, matching SkSL::kSPIRVVersion. + spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1); uint32_t options = spvtools::SpirvTools::kDefaultDisassembleOption; options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT | SPV_BINARY_TO_TEXT_OPTION_INDENT |