GLSL writer: validate all entry points with glslang.
Generate and validate all entry points individually. This is required since GLSL has separate shader files, and can only have a single "main" entry point. Bug: tint:1217 Change-Id: Ie5cb510aaef3b7c8a7573f5fa9446815284afecb Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/61920 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
f3f2d0a218
commit
7cf3b28a87
|
@ -16,6 +16,7 @@ out
|
|||
testing
|
||||
third_party/cpplint
|
||||
third_party/binutils
|
||||
third_party/glslang
|
||||
third_party/googletest
|
||||
third_party/gpuweb-cts
|
||||
third_party/llvm-build
|
||||
|
|
4
DEPS
4
DEPS
|
@ -9,6 +9,7 @@ vars = {
|
|||
'build_revision': 'c6c4a4c3ae890f2c020a087c90fb8c0b8be2816a',
|
||||
'buildtools_revision': 'e3db55b4639f2a331af6f3708ca1fbd22322aac3',
|
||||
'clang_revision': 'eb5ab41f3801e2085208204fd71a490573d72dfd',
|
||||
'glslang_revision': '4b7b86d568b40f4b076259dc2fc4cdd006340f34',
|
||||
'googletest_revision': '5c8ca58edfb304b2dd5e6061f83387470826dd87',
|
||||
'gpuweb_cts_revision': 'b0291fd966b55a5efc496772555b94842bde1085',
|
||||
'protobuf_revision': 'fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a',
|
||||
|
@ -27,6 +28,9 @@ deps = {
|
|||
'third_party/spirv-tools': Var('chromium_git') + Var('github') +
|
||||
'/KhronosGroup//SPIRV-Tools.git@' + Var('spirv_tools_revision'),
|
||||
|
||||
'third_party/glslang': Var('chromium_git') + Var('github') +
|
||||
'/KhronosGroup/glslang.git@' + Var('glslang_revision'),
|
||||
|
||||
# Dependencies required to use GN/Clang in standalone
|
||||
'build': Var('chromium_git') + '/chromium/src/build@' +
|
||||
Var('build_revision'),
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2021 The Dawn Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
glslang_spirv_tools_dir = "//third_party/spirv-tools"
|
|
@ -25,6 +25,13 @@ executable("tint") {
|
|||
"${tint_spirv_tools_dir}/:spvtools_val",
|
||||
]
|
||||
|
||||
if (tint_build_glsl_writer) {
|
||||
deps += [
|
||||
"${tint_root_dir}/third_party/glslang:glslang_default_resource_limits_sources",
|
||||
"${tint_root_dir}/third_party/glslang:glslang_lib_sources",
|
||||
]
|
||||
}
|
||||
|
||||
configs += [
|
||||
"${tint_root_dir}/src:tint_common_config",
|
||||
"${tint_root_dir}/src:tint_config",
|
||||
|
|
|
@ -25,4 +25,15 @@ if(${TINT_BUILD_SPV_READER} OR ${TINT_BUILD_SPV_WRITER})
|
|||
target_link_libraries(tint SPIRV-Tools)
|
||||
endif()
|
||||
|
||||
|
||||
if(${TINT_BUILD_GLSL_WRITER})
|
||||
target_link_libraries(tint glslang)
|
||||
target_link_libraries(tint glslang-default-resource-limits)
|
||||
if(NOT MSVC)
|
||||
target_compile_options(tint PRIVATE
|
||||
-Wno-reserved-id-macro
|
||||
-Wno-shadow-field-in-constructor
|
||||
-Wno-shadow
|
||||
-Wno-weak-vtables
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if TINT_BUILD_GLSL_WRITER
|
||||
#include "StandAlone/ResourceLimits.h"
|
||||
#include "glslang/Public/ShaderLang.h"
|
||||
#endif
|
||||
|
||||
#if TINT_BUILD_SPV_READER
|
||||
#include "spirv-tools/libspirv.hpp"
|
||||
#endif // TINT_BUILD_SPV_READER
|
||||
|
@ -845,14 +850,36 @@ bool GenerateHlsl(const tint::Program* program, const Options& options) {
|
|||
#endif // TINT_BUILD_HLSL_WRITER
|
||||
}
|
||||
|
||||
#if TINT_BUILD_GLSL_WRITER
|
||||
EShLanguage pipeline_stage_to_esh_language(tint::ast::PipelineStage stage) {
|
||||
switch (stage) {
|
||||
case tint::ast::PipelineStage::kFragment:
|
||||
return EShLangFragment;
|
||||
case tint::ast::PipelineStage::kVertex:
|
||||
return EShLangVertex;
|
||||
case tint::ast::PipelineStage::kCompute:
|
||||
return EShLangCompute;
|
||||
default:
|
||||
TINT_ASSERT(AST, false);
|
||||
return EShLangVertex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Generate GLSL code for a program.
|
||||
/// @param program the program to generate
|
||||
/// @param options the options that Tint was invoked with
|
||||
/// @returns true on success
|
||||
bool GenerateGlsl(const tint::Program* program, const Options& options) {
|
||||
#if TINT_BUILD_GLSL_WRITER
|
||||
if (options.validate) {
|
||||
glslang::InitializeProcess();
|
||||
}
|
||||
tint::writer::glsl::Options gen_options;
|
||||
auto result = tint::writer::glsl::Generate(program, gen_options);
|
||||
tint::inspector::Inspector inspector(program);
|
||||
for (auto& entry_point : inspector.GetEntryPoints()) {
|
||||
auto result =
|
||||
tint::writer::glsl::Generate(program, gen_options, entry_point.name);
|
||||
if (!result.success) {
|
||||
PrintWGSL(std::cerr, *program);
|
||||
std::cerr << "Failed to generate: " << result.error << std::endl;
|
||||
|
@ -863,7 +890,25 @@ bool GenerateGlsl(const tint::Program* program, const Options& options) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO(senorblanco): implement GLSL validation
|
||||
if (options.validate) {
|
||||
for (auto entry_pt : result.entry_points) {
|
||||
EShLanguage lang = pipeline_stage_to_esh_language(entry_pt.second);
|
||||
glslang::TShader shader(lang);
|
||||
const char* strings[1] = {result.glsl.c_str()};
|
||||
int lengths[1] = {static_cast<int>(result.glsl.length())};
|
||||
shader.setStringsWithLengths(strings, lengths, 1);
|
||||
shader.setEntryPoint("main");
|
||||
bool glslang_result =
|
||||
shader.parse(&glslang::DefaultTBuiltInResource, 310, EEsProfile,
|
||||
false, false, EShMsgDefault);
|
||||
if (!glslang_result) {
|
||||
std::cerr << "Error parsing GLSL shader:\n"
|
||||
<< shader.getInfoLog() << "\n"
|
||||
<< shader.getInfoDebugLog() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "src/transform/pad_array_elements.h"
|
||||
#include "src/transform/promote_initializers_to_const_var.h"
|
||||
#include "src/transform/simplify.h"
|
||||
#include "src/transform/single_entry_point.h"
|
||||
#include "src/transform/zero_init_workgroup_memory.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl);
|
||||
|
@ -69,6 +70,10 @@ Output Glsl::Run(const Program* in, const DataMap& inputs) {
|
|||
// variables directly.
|
||||
data.Add<CanonicalizeEntryPointIO::Config>(
|
||||
CanonicalizeEntryPointIO::ShaderStyle::kHlsl);
|
||||
if (cfg) {
|
||||
manager.Add<SingleEntryPoint>();
|
||||
data.Add<SingleEntryPoint::Config>(cfg->entry_point);
|
||||
}
|
||||
auto out = manager.Run(in, data);
|
||||
if (!out.program.IsValid()) {
|
||||
return out;
|
||||
|
@ -94,7 +99,8 @@ void Glsl::AddEmptyEntryPoint(CloneContext& ctx) const {
|
|||
ctx.dst->WorkgroupSize(1)});
|
||||
}
|
||||
|
||||
Glsl::Config::Config(bool disable_wi) : disable_workgroup_init(disable_wi) {}
|
||||
Glsl::Config::Config(const std::string& ep, bool disable_wi)
|
||||
: entry_point(ep), disable_workgroup_init(disable_wi) {}
|
||||
Glsl::Config::Config(const Config&) = default;
|
||||
Glsl::Config::~Config() = default;
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef SRC_TRANSFORM_GLSL_H_
|
||||
#define SRC_TRANSFORM_GLSL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/transform/transform.h"
|
||||
|
||||
namespace tint {
|
||||
|
@ -32,9 +34,11 @@ class Glsl : public Castable<Glsl, Transform> {
|
|||
/// Configuration options for the Glsl sanitizer transform.
|
||||
struct Config : public Castable<Data, transform::Data> {
|
||||
/// Constructor
|
||||
/// @param entry_point the root entry point function to generate
|
||||
/// @param disable_workgroup_init `true` to disable workgroup memory zero
|
||||
/// initialization
|
||||
explicit Config(bool disable_workgroup_init = false);
|
||||
explicit Config(const std::string& entry_point,
|
||||
bool disable_workgroup_init = false);
|
||||
|
||||
/// Copy constructor
|
||||
Config(const Config&);
|
||||
|
@ -42,6 +46,9 @@ class Glsl : public Castable<Glsl, Transform> {
|
|||
/// Destructor
|
||||
~Config() override;
|
||||
|
||||
/// GLSL generator wraps a single entry point in a main() function.
|
||||
std::string entry_point;
|
||||
|
||||
/// Set to `true` to disable workgroup memory zero initialization
|
||||
bool disable_workgroup_init = false;
|
||||
};
|
||||
|
|
|
@ -25,12 +25,16 @@ Result::Result() = default;
|
|||
Result::~Result() = default;
|
||||
Result::Result(const Result&) = default;
|
||||
|
||||
Result Generate(const Program* program, const Options&) {
|
||||
Result Generate(const Program* program,
|
||||
const Options&,
|
||||
const std::string& entry_point) {
|
||||
Result result;
|
||||
|
||||
// Run the GLSL sanitizer.
|
||||
transform::DataMap data;
|
||||
data.Add<transform::Glsl::Config>(entry_point);
|
||||
transform::Glsl sanitizer;
|
||||
auto output = sanitizer.Run(program);
|
||||
auto output = sanitizer.Run(program, data);
|
||||
if (!output.program.IsValid()) {
|
||||
result.success = false;
|
||||
result.error = output.program.Diagnostics().str();
|
||||
|
|
|
@ -67,7 +67,9 @@ struct Result {
|
|||
/// @param program the program to translate to GLSL
|
||||
/// @param options the configuration options to use when generating GLSL
|
||||
/// @returns the resulting GLSL and supplementary information
|
||||
Result Generate(const Program* program, const Options& options);
|
||||
Result Generate(const Program* program,
|
||||
const Options& options,
|
||||
const std::string& entry_point);
|
||||
|
||||
} // namespace glsl
|
||||
} // namespace writer
|
||||
|
|
|
@ -39,3 +39,8 @@ if(${TINT_BUILD_SPV_READER} OR ${TINT_BUILD_SPV_WRITER})
|
|||
add_subdirectory("${TINT_THIRD_PARTY_DIR}/spirv-tools" "${CMAKE_BINARY_DIR}/third_party/spirv-tools" EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${TINT_BUILD_GLSL_WRITER})
|
||||
set(SPIRV-Headers_SOURCE_DIR "${TINT_THIRD_PARTY_DIR}/glslang")
|
||||
add_subdirectory("${TINT_THIRD_PARTY_DIR}/glslang" "${CMAKE_BINARY_DIR}/third_party/glslang" EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue