binding-dependencies.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. Copyright (c) Contributors to the Open 3D Engine Project.
  5. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  6. SPDX-License-Identifier: Apache-2.0 OR MIT
  7. """
  8. import sys
  9. import os
  10. sys.path.append("..")
  11. sys.path.append("../..")
  12. from clr import *
  13. import testfuncs
  14. def verifyBindingDependencies(thefile, compilerPath, silent):
  15. j, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--bindingdep"])
  16. if ok:
  17. predicates = []
  18. predicates.append(lambda: "MainPS" in j["Srg1"]["Srg1_SRGConstantBuffer"]["dependentFunctions"])
  19. predicates.append(lambda: "MainVS" in j["Srg1"]["Srg1_SRGConstantBuffer"]["dependentFunctions"])
  20. predicates.append(lambda: "m_meshDisplacement" in j["Srg1"]["Srg1_SRGConstantBuffer"]["participantConstants"])
  21. predicates.append(lambda: "MainPS" in j["Srg1"]["m_environmentMap"]["dependentFunctions"])
  22. predicates.append(lambda: "MainPS" in j["Srg1"]["m_extendedMaterials"]["dependentFunctions"])
  23. predicates.append(lambda: "MainVS" in j["Srg1"]["m_extendedMaterials"]["dependentFunctions"])
  24. predicates.append(lambda: "MainPS" in j["Srg1"]["m_materialConstants"]["dependentFunctions"])
  25. predicates.append(lambda: "MainPS" in j["Srg1"]["m_sampler1"]["dependentFunctions"])
  26. predicates.append(lambda: len(j["Srg1"]["m_sampler2"]["dependentFunctions"]) == 0)
  27. predicates.append(lambda: "MainVS" in j["Srg2"]["Srg2_SRGConstantBuffer"]["dependentFunctions"])
  28. predicates.append(lambda: "m_inverseTranspose" in j["Srg2"]["Srg2_SRGConstantBuffer"]["participantConstants"])
  29. predicates.append(lambda: "m_world" in j["Srg2"]["Srg2_SRGConstantBuffer"]["participantConstants"])
  30. predicates.append(lambda: "MainPS" in j["Srg2"]["m_IBLsampler"]["dependentFunctions"])
  31. predicates.append(lambda: "MainPS" in j["Srg2"]["m_diffuseIBL"]["dependentFunctions"])
  32. predicates.append(lambda: "over" not in j["Srg1"]["m_materialConstants"]["dependentFunctions"])
  33. if not silent: print (fg.CYAN+ style.BRIGHT+ "binding dependency analysis verification..."+ style.RESET_ALL)
  34. ok = testfuncs.verifyAllPredicates(predicates, j)
  35. return True if ok else False
  36. def verifyBindingDependencies_2(thefile, compilerPath, silent):
  37. symbols, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--bindingdep"])
  38. if ok:
  39. predicates = []
  40. # this test is mostly to verify that the analysis doesn't crash altogether.
  41. # this is a regression test, since we had a build where that shader crashed the --bindingdep build.
  42. predicates.append(lambda: "StandardPbr_ForwardPassPS" in symbols["MaterialSrg"]["MaterialSrg_SRGConstantBuffer"]["dependentFunctions"])
  43. if not silent: print (fg.CYAN+ style.BRIGHT+ "complex input program binding dep verification..."+ style.RESET_ALL)
  44. ok = testfuncs.verifyAllPredicates(predicates, symbols)
  45. if ok and not silent:
  46. print (style.BRIGHT+ "OK! "+ str(len(predicates))+ " verified."+ style.RESET_ALL)
  47. return 1 if ok else 0
  48. def verifyBindingDependencies_3(thefile, compilerPath, silent):
  49. symbols, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--bindingdep"])
  50. if ok:
  51. predicates = []
  52. # this is a regression test to make sure we can analyze fully the dependencies when we are in the
  53. # presence of variant options. because options have a fallback in one of the SRG.
  54. # and tracking the use of options to the fallback is its own code path
  55. # every increase of the degree of cyclomatic complexity mandates its own test.
  56. predicates.append(lambda: "MainPS" in symbols["TrianglePerInstanceSRG"]["TrianglePerInstanceSRG_SRGConstantBuffer"]["dependentFunctions"])
  57. predicates.append(lambda: "MainVS" in symbols["TrianglePerInstanceSRG"]["TrianglePerInstanceSRG_SRGConstantBuffer"]["dependentFunctions"])
  58. predicates.append(lambda: "m_objectMatrix" in symbols["TrianglePerInstanceSRG"]["TrianglePerInstanceSRG_SRGConstantBuffer"]["participantConstants"])
  59. predicates.append(lambda: "m_SHADER_VARIANT_KEY_NAME_" in symbols["TrianglePerInstanceSRG"]["TrianglePerInstanceSRG_SRGConstantBuffer"]["participantConstants"])
  60. if not silent: print (fg.CYAN+ style.BRIGHT+ "Program with variant fallback binding dep verification..."+ style.RESET_ALL)
  61. ok = testfuncs.verifyAllPredicates(predicates, symbols)
  62. if ok and not silent:
  63. print (style.BRIGHT+ "OK! "+ str(len(predicates))+ " verified."+ style.RESET_ALL)
  64. return 1 if ok else 0
  65. def verifyBindingDependencies_4(thefile, compilerPath, silent):
  66. symbols, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--bindingdep"])
  67. if ok:
  68. predicates = []
  69. # this is a regression test to make sure the compiler doesn't crash on variables
  70. # internal to functions but declared after an unnamed scope.
  71. predicates.append(lambda: "MainCS" in symbols["PassSrg"]["PassSrg_SRGConstantBuffer"]["dependentFunctions"])
  72. predicates.append(lambda: "MainCS" in symbols["PassSrg"]["m_lutTexture"]["dependentFunctions"])
  73. if not silent: print (fg.CYAN+ style.BRIGHT+ "Program with unnamed scopes binding dep verification..."+ style.RESET_ALL)
  74. ok = testfuncs.verifyAllPredicates(predicates, symbols)
  75. if ok and not silent:
  76. print (style.BRIGHT+ "OK! "+ str(len(predicates))+ " verified."+ style.RESET_ALL)
  77. return 1 if ok else 0
  78. result = 0 # to define for sub-tests
  79. resultFailed = 0 # to define for sub-tests
  80. def doTests(compiler, silent, az3rdParty):
  81. global result
  82. global resultFailed
  83. # Working directory should have been set to this script's directory by the calling parent
  84. # You can get it once doTests() is called, but not during initialization of the module,
  85. # because at that time it will still be set to the working directory of the calling script
  86. workDir = os.getcwd()
  87. if verifyBindingDependencies(os.path.join(workDir, "entry-dependencies.azsl"), compiler, silent) : result += 1
  88. else: resultFailed += 1
  89. if result and verifyBindingDependencies_2(os.path.join(workDir, "../Semantic/standardpbr_forwardpass.azsl"), compiler, silent) : result += 1
  90. else: resultFailed += 1
  91. if result and verifyBindingDependencies_3(os.path.join(workDir, "../Semantic/Triangle.azsl"), compiler, silent) : result += 1
  92. else: resultFailed += 1
  93. if result and verifyBindingDependencies_4(os.path.join(workDir, "BakeAcesOutputTransformLutCS.azslin"), compiler, silent) : result += 1
  94. else: resultFailed += 1
  95. if __name__ == "__main__":
  96. print ("please call from testapp.py")