1617a3babSopenharmony_ci#!/bin/bash 2617a3babSopenharmony_ci 3617a3babSopenharmony_ci# This script validates shaders (if successfully compiled) using spirv-val. 4617a3babSopenharmony_ci# It is not meant to preclude the possible addition of the validator to 5617a3babSopenharmony_ci# glslang. 6617a3babSopenharmony_ci 7617a3babSopenharmony_cideclare -r EXE='../build/install/bin/glslang' 8617a3babSopenharmony_ci 9617a3babSopenharmony_ci# search common locations for spirv-tools: keep first one 10617a3babSopenharmony_cifor toolsdir in '../External/spirv-tools/build/tools' '../../SPIRV-Tools/build/tools/bin' '/usr/local/bin'; do 11617a3babSopenharmony_ci [[ -z "$VAL" && -x "${toolsdir}/spirv-val" ]] && declare -r VAL="${toolsdir}/spirv-val" 12617a3babSopenharmony_ci [[ -z "$DIS" && -x "${toolsdir}/spirv-dis" ]] && declare -r DIS="${toolsdir}/spirv-dis" 13617a3babSopenharmony_cidone 14617a3babSopenharmony_ci 15617a3babSopenharmony_cideclare -r gtests='../gtests/Hlsl.FromFile.cpp ../gtests/Spv.FromFile.cpp' 16617a3babSopenharmony_ci 17617a3babSopenharmony_cideclare -r targetenv='vulkan1.0' 18617a3babSopenharmony_ci 19617a3babSopenharmony_cifunction fatal() { echo "ERROR: $@"; exit 5; } 20617a3babSopenharmony_ci 21617a3babSopenharmony_cifunction usage 22617a3babSopenharmony_ci{ 23617a3babSopenharmony_ci echo 24617a3babSopenharmony_ci echo "Usage: $(basename $0) [options...] shaders..." 25617a3babSopenharmony_ci echo 26617a3babSopenharmony_ci echo " Validates shaders (if successfully compiled) through spirv-val." 27617a3babSopenharmony_ci echo 28617a3babSopenharmony_ci echo "General options:" 29617a3babSopenharmony_ci echo " --help prints this text" 30617a3babSopenharmony_ci echo " --no-color disables output colorization" 31617a3babSopenharmony_ci echo " --dump-asm dumps all successfully compiled shader assemblies" 32617a3babSopenharmony_ci echo " --dump-val dumps all validation results" 33617a3babSopenharmony_ci echo " --dump-comp dumps all compilation logs" 34617a3babSopenharmony_ci echo "Spam reduction options:" 35617a3babSopenharmony_ci echo " --no-summary disables result summaries" 36617a3babSopenharmony_ci echo " --skip-ok do not print successful validations" 37617a3babSopenharmony_ci echo " --skip-comperr do not print compilation errors" 38617a3babSopenharmony_ci echo " --skip-valerr do not print validation errors" 39617a3babSopenharmony_ci echo " --quiet synonym for --skip-ok --skip-comperr --skip-valerr --no-summary" 40617a3babSopenharmony_ci echo " --terse print terse single line progress summary" 41617a3babSopenharmony_ci echo "Disassembly options:" 42617a3babSopenharmony_ci echo " --raw-id uses raw ids for disassembly" 43617a3babSopenharmony_ci echo 44617a3babSopenharmony_ci echo "Usage examples. Note most non-hlsl tests fail to compile for expected reasons." 45617a3babSopenharmony_ci echo " Exercise all hlsl.* files:" 46617a3babSopenharmony_ci echo " $(basename $0) hlsl.*" 47617a3babSopenharmony_ci echo " Exercise all hlsl.* files, tersely:" 48617a3babSopenharmony_ci echo " $(basename $0) --terse hlsl.*" 49617a3babSopenharmony_ci echo " Print validator output for myfile.frag:" 50617a3babSopenharmony_ci echo " $(basename $0) --quiet --dump-val myfile.frag" 51617a3babSopenharmony_ci echo " Exercise hlsl.* files, only printing validation errors:" 52617a3babSopenharmony_ci echo " $(basename $0) --skip-ok --skip-comperr hlsl.*" 53617a3babSopenharmony_ci 54617a3babSopenharmony_ci exit 5 55617a3babSopenharmony_ci} 56617a3babSopenharmony_ci 57617a3babSopenharmony_cifunction status() 58617a3babSopenharmony_ci{ 59617a3babSopenharmony_ci printf "%-40s: %b\n" "$1" "$2" 60617a3babSopenharmony_ci} 61617a3babSopenharmony_ci 62617a3babSopenharmony_ci# make sure we can find glslang 63617a3babSopenharmony_ci[[ -x "$EXE" ]] || fatal "Unable to locate $(basename "$EXE") executable" 64617a3babSopenharmony_ci[[ -x "$VAL" ]] || fatal "Unable to locate spirv-val executable" 65617a3babSopenharmony_ci[[ -x "$DIS" ]] || fatal "Unable to locate spirv-dis executable" 66617a3babSopenharmony_ci 67617a3babSopenharmony_cifor gtest in $gtests; do 68617a3babSopenharmony_ci [[ -r "$gtest" ]] || fatal "Unable to locate source file: $(basename $gtest)" 69617a3babSopenharmony_cidone 70617a3babSopenharmony_ci 71617a3babSopenharmony_ci# temp files 72617a3babSopenharmony_cideclare -r spvfile='out.spv' \ 73617a3babSopenharmony_ci complog='comp.out' \ 74617a3babSopenharmony_ci vallog='val.out' \ 75617a3babSopenharmony_ci dislog='dis.out' \ 76617a3babSopenharmony_ci 77617a3babSopenharmony_ci# options 78617a3babSopenharmony_cideclare opt_vallog=false \ 79617a3babSopenharmony_ci opt_complog=false \ 80617a3babSopenharmony_ci opt_dislog=false \ 81617a3babSopenharmony_ci opt_summary=true \ 82617a3babSopenharmony_ci opt_stat_comperr=true \ 83617a3babSopenharmony_ci opt_stat_ok=true \ 84617a3babSopenharmony_ci opt_stat_valerr=true \ 85617a3babSopenharmony_ci opt_color=true \ 86617a3babSopenharmony_ci opt_raw_id=false \ 87617a3babSopenharmony_ci opt_quiet=false \ 88617a3babSopenharmony_ci opt_terse=false 89617a3babSopenharmony_ci 90617a3babSopenharmony_ci# clean up on exit 91617a3babSopenharmony_citrap "rm -f ${spvfile} ${complog} ${vallog} ${dislog}" EXIT 92617a3babSopenharmony_ci 93617a3babSopenharmony_ci# Language guesser: there is no fixed mapping from filenames to language, 94617a3babSopenharmony_ci# so this examines the file and return one of: 95617a3babSopenharmony_ci# hlsl 96617a3babSopenharmony_ci# glsl 97617a3babSopenharmony_ci# bin 98617a3babSopenharmony_ci# unknown 99617a3babSopenharmony_ci# This is easier WRT future expansion than a big explicit list. 100617a3babSopenharmony_cifunction FindLanguage() 101617a3babSopenharmony_ci{ 102617a3babSopenharmony_ci local test="$1" 103617a3babSopenharmony_ci 104617a3babSopenharmony_ci # If it starts with hlsl, assume it's hlsl. 105617a3babSopenharmony_ci if [[ "$test" == *hlsl.* ]]; then 106617a3babSopenharmony_ci echo hlsl 107617a3babSopenharmony_ci return 108617a3babSopenharmony_ci fi 109617a3babSopenharmony_ci 110617a3babSopenharmony_ci if [[ "$test" == *.spv ]]; then 111617a3babSopenharmony_ci echo bin 112617a3babSopenharmony_ci return; 113617a3babSopenharmony_ci fi 114617a3babSopenharmony_ci 115617a3babSopenharmony_ci # If it doesn't start with spv., assume it's GLSL. 116617a3babSopenharmony_ci if [[ ! "$test" == spv.* && ! "$test" == remap.* ]]; then 117617a3babSopenharmony_ci echo glsl 118617a3babSopenharmony_ci return 119617a3babSopenharmony_ci fi 120617a3babSopenharmony_ci 121617a3babSopenharmony_ci # Otherwise, attempt to guess from shader contents, since there's no 122617a3babSopenharmony_ci # fixed mapping of filenames to languages. 123617a3babSopenharmony_ci local contents="$(cat "$test")" 124617a3babSopenharmony_ci 125617a3babSopenharmony_ci if [[ "$contents" == *#version* ]]; then 126617a3babSopenharmony_ci echo glsl 127617a3babSopenharmony_ci return 128617a3babSopenharmony_ci fi 129617a3babSopenharmony_ci 130617a3babSopenharmony_ci if [[ "$contents" == *SamplerState* || 131617a3babSopenharmony_ci "$contents" == *cbuffer* || 132617a3babSopenharmony_ci "$contents" == *SV_* ]]; then 133617a3babSopenharmony_ci echo hlsl 134617a3babSopenharmony_ci return 135617a3babSopenharmony_ci fi 136617a3babSopenharmony_ci 137617a3babSopenharmony_ci echo unknown 138617a3babSopenharmony_ci} 139617a3babSopenharmony_ci 140617a3babSopenharmony_ci# Attempt to discover entry point 141617a3babSopenharmony_cifunction FindEntryPoint() 142617a3babSopenharmony_ci{ 143617a3babSopenharmony_ci local test="$1" 144617a3babSopenharmony_ci 145617a3babSopenharmony_ci # if it's not hlsl, always use main 146617a3babSopenharmony_ci if [[ "$language" != 'hlsl' ]]; then 147617a3babSopenharmony_ci echo 'main' 148617a3babSopenharmony_ci return 149617a3babSopenharmony_ci fi 150617a3babSopenharmony_ci 151617a3babSopenharmony_ci # Try to find it in test sources 152617a3babSopenharmony_ci awk -F '[ (){",]+' -e "\$2 == \"${test}\" { print \$3; found=1; } END { if (found==0) print \"main\"; } " $gtests 153617a3babSopenharmony_ci} 154617a3babSopenharmony_ci 155617a3babSopenharmony_ci# command line options 156617a3babSopenharmony_ciwhile [ $# -gt 0 ] 157617a3babSopenharmony_cido 158617a3babSopenharmony_ci case "$1" in 159617a3babSopenharmony_ci # -c) glslang="$2"; shift 2;; 160617a3babSopenharmony_ci --help|-?) usage;; 161617a3babSopenharmony_ci --no-color) opt_color=false; shift;; 162617a3babSopenharmony_ci --no-summary) opt_summary=false; shift;; 163617a3babSopenharmony_ci --skip-ok) opt_stat_ok=false; shift;; 164617a3babSopenharmony_ci --skip-comperr) opt_stat_comperr=false; shift;; 165617a3babSopenharmony_ci --skip-valerr) opt_stat_valerr=false; shift;; 166617a3babSopenharmony_ci --dump-asm) opt_dislog=true; shift;; 167617a3babSopenharmony_ci --dump-val) opt_vallog=true; shift;; 168617a3babSopenharmony_ci --dump-comp) opt_complog=true; shift;; 169617a3babSopenharmony_ci --raw-id) opt_raw_id=true; shift;; 170617a3babSopenharmony_ci --quiet) opt_quiet=true; shift;; 171617a3babSopenharmony_ci --terse) opt_quiet=true 172617a3babSopenharmony_ci opt_terse=true 173617a3babSopenharmony_ci shift;; 174617a3babSopenharmony_ci --*) fatal "Unknown command line option: $1";; 175617a3babSopenharmony_ci *) break;; 176617a3babSopenharmony_ci esac 177617a3babSopenharmony_cidone 178617a3babSopenharmony_ci 179617a3babSopenharmony_ci# this is what quiet means 180617a3babSopenharmony_ciif $opt_quiet; then 181617a3babSopenharmony_ci opt_stat_ok=false 182617a3babSopenharmony_ci opt_stat_comperr=false 183617a3babSopenharmony_ci opt_stat_valerr=false 184617a3babSopenharmony_ci $opt_terse || opt_summary=false 185617a3babSopenharmony_cifi 186617a3babSopenharmony_ci 187617a3babSopenharmony_ciif $opt_color; then 188617a3babSopenharmony_ci declare -r white="\e[1;37m" cyan="\e[1;36m" red="\e[0;31m" no_color="\e[0m" 189617a3babSopenharmony_cielse 190617a3babSopenharmony_ci declare -r white="" cyan="" red="" no_color="" 191617a3babSopenharmony_cifi 192617a3babSopenharmony_ci 193617a3babSopenharmony_ci# stats 194617a3babSopenharmony_cideclare -i count_ok=0 count_err=0 count_nocomp=0 count_total=0 195617a3babSopenharmony_ci 196617a3babSopenharmony_cideclare -r dashsep='------------------------------------------------------------------------' 197617a3babSopenharmony_ci 198617a3babSopenharmony_citestfiles=(${@}) 199617a3babSopenharmony_ci# if no shaders given, look for everything in current directory 200617a3babSopenharmony_ci[[ ${#testfiles[*]} == 0 ]] && testfiles=(*.frag *.vert *.tesc *.tese *.geom *.comp) 201617a3babSopenharmony_ci 202617a3babSopenharmony_ci$opt_summary && printf "\nValidating: ${#testfiles[*]} shaders\n\n" 203617a3babSopenharmony_ci 204617a3babSopenharmony_ci# Loop through the shaders we were given, compiling them if we can. 205617a3babSopenharmony_cifor test in ${testfiles[*]} 206617a3babSopenharmony_cido 207617a3babSopenharmony_ci if [[ ! -r "$test" ]]; then 208617a3babSopenharmony_ci $opt_quiet || status "$test" "${red}FILE NOT FOUND${no_color}" 209617a3babSopenharmony_ci continue 210617a3babSopenharmony_ci fi 211617a3babSopenharmony_ci 212617a3babSopenharmony_ci ((++count_total)) 213617a3babSopenharmony_ci 214617a3babSopenharmony_ci $opt_terse && printf "\r[%-3d/%-3d : ${white}comperr=%-3d ${red}valerr=%-3d ${cyan}ok=%-3d${no_color}]" \ 215617a3babSopenharmony_ci ${count_total} ${#testfiles[*]} ${count_nocomp} ${count_err} ${count_ok} 216617a3babSopenharmony_ci 217617a3babSopenharmony_ci language="$(FindLanguage $test)" 218617a3babSopenharmony_ci entry="$(FindEntryPoint $test)" 219617a3babSopenharmony_ci langops='' 220617a3babSopenharmony_ci 221617a3babSopenharmony_ci case "$language" in 222617a3babSopenharmony_ci hlsl) langops='-D --hlsl-iomap --hlsl-offsets';; 223617a3babSopenharmony_ci glsl) ;; 224617a3babSopenharmony_ci bin) continue;; # skip binaries 225617a3babSopenharmony_ci *) $opt_quiet || status "$test" "${red}UNKNOWN LANGUAGE${no_color}"; continue;; 226617a3babSopenharmony_ci esac 227617a3babSopenharmony_ci 228617a3babSopenharmony_ci # compile the test file 229617a3babSopenharmony_ci if compout=$("$EXE" -e "$entry" $langops -V -o "$spvfile" "$test" 2>&1) 230617a3babSopenharmony_ci then 231617a3babSopenharmony_ci # successful compilation: validate 232617a3babSopenharmony_ci if valout=$("$VAL" --target-env ${targetenv} "$spvfile" 2>&1) 233617a3babSopenharmony_ci then 234617a3babSopenharmony_ci # validated OK 235617a3babSopenharmony_ci $opt_stat_ok && status "$test" "${cyan}OK${no_color}" 236617a3babSopenharmony_ci ((++count_ok)) 237617a3babSopenharmony_ci else 238617a3babSopenharmony_ci # validation failure 239617a3babSopenharmony_ci $opt_stat_valerr && status "$test" "${red}VAL ERROR${no_color}" 240617a3babSopenharmony_ci printf "%s\n%s:\n%s\n" "$dashsep" "$test" "$valout" >> "$vallog" 241617a3babSopenharmony_ci ((++count_err)) 242617a3babSopenharmony_ci fi 243617a3babSopenharmony_ci 244617a3babSopenharmony_ci if $opt_dislog; then 245617a3babSopenharmony_ci printf "%s\n%s:\n" "$dashsep" "$test" >> "$dislog" 246617a3babSopenharmony_ci $opt_raw_id && id_opt=--raw-id 247617a3babSopenharmony_ci "$DIS" ${id_opt} "$spvfile" >> "$dislog" 248617a3babSopenharmony_ci fi 249617a3babSopenharmony_ci else 250617a3babSopenharmony_ci # compile failure 251617a3babSopenharmony_ci $opt_stat_comperr && status "$test" "${white}COMP ERROR${no_color}" 252617a3babSopenharmony_ci printf "%s\n%s\n" "$dashsep" "$compout" >> "$complog" 253617a3babSopenharmony_ci ((++count_nocomp)) 254617a3babSopenharmony_ci fi 255617a3babSopenharmony_cidone 256617a3babSopenharmony_ci 257617a3babSopenharmony_ci$opt_terse && echo 258617a3babSopenharmony_ci 259617a3babSopenharmony_ci# summarize 260617a3babSopenharmony_ci$opt_summary && printf "\nSummary: ${white}${count_nocomp} compile errors${no_color}, ${red}${count_err} validation errors${no_color}, ${cyan}${count_ok} successes${no_color}\n" 261617a3babSopenharmony_ci 262617a3babSopenharmony_ci# dump logs 263617a3babSopenharmony_ci$opt_vallog && [[ -r $vallog ]] && cat "$vallog" 264617a3babSopenharmony_ci$opt_complog && [[ -r $complog ]] && cat "$complog" 265617a3babSopenharmony_ci$opt_dislog && [[ -r $dislog ]] && cat "$dislog" 266617a3babSopenharmony_ci 267617a3babSopenharmony_ci# exit code 268617a3babSopenharmony_ci[[ ${count_err} -gt 0 ]] && exit 1 269617a3babSopenharmony_ciexit 0 270