#!/usr/bin/python3
# Copyright 2018 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_vk_internal_shaders.py:
#  Code generation for internal Vulkan shaders. Should be run when an internal
#  shader program is changed, added or removed.
#  Because this script can be slow direct invocation is supported. But before
#  code upload please run scripts/run_code_generation.py.

from datetime import date
import io
import json
import multiprocessing
import os
import platform
import re
import subprocess
import sys
import gzip

out_file_cpp = 'vk_internal_shaders_autogen.cpp'
out_file_h = 'vk_internal_shaders_autogen.h'
out_file_gni = 'vk_internal_shaders_autogen.gni'

is_windows = platform.system() == 'Windows'
is_linux = platform.system() == 'Linux'

# Templates for the generated files:
template_shader_library_cpp = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {out_file_name}:
//   Pre-generated shader library for the ANGLE Vulkan back-end.

#include "libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h"

#define USE_SYSTEM_ZLIB
#include "compression_utils_portable.h"

namespace rx
{{
namespace vk
{{
namespace
{{
{internal_shader_includes}

// This is compressed SPIR-V binary blob and size
struct CompressedShaderBlob
{{
    const uint8_t *code;
    uint32_t size;
}};

{shader_tables_cpp}

angle::Result GetShader(Context *context,
                        RefCounted<ShaderAndSerial> *shaders,
                        const CompressedShaderBlob *compressedShaderBlobs,
                        size_t shadersCount,
                        uint32_t shaderFlags,
                        RefCounted<ShaderAndSerial> **shaderOut)
{{
    ASSERT(shaderFlags < shadersCount);
    RefCounted<ShaderAndSerial> &shader = shaders[shaderFlags];
    *shaderOut                          = &shader;

    if (shader.get().valid())
    {{
        return angle::Result::Continue;
    }}

    // Create shader lazily. Access will need to be locked for multi-threading.
    const CompressedShaderBlob &compressedShaderCode = compressedShaderBlobs[shaderFlags];
    ASSERT(compressedShaderCode.code != nullptr);

    uLong uncompressedSize = zlib_internal::GetGzipUncompressedSize(compressedShaderCode.code,
                                                                    compressedShaderCode.size);
    std::vector<uint32_t> shaderCode((uncompressedSize + 3) / 4, 0);

    // Note: we assume a little-endian environment throughout ANGLE.
    int zResult = zlib_internal::GzipUncompressHelper(reinterpret_cast<uint8_t *>(shaderCode.data()),
            &uncompressedSize, compressedShaderCode.code, compressedShaderCode.size);

    if (zResult != Z_OK)
    {{
        ERR() << "Failure to decompressed internal shader: " << zResult << "\\n";
        return angle::Result::Stop;
    }}

    return InitShaderAndSerial(context, &shader.get(), shaderCode.data(), shaderCode.size() * 4);
}}
}}  // anonymous namespace


ShaderLibrary::ShaderLibrary()
{{
}}

ShaderLibrary::~ShaderLibrary()
{{
}}

void ShaderLibrary::destroy(VkDevice device)
{{
    {shader_destroy_calls}
}}

{shader_get_functions_cpp}
}}  // namespace vk
}}  // namespace rx
"""

template_shader_library_h = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {out_file_name}:
//   Pre-generated shader library for the ANGLE Vulkan back-end.

#ifndef LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
#define LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_

#include "libANGLE/renderer/vulkan/vk_utils.h"

namespace rx
{{
namespace vk
{{
namespace InternalShader
{{
{shader_variation_definitions}
}}  // namespace InternalShader

class ShaderLibrary final : angle::NonCopyable
{{
  public:
    ShaderLibrary();
    ~ShaderLibrary();

    void destroy(VkDevice device);

    {shader_get_functions_h}

  private:
    {shader_tables_h}
}};
}}  // namespace vk
}}  // namespace rx

#endif  // LIBANGLE_RENDERER_VULKAN_VK_INTERNAL_SHADERS_AUTOGEN_H_
"""

template_shader_includes_gni = u"""# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name} using data from {input_file_name}
#
# Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# {out_file_name}:
#   List of generated shaders for inclusion in ANGLE's build process.

angle_vulkan_internal_shaders = [
{shaders_list}
]
"""

template_spirv_blob_inc = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {out_file_name}:
//   Pre-generated shader for the ANGLE Vulkan back-end.

#pragma once
constexpr uint8_t {variable_name}[] = {{
    {blob}
}};

// Generated from:
//
{preprocessed_source}
"""

# Gets the constant variable name for a generated shader.
def get_var_name(output, prefix='k'):
    return prefix + output.replace(".", "_")


# Gets the namespace name given to constants generated from shader_file
def get_namespace_name(shader_file):
    return get_var_name(os.path.basename(shader_file), '')


# Gets the namespace name given to constants generated from shader_file
def get_variation_table_name(shader_file, prefix='k'):
    return get_var_name(os.path.basename(shader_file), prefix) + '_shaders'


# Gets the internal ID string for a particular shader.
def get_shader_id(shader):
    file = os.path.splitext(os.path.basename(shader))[0]
    return file.replace(".", "_")


# Returns the name of the generated SPIR-V file for a shader.
def get_output_path(name):
    return os.path.join('shaders', 'gen', name + ".inc")


# Finds a path to GN's out directory
def get_linux_glslang_exe_path():
    return '../../../../tools/glslang/glslang_validator'


def get_win_glslang_exe_path():
    return get_linux_glslang_exe_path() + '.exe'


def get_glslang_exe_path():
    glslang_exe = get_win_glslang_exe_path() if is_windows else get_linux_glslang_exe_path()
    if not os.path.isfile(glslang_exe):
        raise Exception('Could not find %s' % glslang_exe)
    return glslang_exe


# Generates the code for a shader blob array entry.
def gen_shader_blob_entry(shader):
    var_name = get_var_name(os.path.basename(shader))[0:-4]
    return "{%s, %s}" % (var_name, "sizeof(%s)" % var_name)


def slash(s):
    return s.replace('\\', '/')


def gen_shader_include(shader):
    return '#include "libANGLE/renderer/vulkan/%s"' % slash(shader)


def get_variations_path(shader):
    variation_file = shader + '.json'
    return variation_file if os.path.exists(variation_file) else None


def get_shader_variations(shader):
    variation_file = get_variations_path(shader)
    if variation_file is None:
        # If there is no variation file, assume none.
        return ({}, [])

    with open(variation_file) as fin:
        variations = json.loads(fin.read())
        flags = {}
        enums = []

        for key, value in variations.iteritems():
            if key == "Description":
                continue
            elif key == "Flags":
                flags = value
            elif len(value) > 0:
                enums.append((key, value))

        # sort enums so the ones with the most waste ends up last, reducing the table size
        enums.sort(key=lambda enum: (1 << (len(enum[1]) - 1).bit_length()) / float(len(enum[1])))

        return (flags, enums)


def get_variation_bits(flags, enums):
    flags_bits = len(flags)
    enum_bits = [(len(enum[1]) - 1).bit_length() for enum in enums]
    return (flags_bits, enum_bits)


def next_enum_variation(enums, enum_indices):
    """Loop through indices from [0, 0, ...] to [L0-1, L1-1, ...]
    where Li is len(enums[i]).  The list can be thought of as a number with many
    digits, where each digit is in [0, Li), and this function effectively implements
    the increment operation, with the least-significant digit being the first item."""
    for i in range(len(enums)):
        current = enum_indices[i]
        # if current digit has room, increment it.
        if current + 1 < len(enums[i][1]):
            enum_indices[i] = current + 1
            return True
        # otherwise reset it to 0 and carry to the next digit.
        enum_indices[i] = 0

    # if this is reached, the number has overflowed and the loop is finished.
    return False


compact_newlines_regex = re.compile(r"\n\s*\n", re.MULTILINE)


def cleanup_preprocessed_shader(shader_text):
    return compact_newlines_regex.sub('\n\n', shader_text.strip())


def read_and_compress_spirv_blob(blob_path):
    with open(blob_path, 'rb') as blob_file:
        blob = blob_file.read()

    buf = io.BytesIO()
    with gzip.GzipFile(fileobj=buf, mode='wb', compresslevel=9, mtime=0) as f:
        f.write(blob)
    return buf.getvalue()


def write_compressed_spirv_blob_as_c_array(output_path, variable_name, compressed_blob,
                                           preprocessed_source):
    hex_array = ['0x{:02x}'.format(ord(byte)) for byte in compressed_blob]
    blob = ',\n    '.join(','.join(hex_array[i:i + 16]) for i in range(0, len(hex_array), 16))

    with open(output_path, 'wb') as incfile:
        incfile.write(
            template_spirv_blob_inc.format(
                script_name=__file__,
                copyright_year=date.today().year,
                out_file_name=output_path,
                variable_name=variable_name,
                blob=blob,
                preprocessed_source=preprocessed_source))


class CompileQueue:

    class CompressAndAppendPreprocessorOutput:

        def __init__(self, shader_file, preprocessor_args, output_path, variable_name):
            # Asynchronously launch the preprocessor job.
            self.process = subprocess.Popen(
                preprocessor_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            # Store the file name for output to be appended to.
            self.output_path = output_path
            self.variable_name = variable_name
            # Store info for error description.
            self.shader_file = shader_file

        def wait(self, queue):
            (out, err) = self.process.communicate()
            if self.process.returncode == 0:
                # Use unix line endings.
                out = out.replace('\r\n', '\n')
                # Clean up excessive empty lines.
                out = cleanup_preprocessed_shader(out)
                # Comment it out!
                out = '\n'.join([('// ' + line).strip() for line in out.splitlines()])

                # Read the SPIR-V blob and compress it.
                compressed_blob = read_and_compress_spirv_blob(self.output_path)

                # Write the compressed blob as a C array in the output file, followed by the
                # preprocessor output.
                write_compressed_spirv_blob_as_c_array(self.output_path, self.variable_name,
                                                       compressed_blob, out)

                out = None
            return (out, err, self.process.returncode, None,
                    "Error running preprocessor on " + self.shader_file)

    class CompileToSPIRV:

        def __init__(self, shader_file, shader_basename, variation_string, output_path,
                     compile_args, preprocessor_args, variable_name):
            # Asynchronously launch the compile job.
            self.process = subprocess.Popen(
                compile_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            # Store info for launching the preprocessor.
            self.preprocessor_args = preprocessor_args
            self.output_path = output_path
            # Store info for job and error description.
            self.shader_file = shader_file
            self.shader_basename = shader_basename
            self.variation_string = variation_string
            self.variable_name = variable_name

        def wait(self, queue):
            (out, err) = self.process.communicate()
            if self.process.returncode == 0:
                # Insert the preprocessor job in the queue.
                queue.append(
                    CompileQueue.CompressAndAppendPreprocessorOutput(self.shader_file,
                                                                     self.preprocessor_args,
                                                                     self.output_path,
                                                                     self.variable_name))
            # If all the output says is the source file name, don't bother printing it.
            if out.strip() == self.shader_file:
                out = None
            description = self.output_path + ': ' + self.shader_basename + self.variation_string
            return (out, err, self.process.returncode, description,
                    "Error compiling " + self.shader_file)

    def __init__(self):
        # Compile with as many CPU threads are detected.  Once a shader is compiled, another job is
        # automatically added to the queue to append the preprocessor output to the generated file.
        self.queue = []
        self.thread_count = multiprocessing.cpu_count()

    def _wait_first(self, ignore_output=False):
        (out, err, returncode, description, exception_description) = self.queue[0].wait(self.queue)
        self.queue.pop(0)
        if not ignore_output:
            if description:
                print(description)
            if out and out.strip():
                print(out.strip())
            if err and err.strip():
                print(err)
            if returncode != 0:
                return exception_description
        return None

    # Wait for all pending tasks.  If called after error is detected, ignore_output can be used to
    # make sure errors in later jobs are suppressed to avoid cluttering the output.  This is
    # because the same compile error is likely present in other variations of the same shader and
    # outputting the same error multiple times is not useful.
    def _wait_all(self, ignore_output=False):
        exception_description = None
        while len(self.queue) > 0:
            this_job_exception = self._wait_first(ignore_output)
            # If encountered an error, keep it to be raised, ignoring errors from following jobs.
            if this_job_exception and not ignore_output:
                exception_description = this_job_exception
                ignore_output = True

        return exception_description

    def add_job(self, shader_file, shader_basename, variation_string, output_path, compile_args,
                preprocessor_args, variable_name):
        # If the queue is full, wait until there is at least one slot available.
        while len(self.queue) >= self.thread_count:
            exception = self._wait_first(False)
            # If encountered an exception, cleanup following jobs and raise it.
            if exception:
                self._wait_all(True)
                raise Exception(exception)

        # Add a compile job
        self.queue.append(
            CompileQueue.CompileToSPIRV(shader_file, shader_basename, variation_string,
                                        output_path, compile_args, preprocessor_args,
                                        variable_name))

    def finish(self):
        exception = self._wait_all(False)
        # If encountered an exception, cleanup following jobs and raise it.
        if exception is not None:
            raise Exception(exception)


# If the option is just a string, that's the name.  Otherwise, it could be
# [ name, arg1, ..., argN ].  In that case, name is option[0] and option[1:] are extra arguments
# that need to be passed to glslang_validator for this variation.
def get_variation_name(option):
    return option if isinstance(option, unicode) else option[0]


def get_variation_args(option):
    return [] if isinstance(option, unicode) else option[1:]


def compile_variation(glslang_path, compile_queue, shader_file, shader_basename, flags, enums,
                      flags_active, enum_indices, flags_bits, enum_bits, output_shaders):

    glslang_args = [glslang_path]

    # generate -D defines and the output file name
    #
    # The variations are given a bit pattern to be able to OR different flags into a variation. The
    # least significant bits are the flags, where there is one bit per flag.  After that, each enum
    # takes up as few bits as needed to count that many enum values.
    variation_bits = 0
    variation_string = ''
    variation_extra_args = []
    for f in range(len(flags)):
        if flags_active & (1 << f):
            flag = flags[f]
            flag_name = get_variation_name(flag)
            variation_extra_args += get_variation_args(flag)
            glslang_args.append('-D' + flag_name + '=1')

            variation_bits |= 1 << f
            variation_string += '|' + flag_name

    current_bit_start = flags_bits

    for e in range(len(enums)):
        enum = enums[e][1][enum_indices[e]]
        enum_name = get_variation_name(enum)
        variation_extra_args += get_variation_args(enum)
        glslang_args.append('-D' + enum_name + '=1')

        variation_bits |= enum_indices[e] << current_bit_start
        current_bit_start += enum_bits[e]
        variation_string += '|' + enum_name

    output_name = '%s.%08X' % (shader_basename, variation_bits)
    output_path = get_output_path(output_name)
    output_shaders.append(output_path)

    if glslang_path is not None:
        glslang_preprocessor_output_args = glslang_args + ['-E']
        glslang_preprocessor_output_args.append(shader_file)  # Input GLSL shader

        glslang_args += ['-V']  # Output mode is Vulkan
        glslang_args += ['-Os']  # Optimize by default.
        glslang_args += ['-g0']  # Strip debug info to save on binary size.
        glslang_args += variation_extra_args  # Add other flags, or override -Os or -g0
        glslang_args += ['-o', output_path]  # Output file
        glslang_args.append(shader_file)  # Input GLSL shader

        compile_queue.add_job(shader_file, shader_basename, variation_string, output_path,
                              glslang_args, glslang_preprocessor_output_args,
                              get_var_name(output_name))


class ShaderAndVariations:

    def __init__(self, shader_file):
        self.shader_file = shader_file
        (self.flags, self.enums) = get_shader_variations(shader_file)
        get_variation_bits(self.flags, self.enums)
        (self.flags_bits, self.enum_bits) = get_variation_bits(self.flags, self.enums)
        # Maximum index value has all flags set and all enums at max value.
        max_index = (1 << self.flags_bits) - 1
        current_bit_start = self.flags_bits
        for (name, values), bits in zip(self.enums, self.enum_bits):
            max_index |= (len(values) - 1) << current_bit_start
            current_bit_start += bits
        # Minimum array size is one more than the maximum value.
        self.array_len = max_index + 1


def get_variation_definition(shader_and_variation):
    shader_file = shader_and_variation.shader_file
    flags = shader_and_variation.flags
    enums = shader_and_variation.enums
    flags_bits = shader_and_variation.flags_bits
    enum_bits = shader_and_variation.enum_bits
    array_len = shader_and_variation.array_len

    namespace_name = get_namespace_name(shader_file)

    definition = 'namespace %s\n{\n' % namespace_name
    if len(flags) > 0:
        definition += 'enum flags\n{\n'
        definition += ''.join([
            'k%s = 0x%08X,\n' % (get_variation_name(flags[f]), 1 << f) for f in range(len(flags))
        ])
        definition += '};\n'

    current_bit_start = flags_bits

    for e in range(len(enums)):
        enum = enums[e]
        enum_name = enum[0]
        definition += 'enum %s\n{\n' % enum_name
        definition += ''.join([
            'k%s = 0x%08X,\n' % (get_variation_name(enum[1][v]), v << current_bit_start)
            for v in range(len(enum[1]))
        ])
        definition += '};\n'
        current_bit_start += enum_bits[e]

    definition += 'constexpr size_t kArrayLen = 0x%08X;\n' % array_len

    definition += '}  // namespace %s\n' % namespace_name
    return definition


def get_shader_table_h(shader_and_variation):
    shader_file = shader_and_variation.shader_file
    flags = shader_and_variation.flags
    enums = shader_and_variation.enums

    table_name = get_variation_table_name(shader_file, 'm')

    table = 'RefCounted<ShaderAndSerial> %s[' % table_name

    namespace_name = "InternalShader::" + get_namespace_name(shader_file)

    table += '%s::kArrayLen' % namespace_name

    table += '];'
    return table


def get_shader_table_cpp(shader_and_variation):
    shader_file = shader_and_variation.shader_file
    enums = shader_and_variation.enums
    flags_bits = shader_and_variation.flags_bits
    enum_bits = shader_and_variation.enum_bits
    array_len = shader_and_variation.array_len

    # Cache max and mask value of each enum to quickly know when a possible variation is invalid
    enum_maxes = []
    enum_masks = []
    current_bit_start = flags_bits

    for e in range(len(enums)):
        enum_values = enums[e][1]
        enum_maxes.append((len(enum_values) - 1) << current_bit_start)
        enum_masks.append(((1 << enum_bits[e]) - 1) << current_bit_start)
        current_bit_start += enum_bits[e]

    table_name = get_variation_table_name(shader_file)
    var_name = get_var_name(os.path.basename(shader_file))

    table = 'constexpr CompressedShaderBlob %s[] = {\n' % table_name

    for variation in range(array_len):
        # if any variation is invalid, output an empty entry
        if any([(variation & enum_masks[e]) > enum_maxes[e] for e in range(len(enums))]):
            table += '{nullptr, 0}, // 0x%08X\n' % variation
        else:
            entry = '%s_%08X' % (var_name, variation)
            table += '{%s, sizeof(%s)},\n' % (entry, entry)

    table += '};'
    return table


def get_get_function_h(shader_and_variation):
    shader_file = shader_and_variation.shader_file

    function_name = get_var_name(os.path.basename(shader_file), 'get')

    definition = 'angle::Result %s' % function_name
    definition += '(Context *context, uint32_t shaderFlags, RefCounted<ShaderAndSerial> **shaderOut);'

    return definition


def get_get_function_cpp(shader_and_variation):
    shader_file = shader_and_variation.shader_file
    enums = shader_and_variation.enums

    function_name = get_var_name(os.path.basename(shader_file), 'get')
    namespace_name = "InternalShader::" + get_namespace_name(shader_file)
    member_table_name = get_variation_table_name(shader_file, 'm')
    constant_table_name = get_variation_table_name(shader_file)

    definition = 'angle::Result ShaderLibrary::%s' % function_name
    definition += '(Context *context, uint32_t shaderFlags, RefCounted<ShaderAndSerial> **shaderOut)\n{\n'
    definition += 'return GetShader(context, %s, %s, ArraySize(%s), shaderFlags, shaderOut);\n}\n' % (
        member_table_name, constant_table_name, constant_table_name)

    return definition


def get_destroy_call(shader_and_variation):
    shader_file = shader_and_variation.shader_file

    table_name = get_variation_table_name(shader_file, 'm')

    destroy = 'for (RefCounted<ShaderAndSerial> &shader : %s)\n' % table_name
    destroy += '{\nshader.get().destroy(device);\n}'
    return destroy


def shader_path(shader):
    return '"%s"' % slash(shader)


def main():
    # STEP 0: Handle inputs/outputs for run_code_generation.py's auto_script
    shaders_dir = os.path.join('shaders', 'src')
    if not os.path.isdir(shaders_dir):
        raise Exception("Could not find shaders directory")

    print_inputs = len(sys.argv) == 2 and sys.argv[1] == 'inputs'
    print_outputs = len(sys.argv) == 2 and sys.argv[1] == 'outputs'
    # If an argument X is given that's not inputs or outputs, compile shaders that match *X*.
    # This is useful in development to build only the shader of interest.
    shader_files_to_compile = os.listdir(shaders_dir)
    if not (print_inputs or print_outputs or len(sys.argv) < 2):
        shader_files_to_compile = [f for f in shader_files_to_compile if f.find(sys.argv[1]) != -1]

    valid_extensions = ['.vert', '.frag', '.comp']
    input_shaders = sorted([
        os.path.join(shaders_dir, shader)
        for shader in os.listdir(shaders_dir)
        if any([os.path.splitext(shader)[1] == ext for ext in valid_extensions])
    ])
    if print_inputs:
        glslang_binaries = [get_linux_glslang_exe_path(), get_win_glslang_exe_path()]
        glslang_binary_hashes = [path + '.sha1' for path in glslang_binaries]
        input_shaders_variations = [get_variations_path(shader) for shader in input_shaders]
        input_shaders_variations = [
            variations for variations in input_shaders_variations if variations is not None
        ]
        print(",".join(input_shaders + input_shaders_variations + glslang_binary_hashes))
        return 0

    # STEP 1: Call glslang to generate the internal shaders into small .inc files.
    # Iterates over the shaders and call glslang with the right arguments.

    glslang_path = None
    if not print_outputs:
        glslang_path = get_glslang_exe_path()

    output_shaders = []

    input_shaders_and_variations = [
        ShaderAndVariations(shader_file) for shader_file in input_shaders
    ]

    compile_queue = CompileQueue()

    for shader_and_variation in input_shaders_and_variations:
        shader_file = shader_and_variation.shader_file
        flags = shader_and_variation.flags
        enums = shader_and_variation.enums
        flags_bits = shader_and_variation.flags_bits
        enum_bits = shader_and_variation.enum_bits

        # an array where each element i is in [0, len(enums[i])),
        # telling which enum is currently selected
        enum_indices = [0] * len(enums)

        output_name = os.path.basename(shader_file)

        while True:
            do_compile = not print_outputs and output_name in shader_files_to_compile
            # a number where each bit says whether a flag is active or not,
            # with values in [0, 2^len(flags))
            for flags_active in range(1 << len(flags)):
                compile_variation(glslang_path if do_compile else None, compile_queue, shader_file,
                                  output_name, flags, enums, flags_active, enum_indices,
                                  flags_bits, enum_bits, output_shaders)

            if not next_enum_variation(enums, enum_indices):
                break

    output_shaders = sorted(output_shaders)
    outputs = output_shaders + [out_file_cpp, out_file_h]

    if print_outputs:
        print(','.join(outputs))
        return 0

    compile_queue.finish()

    # STEP 2: Consolidate the .inc files into an auto-generated cpp/h library.
    with open(out_file_cpp, 'w') as outfile:
        includes = "\n".join([gen_shader_include(shader) for shader in output_shaders])
        shader_tables_cpp = '\n'.join(
            [get_shader_table_cpp(s) for s in input_shaders_and_variations])
        shader_destroy_calls = '\n'.join(
            [get_destroy_call(s) for s in input_shaders_and_variations])
        shader_get_functions_cpp = '\n'.join(
            [get_get_function_cpp(s) for s in input_shaders_and_variations])

        outcode = template_shader_library_cpp.format(
            script_name=__file__,
            copyright_year=date.today().year,
            out_file_name=out_file_cpp,
            input_file_name='shaders/src/*',
            internal_shader_includes=includes,
            shader_tables_cpp=shader_tables_cpp,
            shader_destroy_calls=shader_destroy_calls,
            shader_get_functions_cpp=shader_get_functions_cpp)
        outfile.write(outcode)
        outfile.close()

    with open(out_file_h, 'w') as outfile:
        shader_variation_definitions = '\n'.join(
            [get_variation_definition(s) for s in input_shaders_and_variations])
        shader_get_functions_h = '\n'.join(
            [get_get_function_h(s) for s in input_shaders_and_variations])
        shader_tables_h = '\n'.join([get_shader_table_h(s) for s in input_shaders_and_variations])
        outcode = template_shader_library_h.format(
            script_name=__file__,
            copyright_year=date.today().year,
            out_file_name=out_file_h,
            input_file_name='shaders/src/*',
            shader_variation_definitions=shader_variation_definitions,
            shader_get_functions_h=shader_get_functions_h,
            shader_tables_h=shader_tables_h)
        outfile.write(outcode)
        outfile.close()

    # STEP 3: Create a gni file with the generated files.
    with io.open(out_file_gni, 'w', newline='\n') as outfile:
        outcode = template_shader_includes_gni.format(
            script_name=__file__,
            copyright_year=date.today().year,
            out_file_name=out_file_gni,
            input_file_name='shaders/src/*',
            shaders_list=',\n'.join([shader_path(shader) for shader in output_shaders]))
        outfile.write(outcode)
        outfile.close()

    return 0


if __name__ == '__main__':
    sys.exit(main())
