Generate the SPIR-V shaders automatically at build time (#2200)

Add custom commands and targets to automatically assemble and validate
the SPIR-V shaders used by the test.

Automatic assembly depends on finding `python3`, `spirv-as` and
`spirv-val`. `SPIRV_TOOLS_DIR` can be defined by the user during
configuration to provide an override path. Default behaviour assumes
that the binaries exist in `PATH`.

---------

Signed-off-by: Ahmed Hesham <ahmed.hesham@arm.com>
This commit is contained in:
Ahmed Hesham
2025-02-11 16:43:37 +00:00
committed by GitHub
parent a8b32b2720
commit ecd012737f
4 changed files with 507 additions and 2 deletions

View File

@@ -0,0 +1,502 @@
set(SPRIV_TOOLS_DIR ""
CACHE
PATH
"Absolute path to the directory containing the SPIR-V tools to use")
find_package(Python3 COMPONENTS Interpreter QUIET)
find_program(SPIRV_ASSEMBLER
NAMES spirv-as
HINTS ${SPIRV_TOOLS_DIR})
find_program(SPIRV_VALIDATOR
NAMES spirv-val
HINTS ${SPIRV_TOOLS_DIR})
if (Python3_FOUND AND
NOT ${SPIRV_ASSEMBLER} STREQUAL "SPIRV_ASSEMBLER-NOTFOUND" AND
NOT ${SPIRV_VALIDATOR} STREQUAL "SPIRV_VALIDATOR-NOTFOUND")
message(STATUS "Using python3: ${Python3_EXECUTABLE}")
message(STATUS "Using spirv-as: ${SPIRV_ASSEMBLER}")
message(STATUS "Using spirv-val: ${SPIRV_VALIDATOR}")
else()
message(STATUS "Skipping automatic build of SPIR-V files for spirv_new")
# Empty custom target
add_custom_target(spirv_new_binaries)
return()
endif()
set(spirv_sources
assume.spvasm32
assume.spvasm64
atomic_dec_global.spvasm32
atomic_dec_global.spvasm64
atomic_inc_global.spvasm32
atomic_inc_global.spvasm64
basic.spvasm32
basic.spvasm64
branch_conditional.spvasm32
branch_conditional.spvasm64
branch_conditional_weighted.spvasm32
branch_conditional_weighted.spvasm64
branch_simple.spvasm32
branch_simple.spvasm64
composite_construct_int4.spvasm32
composite_construct_int4.spvasm64
composite_construct_struct.spvasm32
composite_construct_struct.spvasm64
constant_char_simple.spvasm32
constant_char_simple.spvasm64
constant_double_simple.spvasm32
constant_double_simple.spvasm64
constant_false_simple.spvasm32
constant_false_simple.spvasm64
constant_float_simple.spvasm32
constant_float_simple.spvasm64
constant_half_simple.spvasm32
constant_half_simple.spvasm64
constant_int3_simple.spvasm32
constant_int3_simple.spvasm64
constant_int4_simple.spvasm32
constant_int4_simple.spvasm64
constant_int_simple.spvasm32
constant_int_simple.spvasm64
constant_long_simple.spvasm32
constant_long_simple.spvasm64
constant_short_simple.spvasm32
constant_short_simple.spvasm64
constant_struct_int_char_simple.spvasm32
constant_struct_int_char_simple.spvasm64
constant_struct_int_float_simple.spvasm32
constant_struct_int_float_simple.spvasm64
constant_struct_struct_simple.spvasm32
constant_struct_struct_simple.spvasm64
constant_true_simple.spvasm32
constant_true_simple.spvasm64
constant_uchar_simple.spvasm32
constant_uchar_simple.spvasm64
constant_uint_simple.spvasm32
constant_uint_simple.spvasm64
constant_ulong_simple.spvasm32
constant_ulong_simple.spvasm64
constant_ushort_simple.spvasm32
constant_ushort_simple.spvasm64
copy_char_simple.spvasm32
copy_char_simple.spvasm64
copy_double_simple.spvasm32
copy_double_simple.spvasm64
copy_float_simple.spvasm32
copy_float_simple.spvasm64
copy_half_simple.spvasm32
copy_half_simple.spvasm64
copy_int3_simple.spvasm32
copy_int3_simple.spvasm64
copy_int4_simple.spvasm32
copy_int4_simple.spvasm64
copy_int_simple.spvasm32
copy_int_simple.spvasm64
copy_long_simple.spvasm32
copy_long_simple.spvasm64
copy_short_simple.spvasm32
copy_short_simple.spvasm64
copy_struct_int_char_simple.spvasm32
copy_struct_int_char_simple.spvasm64
copy_struct_int_float_simple.spvasm32
copy_struct_int_float_simple.spvasm64
copy_struct_struct_simple.spvasm32
copy_struct_struct_simple.spvasm64
copy_uchar_simple.spvasm32
copy_uchar_simple.spvasm64
copy_uint_simple.spvasm32
copy_uint_simple.spvasm64
copy_ulong_simple.spvasm32
copy_ulong_simple.spvasm64
copy_ushort_simple.spvasm32
copy_ushort_simple.spvasm64
decorate_aliased.spvasm32
decorate_aliased.spvasm64
decorate_alignment.spvasm32
decorate_alignment.spvasm64
decorate_constant.spvasm32
decorate_constant.spvasm64
decorate_constant_fail.spvasm32
decorate_constant_fail.spvasm64
decorate_cpacked.spvasm32
decorate_cpacked.spvasm64
decorate_restrict.spvasm32
decorate_restrict.spvasm64
decorate_rounding_rte_double_long.spvasm32
decorate_rounding_rte_double_long.spvasm64
decorate_rounding_rte_float_int.spvasm32
decorate_rounding_rte_float_int.spvasm64
decorate_rounding_rte_half_short.spvasm32
decorate_rounding_rte_half_short.spvasm64
decorate_rounding_rtn_double_long.spvasm32
decorate_rounding_rtn_double_long.spvasm64
decorate_rounding_rtn_float_int.spvasm32
decorate_rounding_rtn_float_int.spvasm64
decorate_rounding_rtn_half_short.spvasm32
decorate_rounding_rtn_half_short.spvasm64
decorate_rounding_rtp_double_long.spvasm32
decorate_rounding_rtp_double_long.spvasm64
decorate_rounding_rtp_float_int.spvasm32
decorate_rounding_rtp_float_int.spvasm64
decorate_rounding_rtp_half_short.spvasm32
decorate_rounding_rtp_half_short.spvasm64
decorate_rounding_rtz_double_long.spvasm32
decorate_rounding_rtz_double_long.spvasm64
decorate_rounding_rtz_float_int.spvasm32
decorate_rounding_rtz_float_int.spvasm64
decorate_rounding_rtz_half_short.spvasm32
decorate_rounding_rtz_half_short.spvasm64
decorate_saturated_conversion_double_to_int.spvasm32
decorate_saturated_conversion_double_to_int.spvasm64
decorate_saturated_conversion_double_to_uint.spvasm32
decorate_saturated_conversion_double_to_uint.spvasm64
decorate_saturated_conversion_float_to_char.spvasm32
decorate_saturated_conversion_float_to_char.spvasm64
decorate_saturated_conversion_float_to_short.spvasm32
decorate_saturated_conversion_float_to_short.spvasm64
decorate_saturated_conversion_float_to_uchar.spvasm32
decorate_saturated_conversion_float_to_uchar.spvasm64
decorate_saturated_conversion_float_to_ushort.spvasm32
decorate_saturated_conversion_float_to_ushort.spvasm64
decorate_saturated_conversion_half_to_char.spvasm32
decorate_saturated_conversion_half_to_char.spvasm64
decorate_saturated_conversion_half_to_uchar.spvasm32
decorate_saturated_conversion_half_to_uchar.spvasm64
expect_bool.spvasm32
expect_bool.spvasm64
expect_char.spvasm32
expect_char.spvasm64
expect_int.spvasm32
expect_int.spvasm64
expect_long.spvasm32
expect_long.spvasm64
expect_short.spvasm32
expect_short.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fadd_int.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fadd_int.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fadd_uint.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fadd_uint.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fmul_int.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fmul_int.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fmul_uint.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fmul_uint.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fnegate_int.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fnegate_int.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fshiftleft_int.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fshiftleft_int.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fshiftleft_uint.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fshiftleft_uint.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fsub_int.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fsub_int.spvasm64
ext_cl_khr_spirv_no_integer_wrap_decoration_fsub_uint.spvasm32
ext_cl_khr_spirv_no_integer_wrap_decoration_fsub_uint.spvasm64
fadd_double.spvasm32
fadd_double.spvasm64
fadd_double2.spvasm32
fadd_double2.spvasm64
fadd_float.spvasm32
fadd_float.spvasm64
fadd_float4.spvasm32
fadd_float4.spvasm64
fadd_half.spvasm32
fadd_half.spvasm64
fdiv_double.spvasm32
fdiv_double.spvasm64
fdiv_double2.spvasm32
fdiv_double2.spvasm64
fdiv_float.spvasm32
fdiv_float.spvasm64
fdiv_float4.spvasm32
fdiv_float4.spvasm64
fdiv_half.spvasm32
fdiv_half.spvasm64
fmod_double.spvasm32
fmod_double.spvasm64
fmod_double2.spvasm32
fmod_double2.spvasm64
fmod_float.spvasm32
fmod_float.spvasm64
fmod_float4.spvasm32
fmod_float4.spvasm64
fmod_half.spvasm32
fmod_half.spvasm64
fmul_double.spvasm32
fmul_double.spvasm64
fmul_double2.spvasm32
fmul_double2.spvasm64
fmul_float.spvasm32
fmul_float.spvasm64
fmul_float4.spvasm32
fmul_float4.spvasm64
fmul_half.spvasm32
fmul_half.spvasm64
frem_double.spvasm32
frem_double.spvasm64
frem_double2.spvasm32
frem_double2.spvasm64
frem_float.spvasm32
frem_float.spvasm64
frem_float4.spvasm32
frem_float4.spvasm64
frem_half.spvasm32
frem_half.spvasm64
fsub_double.spvasm32
fsub_double.spvasm64
fsub_double2.spvasm32
fsub_double2.spvasm64
fsub_float.spvasm32
fsub_float.spvasm64
fsub_float4.spvasm32
fsub_float4.spvasm64
fsub_half.spvasm32
fsub_half.spvasm64
label_simple.spvasm32
label_simple.spvasm64
lifetime_simple.spvasm32
lifetime_simple.spvasm64
linkage_export.spvasm32
linkage_export.spvasm64
linkage_import.spvasm32
linkage_import.spvasm64
linkage_linkonce_odr_main.spvasm32
linkage_linkonce_odr_main.spvasm64
linkage_linkonce_odr_noa_main.spvasm32
linkage_linkonce_odr_noa_main.spvasm64
linkage_linkonce_odr_obj.spvasm32
linkage_linkonce_odr_obj.spvasm64
loop_merge_branch_conditional_dont_unroll.spvasm32
loop_merge_branch_conditional_dont_unroll.spvasm64
loop_merge_branch_conditional_none.spvasm32
loop_merge_branch_conditional_none.spvasm64
loop_merge_branch_conditional_unroll.spvasm32
loop_merge_branch_conditional_unroll.spvasm64
loop_merge_branch_dont_unroll.spvasm32
loop_merge_branch_dont_unroll.spvasm64
loop_merge_branch_none.spvasm32
loop_merge_branch_none.spvasm64
loop_merge_branch_unroll.spvasm32
loop_merge_branch_unroll.spvasm64
op_function_const.spvasm32
op_function_const.spvasm64
op_function_inline.spvasm32
op_function_inline.spvasm64
op_function_noinline.spvasm32
op_function_noinline.spvasm64
op_function_none.spvasm32
op_function_none.spvasm64
op_function_pure.spvasm32
op_function_pure.spvasm64
op_function_pure_ptr.spvasm32
op_function_pure_ptr.spvasm64
op_neg_double.spvasm32
op_neg_double.spvasm64
op_neg_float.spvasm32
op_neg_float.spvasm64
op_neg_float4.spvasm32
op_neg_float4.spvasm64
op_neg_half.spvasm32
op_neg_half.spvasm64
op_neg_int.spvasm32
op_neg_int.spvasm64
op_neg_int4.spvasm32
op_neg_int4.spvasm64
op_neg_long.spvasm32
op_neg_long.spvasm64
op_neg_short.spvasm32
op_neg_short.spvasm64
op_not_int.spvasm32
op_not_int.spvasm64
op_not_int4.spvasm32
op_not_int4.spvasm64
op_not_long.spvasm32
op_not_long.spvasm64
op_not_short.spvasm32
op_not_short.spvasm64
op_spec_constant_double_simple.spvasm32
op_spec_constant_double_simple.spvasm64
op_spec_constant_false_simple.spvasm32
op_spec_constant_false_simple.spvasm64
op_spec_constant_float_simple.spvasm32
op_spec_constant_float_simple.spvasm64
op_spec_constant_half_simple.spvasm32
op_spec_constant_half_simple.spvasm64
op_spec_constant_true_simple.spvasm32
op_spec_constant_true_simple.spvasm64
op_spec_constant_uchar_simple.spvasm32
op_spec_constant_uchar_simple.spvasm64
op_spec_constant_uint_simple.spvasm32
op_spec_constant_uint_simple.spvasm64
op_spec_constant_ulong_simple.spvasm32
op_spec_constant_ulong_simple.spvasm64
op_spec_constant_ushort_simple.spvasm32
op_spec_constant_ushort_simple.spvasm64
opaque.spvasm32
opaque.spvasm64
phi_2.spvasm32
phi_2.spvasm64
phi_3.spvasm32
phi_3.spvasm64
phi_4.spvasm32
phi_4.spvasm64
select_if_dont_flatten.spvasm32
select_if_dont_flatten.spvasm64
select_if_flatten.spvasm32
select_if_flatten.spvasm64
select_if_none.spvasm32
select_if_none.spvasm64
select_switch_dont_flatten.spvasm32
select_switch_dont_flatten.spvasm64
select_switch_flatten.spvasm32
select_switch_flatten.spvasm64
select_switch_none.spvasm32
select_switch_none.spvasm64
spv1.1/basic.spvasm32
spv1.1/basic.spvasm64
spv1.2/basic.spvasm32
spv1.2/basic.spvasm64
spv1.3/basic.spvasm32
spv1.3/basic.spvasm64
spv1.4/basic.spvasm32
spv1.4/basic.spvasm64
spv1.4/copylogical_struct.spvasm32
spv1.4/copylogical_struct.spvasm64
spv1.4/copymemory_memory_operands.spvasm32
spv1.4/copymemory_memory_operands.spvasm64
spv1.4/image_operand_signextend.spvasm32
spv1.4/image_operand_signextend.spvasm64
spv1.4/image_operand_zeroextend.spvasm32
spv1.4/image_operand_zeroextend.spvasm64
spv1.4/loop_control_iterationmultiple.spvasm32
spv1.4/loop_control_iterationmultiple.spvasm64
spv1.4/loop_control_maxiterations.spvasm32
spv1.4/loop_control_maxiterations.spvasm64
spv1.4/loop_control_miniterations.spvasm32
spv1.4/loop_control_miniterations.spvasm64
spv1.4/loop_control_partialcount.spvasm32
spv1.4/loop_control_partialcount.spvasm64
spv1.4/loop_control_peelcount.spvasm32
spv1.4/loop_control_peelcount.spvasm64
spv1.4/no_integer_wrap_decoration_fadd_int.spvasm32
spv1.4/no_integer_wrap_decoration_fadd_int.spvasm64
spv1.4/no_integer_wrap_decoration_fadd_uint.spvasm32
spv1.4/no_integer_wrap_decoration_fadd_uint.spvasm64
spv1.4/no_integer_wrap_decoration_fmul_int.spvasm32
spv1.4/no_integer_wrap_decoration_fmul_int.spvasm64
spv1.4/no_integer_wrap_decoration_fmul_uint.spvasm32
spv1.4/no_integer_wrap_decoration_fmul_uint.spvasm64
spv1.4/no_integer_wrap_decoration_fnegate_int.spvasm32
spv1.4/no_integer_wrap_decoration_fnegate_int.spvasm64
spv1.4/no_integer_wrap_decoration_fshiftleft_int.spvasm32
spv1.4/no_integer_wrap_decoration_fshiftleft_int.spvasm64
spv1.4/no_integer_wrap_decoration_fshiftleft_uint.spvasm32
spv1.4/no_integer_wrap_decoration_fshiftleft_uint.spvasm64
spv1.4/no_integer_wrap_decoration_fsub_int.spvasm32
spv1.4/no_integer_wrap_decoration_fsub_int.spvasm64
spv1.4/no_integer_wrap_decoration_fsub_uint.spvasm32
spv1.4/no_integer_wrap_decoration_fsub_uint.spvasm64
spv1.4/nonwriteable_decoration_function_storage_class.spvasm32
spv1.4/nonwriteable_decoration_function_storage_class.spvasm64
spv1.4/ptrops.spvasm32
spv1.4/ptrops.spvasm64
spv1.4/select_struct.spvasm32
spv1.4/select_struct.spvasm64
spv1.4/usersemantic_decoratestring.spvasm32
spv1.4/usersemantic_decoratestring.spvasm64
spv1.4/usersemantic_memberdecoratestring.spvasm32
spv1.4/usersemantic_memberdecoratestring.spvasm64
spv1.5/basic.spvasm32
spv1.5/basic.spvasm64
spv1.6/basic.spvasm32
spv1.6/basic.spvasm64
undef_char_simple.spvasm32
undef_char_simple.spvasm64
undef_double_simple.spvasm32
undef_double_simple.spvasm64
undef_false_simple.spvasm32
undef_false_simple.spvasm64
undef_float_simple.spvasm32
undef_float_simple.spvasm64
undef_half_simple.spvasm32
undef_half_simple.spvasm64
undef_int3_simple.spvasm32
undef_int3_simple.spvasm64
undef_int4_simple.spvasm32
undef_int4_simple.spvasm64
undef_int_simple.spvasm32
undef_int_simple.spvasm64
undef_long_simple.spvasm32
undef_long_simple.spvasm64
undef_short_simple.spvasm32
undef_short_simple.spvasm64
undef_struct_int_char_simple.spvasm32
undef_struct_int_char_simple.spvasm64
undef_struct_int_float_simple.spvasm32
undef_struct_int_float_simple.spvasm64
undef_struct_struct_simple.spvasm32
undef_struct_struct_simple.spvasm64
undef_true_simple.spvasm32
undef_true_simple.spvasm64
undef_uchar_simple.spvasm32
undef_uchar_simple.spvasm64
undef_uint_simple.spvasm32
undef_uint_simple.spvasm64
undef_ulong_simple.spvasm32
undef_ulong_simple.spvasm64
undef_ushort_simple.spvasm32
undef_ushort_simple.spvasm64
unreachable_simple.spvasm32
unreachable_simple.spvasm64
vector_char16_extract.spvasm32
vector_char16_extract.spvasm64
vector_char16_insert.spvasm32
vector_char16_insert.spvasm64
vector_double2_extract.spvasm32
vector_double2_extract.spvasm64
vector_double2_insert.spvasm32
vector_double2_insert.spvasm64
vector_float4_extract.spvasm32
vector_float4_extract.spvasm64
vector_float4_insert.spvasm32
vector_float4_insert.spvasm64
vector_half8_extract.spvasm32
vector_half8_extract.spvasm64
vector_half8_insert.spvasm32
vector_half8_insert.spvasm64
vector_int4_extract.spvasm32
vector_int4_extract.spvasm64
vector_int4_insert.spvasm32
vector_int4_insert.spvasm64
vector_long2_extract.spvasm32
vector_long2_extract.spvasm64
vector_long2_insert.spvasm32
vector_long2_insert.spvasm64
vector_times_scalar_double.spvasm32
vector_times_scalar_double.spvasm64
vector_times_scalar_float.spvasm32
vector_times_scalar_float.spvasm64
vector_times_scalar_half.spvasm32
vector_times_scalar_half.spvasm64)
set(assembled_spirv_binaries "")
foreach(spirv_source ${spirv_sources})
string(REPLACE ".spvasm" ".spv" assembled_spirv_binary ${spirv_source})
set(assembled_spirv_binary "${CMAKE_CURRENT_BINARY_DIR}/../spirv_bin/${assembled_spirv_binary}")
list(APPEND assembled_spirv_binaries ${assembled_spirv_binary})
endforeach()
add_custom_command(
OUTPUT ${assembled_spirv_binaries}
COMMENT "Generating SPIR-V binaries..."
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/assemble_spirv.py
--source-dir "${CMAKE_CURRENT_SOURCE_DIR}"
--output-dir "${CMAKE_CURRENT_BINARY_DIR}/../spirv_bin"
--assembler "${SPIRV_ASSEMBLER}"
--validator "${SPIRV_VALIDATOR}"
DEPENDS assemble_spirv.py ${spirv_sources}
USES_TERMINAL
VERBATIM)
add_custom_target(spirv_new_binaries DEPENDS ${assembled_spirv_binaries})

View File

@@ -0,0 +1,180 @@
#!/usr/bin/env python3
#####################################################################
# Copyright (c) 2020-2023 The Khronos Group Inc. All Rights Reserved.
#
# 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.
#####################################################################
"""Assembles the SPIR-V assembly files used by spirv_new into binaries,
and validates them using spirv-val. Either run this from the parent
of the spirv_asm directory, or pass the --source-dir and --output-dir
options to specify the locations of the assembly files and the
binaries to be generated.
"""
import argparse
import glob
import os
import subprocess
import sys
from textwrap import wrap
# sub-directories for specific SPIR-V environments
spirv_envs = [
'', # all files in the root directory are considered SPIR-V 1.0
'spv1.1',
'spv1.2',
'spv1.3',
'spv1.4',
'spv1.5',
'spv1.6',
]
def fatal(message):
"""Print an error message and exit with a non-zero status, to
indicate failure.
"""
print(message)
sys.exit(1)
def assemble_spirv(asm_dir, bin_dir, spirv_as, spirv_env, verbose):
"""Assemble SPIR-V source into binaries."""
if not os.path.exists(bin_dir):
os.makedirs(bin_dir)
assembly_failures = False
for asm_file_path in glob.glob(os.path.join(asm_dir, '*.spvasm*')):
asm_file = os.path.basename(asm_file_path)
if os.path.isfile(asm_file_path):
if verbose:
print(' Assembling {}'.format(asm_file))
asm_file_root, asm_file_ext = os.path.splitext(asm_file)
bin_file = asm_file_root + asm_file_ext.replace('asm', '')
bin_file_path = os.path.join(bin_dir, bin_file)
command = '"{}" --target-env "{}" "{}" -o "{}"'.format(
spirv_as, spirv_env, asm_file_path, bin_file_path)
if subprocess.call(command, shell=True) != 0:
assembly_failures = True
print('ERROR: Failure assembling {}: '
'see above output.'.format(
asm_file))
print()
if assembly_failures:
fatal('\n'.join(wrap(
'ERROR: Assembly failure(s) occurred. See above for error '
'messages from the assembler, if any.')))
def validate_spirv(bin_dir, spirv_val, spirv_env, verbose):
"""Validates SPIR-V binaries. Ignores known failures."""
validation_failures = False
for bin_file_path in glob.glob(os.path.join(bin_dir, '*.spv*')):
bin_file = os.path.basename(bin_file_path)
if os.path.isfile(bin_file_path):
if verbose:
print(' Validating {}'.format(bin_file))
command = '"{}" --target-env "{}" "{}"'.format(
spirv_val, spirv_env, bin_file_path)
if subprocess.call(command, shell=True) != 0:
print('ERROR: Failure validating {}: '
'see above output.'.format(
bin_file))
validation_failures = True
print()
if validation_failures:
fatal('ERROR: Validation failure(s) found. '
'See above for validation output.')
def parse_args():
"""Parse the command-line arguments."""
argparse_kwargs = (
{'allow_abbrev': False} if sys.version_info >= (3, 5) else {})
argparse_kwargs['description'] = (
'''Assembles the SPIR-V assembly files used by spirv_new into
binaries, and validates them using spirv-val. Either run this
from the parent of the spirv_asm directory, or pass the
--source-dir and --output-dir options to specify the locations
the assembly files and the binaries to be generated.
''')
parser = argparse.ArgumentParser(**argparse_kwargs)
parser.add_argument('-s', '--source-dir', metavar='DIR',
default='spirv_asm',
help='''specifies the directory containing SPIR-V
assembly files''')
parser.add_argument('-o', '--output-dir', metavar='DIR',
default='spirv_bin',
help='''specifies the directory in which to
output SPIR-V binary files''')
parser.add_argument('-a', '--assembler', metavar='PROGRAM',
default='spirv-as',
help='''specifies the program to use for assembly
of SPIR-V, defaults to spirv-as''')
parser.add_argument('-l', '--validator', metavar='PROGRAM',
default='spirv-val',
help='''specifies the program to use for validation
of SPIR-V, defaults to spirv-val''')
parser.add_argument('-k', '--skip-validation', action='store_true',
default=False,
help='skips validation of the genareted SPIR-V')
parser.add_argument('-v', '--verbose', action='store_true', default=False,
help='''enable verbose output (i.e. prints the
name of each SPIR-V assembly file or
binary as it is assembled or validated)
''')
return parser.parse_args()
def main():
"""Main function. Assembles and validates SPIR-V."""
args = parse_args()
for subdir in spirv_envs:
src_dir = os.path.join(args.source_dir, subdir)
out_dir = os.path.join(args.output_dir, subdir)
spirv_env = 'spv1.0' if subdir == '' else subdir
print('Assembling SPIR-V source into binaries for target {}...'.
format(spirv_env))
assemble_spirv(src_dir, out_dir, args.assembler,
spirv_env, args.verbose)
print('Finished assembling SPIR-V binaries.')
print()
if args.skip_validation:
print('Skipping validation of SPIR-V binaries as requested.')
else:
print('Validating SPIR-V binaries for target {}...'.
format(spirv_env))
validate_spirv(out_dir, args.validator,
spirv_env, args.verbose)
print('All SPIR-V binaries validated successfully.')
print()
print('Done.')
if __name__ == '__main__':
main()