SkSLWGSLValidator.cpp (2562B)
1 /* 2 * Copyright 2024 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "src/sksl/codegen/SkSLWGSLValidator.h" 9 10 #include "src/sksl/SkSLErrorReporter.h" 11 #include "src/sksl/SkSLPosition.h" 12 13 #include "src/tint/lang/wgsl/enums.h" 14 #include "src/tint/lang/wgsl/reader/options.h" 15 #include "tint/tint.h" 16 17 namespace SkSL { 18 19 static bool validate_wgsl(ErrorReporter& reporter, 20 std::string_view wgsl, 21 bool appendError, 22 std::string* warnings) { 23 // Enable the WGSL optional features that Skia might rely on. 24 tint::wgsl::reader::Options options; 25 for (auto extension : {tint::wgsl::Extension::kChromiumExperimentalPixelLocal, 26 tint::wgsl::Extension::kDualSourceBlending}) { 27 options.allowed_features.extensions.insert(extension); 28 } 29 options.allowed_features.features.insert( 30 tint::wgsl::LanguageFeature::kUnrestrictedPointerParameters); 31 32 // Verify that the WGSL we produced is valid. 33 tint::Source::File srcFile("", wgsl); 34 tint::Program program(tint::wgsl::reader::Parse(&srcFile, options)); 35 36 if (program.Diagnostics().ContainsErrors()) { 37 // The program isn't valid WGSL. 38 if (appendError) { 39 // Report the error via SkDEBUGFAIL and append the generated program for 40 // ease of debugging. We don't do this for our golden test output because 41 // it can change too often 42 tint::diag::Formatter diagFormatter; 43 std::string diagOutput = diagFormatter.Format(program.Diagnostics()).Plain(); 44 diagOutput += "\n"; 45 diagOutput += wgsl; 46 SkDEBUGFAILF("%s", diagOutput.c_str()); 47 } else { 48 reporter.error(Position(), 49 std::string("Tint compilation failed.\n\n") + std::string(wgsl)); 50 } 51 return false; 52 } 53 54 if (!program.Diagnostics().empty()) { 55 // The program contains warnings. Report them as-is. 56 tint::diag::Formatter diagFormatter; 57 *warnings = diagFormatter.Format(program.Diagnostics()).Plain(); 58 } 59 return true; 60 } 61 62 bool ValidateWGSL(ErrorReporter& reporter, std::string_view wgsl, std::string* warnings) { 63 return validate_wgsl(reporter, wgsl, false, warnings); 64 } 65 66 bool ValidateWGSLVerbose(ErrorReporter& reporter, std::string_view wgsl, std::string* warnings) { 67 return validate_wgsl(reporter, wgsl, true, warnings); 68 } 69 70 } // namespace SkSL