mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-12 06:45:16 +00:00
writer: Move sanitizers into the backends
Adds a new single-function API for the generators, which applies the sanitizing transform and performs the generation in one step, and returns a result object which contains the generated code and success status/diagnostics. The new APIs take an `Option` structure to control backend-specific generation details (e.g. MSL fixed sample mask). The result objects also provide backend-specific feedback (e.g. whether a UBO of buffer lengths was generated). HLSL needs a list of entry points to validate, and it's the HLSL sanitizer that generates an entry point for programs that do not have one. This change makes the HLSL generator return the list of post-sanitize entry points so that the Tint executable can forward them to the validation code. Change-Id: I2d5aa27fda95d7c50c5bef41e206aee38f2fd2eb Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/57101 Auto-Submit: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
committed by
Tint LUCI CQ
parent
08b0ab9b92
commit
af89c729ed
134
src/val/hlsl.cc
134
src/val/hlsl.cc
@@ -14,8 +14,6 @@
|
||||
|
||||
#include "src/val/val.h"
|
||||
|
||||
#include "src/ast/module.h"
|
||||
#include "src/program.h"
|
||||
#include "src/utils/io/command.h"
|
||||
#include "src/utils/io/tmpfile.h"
|
||||
|
||||
@@ -33,7 +31,7 @@ namespace val {
|
||||
|
||||
Result HlslUsingDXC(const std::string& dxc_path,
|
||||
const std::string& source,
|
||||
Program* program) {
|
||||
const EntryPointList& entry_points) {
|
||||
Result result;
|
||||
|
||||
auto dxc = utils::Command(dxc_path);
|
||||
@@ -48,48 +46,42 @@ Result HlslUsingDXC(const std::string& dxc_path,
|
||||
utils::TmpFile file;
|
||||
file << source;
|
||||
|
||||
bool found_an_entrypoint = false;
|
||||
for (auto* func : program->AST().Functions()) {
|
||||
if (func->IsEntryPoint()) {
|
||||
found_an_entrypoint = true;
|
||||
for (auto ep : entry_points) {
|
||||
const char* profile = "";
|
||||
|
||||
const char* profile = "";
|
||||
|
||||
switch (func->pipeline_stage()) {
|
||||
case ast::PipelineStage::kNone:
|
||||
result.output = "Invalid PipelineStage";
|
||||
result.failed = true;
|
||||
return result;
|
||||
case ast::PipelineStage::kVertex:
|
||||
profile = "-T vs_6_0";
|
||||
break;
|
||||
case ast::PipelineStage::kFragment:
|
||||
profile = "-T ps_6_0";
|
||||
break;
|
||||
case ast::PipelineStage::kCompute:
|
||||
profile = "-T cs_6_0";
|
||||
break;
|
||||
}
|
||||
|
||||
auto name = program->Symbols().NameFor(func->symbol());
|
||||
auto res = dxc(profile, "-E " + name, file.Path());
|
||||
if (!res.out.empty()) {
|
||||
if (!result.output.empty()) {
|
||||
result.output += "\n";
|
||||
}
|
||||
result.output += res.out;
|
||||
}
|
||||
if (!res.err.empty()) {
|
||||
if (!result.output.empty()) {
|
||||
result.output += "\n";
|
||||
}
|
||||
result.output += res.err;
|
||||
}
|
||||
result.failed = (res.error_code != 0);
|
||||
switch (ep.second) {
|
||||
case ast::PipelineStage::kNone:
|
||||
result.output = "Invalid PipelineStage";
|
||||
result.failed = true;
|
||||
return result;
|
||||
case ast::PipelineStage::kVertex:
|
||||
profile = "-T vs_6_0";
|
||||
break;
|
||||
case ast::PipelineStage::kFragment:
|
||||
profile = "-T ps_6_0";
|
||||
break;
|
||||
case ast::PipelineStage::kCompute:
|
||||
profile = "-T cs_6_0";
|
||||
break;
|
||||
}
|
||||
|
||||
auto res = dxc(profile, "-E " + ep.first, file.Path());
|
||||
if (!res.out.empty()) {
|
||||
if (!result.output.empty()) {
|
||||
result.output += "\n";
|
||||
}
|
||||
result.output += res.out;
|
||||
}
|
||||
if (!res.err.empty()) {
|
||||
if (!result.output.empty()) {
|
||||
result.output += "\n";
|
||||
}
|
||||
result.output += res.err;
|
||||
}
|
||||
result.failed = (res.error_code != 0);
|
||||
}
|
||||
|
||||
if (!found_an_entrypoint) {
|
||||
if (entry_points.empty()) {
|
||||
result.output = "No entrypoint found";
|
||||
result.failed = true;
|
||||
return result;
|
||||
@@ -99,7 +91,8 @@ Result HlslUsingDXC(const std::string& dxc_path,
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
Result HlslUsingFXC(const std::string& source, Program* program) {
|
||||
Result HlslUsingFXC(const std::string& source,
|
||||
const EntryPointList& entry_points) {
|
||||
Result result;
|
||||
|
||||
// This library leaks if an error happens in this function, but it is ok
|
||||
@@ -122,45 +115,38 @@ Result HlslUsingFXC(const std::string& source, Program* program) {
|
||||
|
||||
result.source = source;
|
||||
|
||||
bool found_an_entrypoint = false;
|
||||
for (auto* func : program->AST().Functions()) {
|
||||
if (func->IsEntryPoint()) {
|
||||
found_an_entrypoint = true;
|
||||
|
||||
const char* profile = "";
|
||||
switch (func->pipeline_stage()) {
|
||||
case ast::PipelineStage::kNone:
|
||||
result.output = "Invalid PipelineStage";
|
||||
result.failed = true;
|
||||
return result;
|
||||
case ast::PipelineStage::kVertex:
|
||||
profile = "vs_5_1";
|
||||
break;
|
||||
case ast::PipelineStage::kFragment:
|
||||
profile = "ps_5_1";
|
||||
break;
|
||||
case ast::PipelineStage::kCompute:
|
||||
profile = "cs_5_1";
|
||||
break;
|
||||
}
|
||||
|
||||
auto name = program->Symbols().NameFor(func->symbol());
|
||||
|
||||
ComPtr<ID3DBlob> compiledShader;
|
||||
ComPtr<ID3DBlob> errors;
|
||||
if (FAILED(d3dCompile(source.c_str(), source.length(), nullptr, nullptr,
|
||||
nullptr, name.c_str(), profile, 0, 0,
|
||||
&compiledShader, &errors))) {
|
||||
result.output = static_cast<char*>(errors->GetBufferPointer());
|
||||
for (auto ep : entry_points) {
|
||||
const char* profile = "";
|
||||
switch (ep.second) {
|
||||
case ast::PipelineStage::kNone:
|
||||
result.output = "Invalid PipelineStage";
|
||||
result.failed = true;
|
||||
return result;
|
||||
}
|
||||
case ast::PipelineStage::kVertex:
|
||||
profile = "vs_5_1";
|
||||
break;
|
||||
case ast::PipelineStage::kFragment:
|
||||
profile = "ps_5_1";
|
||||
break;
|
||||
case ast::PipelineStage::kCompute:
|
||||
profile = "cs_5_1";
|
||||
break;
|
||||
}
|
||||
|
||||
ComPtr<ID3DBlob> compiledShader;
|
||||
ComPtr<ID3DBlob> errors;
|
||||
if (FAILED(d3dCompile(source.c_str(), source.length(), nullptr, nullptr,
|
||||
nullptr, ep.first.c_str(), profile, 0, 0,
|
||||
&compiledShader, &errors))) {
|
||||
result.output = static_cast<char*>(errors->GetBufferPointer());
|
||||
result.failed = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(fxcLib);
|
||||
|
||||
if (!found_an_entrypoint) {
|
||||
if (entry_points.empty()) {
|
||||
result.output = "No entrypoint found";
|
||||
result.failed = true;
|
||||
return result;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#define SRC_VAL_VAL_H_
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "src/ast/pipeline_stage.h"
|
||||
|
||||
// Forward declarations
|
||||
namespace tint {
|
||||
@@ -25,6 +29,8 @@ class Program;
|
||||
namespace tint {
|
||||
namespace val {
|
||||
|
||||
using EntryPointList = std::vector<std::pair<std::string, ast::PipelineStage>>;
|
||||
|
||||
/// The return structure of Validate()
|
||||
struct Result {
|
||||
/// True if validation passed
|
||||
@@ -39,19 +45,20 @@ struct Result {
|
||||
/// compiles successfully.
|
||||
/// @param dxc_path path to DXC
|
||||
/// @param source the generated HLSL source
|
||||
/// @param program the HLSL program
|
||||
/// @param entry_points the list of entry points to validate
|
||||
/// @return the result of the compile
|
||||
Result HlslUsingDXC(const std::string& dxc_path,
|
||||
const std::string& source,
|
||||
Program* program);
|
||||
const EntryPointList& entry_points);
|
||||
|
||||
#ifdef _WIN32
|
||||
/// Hlsl attempts to compile the shader with FXC, verifying that the shader
|
||||
/// compiles successfully.
|
||||
/// @param source the generated HLSL source
|
||||
/// @param program the HLSL program
|
||||
/// @param entry_points the list of entry points to validate
|
||||
/// @return the result of the compile
|
||||
Result HlslUsingFXC(const std::string& source, Program* program);
|
||||
Result HlslUsingFXC(const std::string& source,
|
||||
const EntryPointList& entry_points);
|
||||
#endif // _WIN32
|
||||
|
||||
/// Msl attempts to compile the shader with the Metal Shader Compiler,
|
||||
|
||||
Reference in New Issue
Block a user