| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("../../../../gn/glsl_shader_rules.gni") |
| |
| _hotsort_dir = "${graphics_compute_dir}/hotsort" |
| |
| # |
| # Generates a "HotSort target", which contains a compiled compute kernel to |
| # perform sorting of 32-bit or 64-bit integers, highly optimized for a given |
| # GPU architecture. |
| # |
| # To use a hotsort target in your code, do the following: |
| # |
| # 1) Declare a hotsort_target(<target_name>) target in your BUILD.gn |
| # that sets the appropriate configuration parameters (see below). |
| # |
| # 2) Add <target_name> to your source file's GN target deps variable. |
| # |
| # 3) In your source file, #include "<target_name>/hs_target.h", a |
| # special auto-generated header that defines a single variable |
| # declared as: |
| # |
| # extern struct hotsort_vk_target const * const <target_name>; |
| # |
| # NOTE: This GN template ensures that anything that depends on this |
| # GN target will have the right include_dirs set to do so. |
| # |
| # 4) Pass the <target_name> address to hotsort_vk_create(). |
| # |
| # |
| # Variables: |
| # |
| # The following variable names are optional and used to select various |
| # configuration parameters sent to hotsort_gen. Their description comes from |
| # comments in the 'hotsort_gen' sources, but should be clarified in the future. |
| # |
| # vendor: vendor name. Used to pick the default configuration file from |
| # hotsort/platforms/vk/targets/configs/${vendor}/ |
| # type_dwords: number of 32-bit words per sort entry. |
| # warp_lanes: Number of independent ALU cores (CUDA lanes) per |
| # processing element (CUDA warp). |
| # thread_regs: Number of registers to use per thread (lane?). |
| # smem_min: Minimum amount of memory that can be allocated (??) |
| # smem_quantum: smem quantum amount (??) |
| # smem_bs: ?? |
| # smem_bc: ?? |
| # warps_per_group: Max warps in a workgroup/cta/thread block (??) |
| # warps_max: Max warps that can fit in a multiprocessor (??) |
| # warps_min: blocks using smem barriers must have at least this many warps. |
| # warps_mod: the number of warps necessary to load balance horizontal |
| # merging. |
| # thread_xtra: ?? |
| # merge_flip_lo: ?? |
| # merge_flip_hi: ?? |
| # merge_half_lo: ?? |
| # merge_half_hi: ?? |
| # merge_flip_warps: ?? |
| # merge_half_warps: ?? |
| # glsl_bindings: A string containing four comma-separated unsigned integers, |
| # related to GLSL in/out bindings (??) |
| # autotune: Set to true to enable auto-tuning of some parameters (??). |
| # |
| # The following variables are still supported for legacy reasons. |
| # |
| # hotsort_target_name: |
| # A name that conveys the configuration of the generated HotSort |
| # algorithm. If not provided, defaults to the short name of |
| # ${target_name}. |
| # |
| # hotsort_target_config_files: |
| # An optional list of additional configuration files, which will be added |
| # to the vendor-specific configuration file determined from the "vendor" |
| # variable (see below). |
| # |
| # hotsort_target_dump: |
| # Boolean, if true the generated GN target is a group that references a |
| # target binary produced by the host toolchain. Otherwise, a source set is |
| # produced on the current toolchain. |
| # |
| # hotsort_target_args: |
| # Extra arguments passed to the 'hotsort_gen' HotSort algorithm code |
| # generator. |
| # |
| template("hotsort_target") { |
| # Order of operations below: |
| # |
| # 1. Determine what compute shaders will be generated by the |
| # hotsort_gen executable. |
| # |
| # 2. Generate compute shaders and supporting files with the |
| # hotsort_gen executable. |
| # |
| # 3. Compile compute shaders to SPIR-V modules. |
| # |
| # 4. Optimize SPIR-V modules. |
| # |
| # 5. Remap SPIR-V modules. |
| # |
| # 6. Return the target as either: |
| # - a source set |
| # - a binary image produced by the host toolchain |
| # |
| |
| # NOTE: If $hotsort_target_name is provided, the generated HotSort target |
| # and its artifacts are output to the root of $target_gen_dir. Otherwise, |
| # the outputs are found in $target_gen_dir/$target_name. |
| # |
| if (defined(invoker.hotsort_target_name)) { |
| _hs_target_name = invoker.hotsort_target_name |
| _hs_output_dir = "${target_gen_dir}" |
| } else { |
| _hs_target_name = get_label_info(target_name, "name") |
| _hs_output_dir = "${target_gen_dir}/${_hs_target_name}" |
| } |
| |
| _hs_public_include_dirs = target_gen_dir |
| |
| # |
| # Either dump a binary or produce a source set |
| # |
| _hs_target_dump = |
| defined(invoker.hotsort_target_dump) && invoker.hotsort_target_dump |
| |
| # |
| # prefix target args with implicit args |
| # |
| _hs_target_gen_args = [ |
| # Select glsl platform (what hotsort_gen calls an 'arch'). |
| "-a", |
| "glsl", |
| |
| # hotsort_gen output directory. |
| "-o", |
| rebase_path(_hs_output_dir, root_build_dir), |
| ] |
| |
| # Generate the hotsort_gen command line arguments from our GN variables. |
| |
| _gen_args = [] |
| if (defined(invoker.type_dwords)) { |
| _gen_args += [ |
| "-t", |
| "${invoker.type_dwords}", |
| ] |
| } |
| if (defined(invoker.warp_lanes)) { |
| _gen_args += [ |
| "-w", |
| "${invoker.warp_lanes}", |
| ] |
| } |
| if (defined(invoker.thread_regs)) { |
| _gen_args += [ |
| "-r", |
| "${invoker.thread_regs}", |
| ] |
| } |
| if (defined(invoker.smem_min)) { |
| _gen_args += [ |
| "-g", |
| "${invoker.smem_min}", |
| ] |
| } |
| if (defined(invoker.smem_quantum)) { |
| _gen_args += [ |
| "-G", |
| "${invoker.smem_quantum}", |
| ] |
| } |
| if (defined(invoker.smem_bs)) { |
| _gen_args += [ |
| "-s", |
| "${invoker.smem_bs}", |
| ] |
| } |
| if (defined(invoker.smem_bc)) { |
| _gen_args += [ |
| "-S", |
| "${invoker.smem_bc}", |
| ] |
| } |
| if (defined(invoker.warps_per_group)) { |
| _gen_args += [ |
| "-b", |
| "${invoker.warps_per_group}", |
| ] |
| } |
| if (defined(invoker.warps_max)) { |
| _gen_args += [ |
| "-B", |
| "${invoker.warps_max}", |
| ] |
| } |
| if (defined(invoker.warps_min)) { |
| _gen_args += [ |
| "-m", |
| "${invoker.warps_min}", |
| ] |
| } |
| if (defined(invoker.warps_mod)) { |
| _gen_args += [ |
| "-M", |
| "${invoker.warps_mod}", |
| ] |
| } |
| if (defined(invoker.thread_xtra)) { |
| _gen_args += [ |
| "-x", |
| "${invoker.thread_xtra}", |
| ] |
| } |
| if (defined(invoker.merge_flip_lo)) { |
| _gen_args += [ |
| "-f", |
| "${invoker.merge_flip_lo}", |
| ] |
| } |
| if (defined(invoker.merge_flip_hi)) { |
| _gen_args += [ |
| "-F", |
| "${invoker.merge_flip_hi}", |
| ] |
| } |
| if (defined(invoker.merge_half_lo)) { |
| _gen_args += [ |
| "-c", |
| "${invoker.merge_half_lo}", |
| ] |
| } |
| if (defined(invoker.merge_half_hi)) { |
| _gen_args += [ |
| "-C", |
| "${invoker.merge_half_hi}", |
| ] |
| } |
| if (defined(invoker.merge_flip_warps)) { |
| _gen_args += [ |
| "-p", |
| "${invoker.merge_flip_warps}", |
| ] |
| } |
| if (defined(invoker.merge_half_warps)) { |
| _gen_args += [ |
| "-P", |
| "${invoker.merge_half_warps}", |
| ] |
| } |
| if (defined(invoker.glsl_bindings)) { |
| # NOTE: Parameter is a string |
| _gen_args += [ |
| "-L", |
| invoker.glsl_bindings, |
| ] |
| } |
| if (defined(invoker.autotune) && invoker.autotune) { |
| # NOTE: Parameter is a boolean |
| _gen_args += [ "-z" ] |
| } |
| |
| _hs_target_gen_args += _gen_args |
| |
| # Legacy support |
| if (defined(invoker.hotsort_target_args)) { |
| _hs_target_gen_args += invoker.hotsort_target_args |
| } |
| |
| # |
| # define generated sources, includes and deps |
| # |
| _hs_target_gen_includes_public = [ "${_hs_output_dir}/hs_target.h" ] |
| |
| _hs_target_gen_includes = |
| [ "${_hs_output_dir}/hs_config.h" ] + _hs_target_gen_includes_public |
| |
| _hs_target_gen_sources = [ "${_hs_output_dir}/" + _hs_target_name + ".c" ] |
| |
| _hs_target_gen_inlines = [ "${_hs_output_dir}/hs_modules.inl" ] |
| |
| # |
| # define source set sources |
| # |
| _hs_target_include_dirs = [ |
| _hs_output_dir, |
| "${_hotsort_dir}/platforms/vk/targets", |
| "${_hotsort_dir}/platforms/vk", |
| ] |
| |
| _hs_target_sources = |
| _hs_target_gen_includes + _hs_target_gen_sources + _hs_target_gen_inlines |
| |
| # |
| # generated compute shaders |
| # |
| _hs_comp_names = |
| exec_script("${_hotsort_dir}/platforms/vk/targets/hotsort_comp_names.py", |
| _hs_target_gen_args, |
| "list lines") |
| |
| _hs_comp_sources = |
| process_file_template(_hs_comp_names, |
| "${_hs_output_dir}/comp/{{source_file_part}}") |
| |
| # |
| # generate the .comp shaders |
| # |
| # Note that hs_modules.txt should match names returned by script |
| # |
| _gen_comp_target_name = "gen_comp_${_hs_target_name}" |
| compiled_action(_gen_comp_target_name) { |
| tool = "${_hotsort_dir}/hotsort_gen" |
| outputs = |
| _hs_comp_sources + _hs_target_gen_sources + _hs_target_gen_includes |
| args = [ |
| "-D", |
| _hs_target_name, |
| ] + _hs_target_gen_args |
| } |
| |
| # |
| # copy any configuration files to the target directory |
| # |
| _gen_config_dir = |
| "${_hotsort_dir}/platforms/vk/targets/configs/${invoker.vendor}" |
| _gen_config_files = [ "${_gen_config_dir}/hs_glsl_macros_config.h" ] |
| if (defined(invoker.hotsort_target_config_files)) { |
| _gen_config_files += invoker.hotsort_target_config_files |
| } |
| _gen_copy_target_name = "gen_copy_${_hs_target_name}" |
| copy(_gen_copy_target_name) { |
| sources = _gen_config_files |
| outputs = [ |
| "${_hs_output_dir}/{{source_file_part}}", |
| ] |
| } |
| |
| # |
| # compile the .comp shaders to SPIR-V modules |
| # |
| _gen_spv_target_name = "gen_spv_${_hs_target_name}" |
| graphics_compute_compile_glsl_shader_foreach(_gen_spv_target_name) { |
| # Ensure we only keep the .comp files as sources for this step. |
| set_sources_assignment_filter([ |
| "*.h", |
| "*.c", |
| ]) |
| sources = get_target_outputs(":${_gen_comp_target_name}") |
| inputs = [ "${_hotsort_dir}/platforms/vk/targets/hs_glsl_macros.h" ] + |
| _hs_target_gen_includes + |
| get_target_outputs(":${_gen_copy_target_name}") |
| output_dir = _hs_output_dir |
| args = [ |
| "--target-env", |
| "vulkan1.1", |
| ] |
| include_dirs = _hs_target_include_dirs |
| deps = [ |
| ":${_gen_comp_target_name}", |
| ":${_gen_copy_target_name}", |
| ] |
| } |
| |
| # |
| # dump the modules as uint32_t literals |
| # |
| _gen_modules_target_name = "gen_modules_${_hs_target_name}" |
| compiled_action(_gen_modules_target_name) { |
| tool = "${_hotsort_dir}/platforms/vk/targets:hotsort_modules_to_literals" |
| inputs = get_target_outputs(":${_gen_spv_target_name}") |
| outputs = _hs_target_gen_inlines |
| args = rebase_path(outputs, root_build_dir) + |
| rebase_path(inputs, root_build_dir) |
| deps = [ |
| ":${_gen_spv_target_name}", |
| ] |
| } |
| |
| # |
| # either dump a binary or return a source set |
| # |
| if (_hs_target_dump) { |
| # |
| # executable for dumping a binary image of target |
| # |
| _hs_target_dump_name = "hotsort_dump_" + invoker.hotsort_target_name |
| |
| executable(_hs_target_dump_name) { |
| defines = [ "HS_DUMP" ] |
| sources = _hs_target_gen_sources |
| include_dirs = _hs_target_include_dirs |
| deps = [ |
| "${_gen_comp_target_name}", |
| ] |
| } |
| |
| # |
| # dump a binary image of target |
| # |
| _gen_bin_target_name = "gen_bin_${_hs_target_name}" |
| compiled_action(_gen_bin_target_name) { |
| tool = ":$_hs_target_dump_name" |
| sources = _hs_target_sources |
| outputs = [ |
| "${_hs_output_dir}/hs_target.bin", |
| ] |
| args = rebase_path(outputs, root_build_dir) |
| public_deps = [ |
| ":$_hs_target_dump_name", |
| ] |
| } |
| |
| # |
| # dummy group invokes $host_toolchain |
| # |
| group(target_name) { |
| public_deps = [ |
| ":${_gen_bin_target_name}($host_toolchain)", |
| ] |
| } |
| } else { |
| # |
| # target is a source set |
| # |
| _config_name = "${target_name}_public_config" |
| config(_config_name) { |
| include_dirs = [ _hs_public_include_dirs ] |
| } |
| |
| source_set(target_name) { |
| public = [ |
| "${_hs_output_dir}/hs_target.h", |
| ] |
| sources = _hs_target_sources |
| include_dirs = _hs_target_include_dirs |
| public_configs = [ ":${_config_name}" ] |
| deps = [ |
| ":${_gen_comp_target_name}", |
| ":${_gen_modules_target_name}", |
| ":${_gen_spv_target_name}", |
| ] |
| } |
| } |
| } |