google / shaderc

A collection of tools, libraries, and tests for Vulkan shader compilation.
Other
1.82k stars 353 forks source link

WGSL output format doesn't compile with latest Tint #1178

Open brendan-duncan opened 3 years ago

brendan-duncan commented 3 years ago

The WGSL output format for shaderc has been helpful for WebGPU testing.

Cloning Tint into the the third_party folder and trying to build with SHADERC_ENABLE_WGSL_OUTPUT enabled does not compile, it seems the Tint API has changed since this code was added to shaderc.

I got it working by updated the WGSL generating code in file_compiler.cc. I can submit a PR, or you can update the code, if you're interested in updating the WGSL output.

#if SHADERC_ENABLE_WGSL_OUTPUT == 1
       std::unique_ptr<tint::Program> program;
       program = std::make_unique<tint::Program>(tint::reader::spirv::Parse(std::vector<uint32_t>(result.begin(), result.end())));

       tint::transform::Manager transform_manager;
       auto mgr_out = transform_manager.Run(program.get());
       *program = std::move(mgr_out.program);

       auto wgsl_writer = std::make_unique<tint::writer::wgsl::Generator>(program.get());

       if (!wgsl_writer->Generate()) {
          std::cout << "error: failed to convert to WGSL: "
                    << wgsl_writer->error() << std::endl;
          return false;
        }

        auto* w = static_cast<tint::writer::Text*>(wgsl_writer.get());
        auto output = w->result();
        *out << output;
#endif  // SHADERC_ENABLE_WGSL_OUTPUT==1
ben-clayton commented 3 years ago

Note, I haven't attempted to compile this, but I think your example can be simplified down to:

#if SHADERC_ENABLE_WGSL_OUTPUT == 1
        auto program = tint::reader::spirv::Parse(std::vector<uint32_t>(result.begin(), result.end()));
        if (!program.IsValid()) {
            std::cout << "error: failed to parse SPIRV: "
                    << program.Diagnostics().str() << std::endl;
            return false;
        }

        tint::writer::wgsl::Generator wgsl_writer{program.get()};

        if (!wgsl_writer.Generate()) {
            std::cout << "error: failed to convert to WGSL: "
                    << wgsl_writer.error() << std::endl;
            return false;
        }

        *out << wgsl_writer.result();
#endif  // SHADERC_ENABLE_WGSL_OUTPUT==1
brendan-duncan commented 3 years ago

Just tested your version and it's not quite right. I'll poke at it to see what needs to be fixed. I wasn't a fan of all the memory moves and unique_ptr business, it's just how it was written in Tint.

brendan-duncan commented 3 years ago

Yours was close, just had a left over program.get(), which should have been &program.

#if SHADERC_ENABLE_WGSL_OUTPUT == 1
        auto program = tint::reader::spirv::Parse(std::vector<uint32_t>(result.begin(), result.end()));
        if (!program.IsValid()) {
            std::cout << "error: failed to parse SPIRV: "
                    << program.Diagnostics().str() << std::endl;
        }

        tint::writer::wgsl::Generator wgsl_writer{&program};

        if (!wgsl_writer.Generate()) {
            std::cout << "error: failed to convert to WGSL: "
                    << wgsl_writer.error() << std::endl;
            return false;
        }

        *out << wgsl_writer.result();
#endif  // SHADERC_ENABLE_WGSL_OUTPUT==1