Skip to content

Commit

Permalink
Fix the lack of incremental compilation provided by add_custom_target (
Browse files Browse the repository at this point in the history
  • Loading branch information
Duttenheim authored Sep 2, 2024
1 parent ae4b535 commit 1a9adb4
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 103 deletions.
24 changes: 19 additions & 5 deletions fips-files/generators/framescriptc.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ def FormatPipeline(self, file):
file.DecreaseIndent()
file.WriteLine("else")
file.IncreaseIndent()
file.WriteLine('n_warning("No registered pipeline creation callback is registered for {}\\n");'.format(self.name))
global framescriptName
file.WriteLine('n_warning("[Frame Script {}] No registered pipeline creation callback is registered for {}\\n");'.format(framescriptName, self.name))
file.DecreaseIndent()

def FormatHeader(self, file):
Expand Down Expand Up @@ -1065,6 +1066,7 @@ def FormatSource(self, file, imports):
file.WriteLine("CoreGraphics::CmdFinishQueries(cmdBuf);")
file.WriteLine("CoreGraphics::CmdEndRecord(cmdBuf);")

file.WriteLine("CoreGraphics::SubmitImmediateCommandBuffers();")
waits = ""
if len(self.waitForSubmissions) > 0:
for wait in self.waitForSubmissions:
Expand All @@ -1079,7 +1081,6 @@ def FormatSource(self, file, imports):
file.WriteLine(', "{}"'.format(self.name))
file.WriteLine("#endif")
file.WriteLine(");")
file.WriteLine("CoreGraphics::SubmitImmediateCommandBuffers();")
if self.waitForQueue is not None:
file.WriteLine("CoreGraphics::WaitForLastSubmission(CoreGraphics::QueueType::{}QueueType, CoreGraphics::QueueType::{}QueueType);".format(self.queue, self.waitForQueue))

Expand Down Expand Up @@ -1456,15 +1457,28 @@ def FormatSource(self, file):
if __name__ == '__main__':
globals()

queues = set(['Graphics', 'Compute', 'Transfer', 'Sparse'])

generator = FrameScriptGenerator()
generator.SetVersion(Version)
file = sys.argv[-3]
outH = sys.argv[-2]
outS = sys.argv[-1]

print("Compiling frame script '{}' -> '{}' & '{}'".format(file, outH, outS))
try:
compilerChangeTime = os.path.getmtime(sys.argv[0])
inputChangeTime = os.path.getmtime(file)
outputHeaderChangeTime = os.path.getmtime(outH)
outputSourceChangeTime = os.path.getmtime(outS)

if compilerChangeTime < outputHeaderChangeTime and compilerChangeTime < outputSourceChangeTime:
if inputChangeTime <= outputHeaderChangeTime and inputChangeTime <= outputSourceChangeTime:
exit(0)
except FileNotFoundError:
pass

print("[Frame Script Compiler] Compiling '{}' -> '{}' & '{}'".format(file, outH, outS))

queues = set(['Graphics', 'Compute', 'Transfer', 'Sparse'])
framescriptName = Path(file).stem

headerF = IDLC.filewriter.FileWriter()
headerF.Open(outH)
Expand Down
194 changes: 119 additions & 75 deletions fips-files/generators/materialtemplatec.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os, platform, sys
import sjson
import ntpath
import subprocess
from pathlib import Path
Version = 1

Expand Down Expand Up @@ -571,87 +572,130 @@ def EndShader(self, f):

generator = MaterialTemplateGenerator()
generator.SetVersion(Version)
files = sys.argv[1:-1]
files = sys.argv[1:-3]
shaderC = sys.argv[-3]
shaderInclude = sys.argv[-2]
outDir = sys.argv[-1]

generator.SetName("materialtemplates")
headerF = IDLC.filewriter.FileWriter()
headerF.Open('{}/materialtemplates.h'.format(outDir))
generator.BeginHeader(headerF)

sourceF = IDLC.filewriter.FileWriter()
sourceF.Open('{}/materialtemplates.cc'.format(outDir))
generator.BeginSource(sourceF)

sourceF.WriteLine('Util::Dictionary<uint, Entry*> Lookup;')
sourceF.WriteLine('Util::Array<Entry*> Configs[(uint)MaterialTemplates::BatchGroup::Num];')

shaderF = IDLC.filewriter.FileWriter()
shaderF.Open('{}/material_interfaces.fx'.format(outDir))
generator.BeginShader(shaderF)

for file in files:
path = Path(file).stem
print("Compiling material template '{}' -> '{}/materialtemplates.h' & '{}/materialtemplates.cc'".format(file, outDir, outDir))
generator.SetDocument(file)
generator.SetName(path)
generator.Parse()
generator.FormatHeader(headerF)
generator.FormatSource(sourceF)
generator.FormatShader(shaderF)

enumStr = '\tInvalid = -1,\n'
for batch in generator.batchGroupDict:
enumStr += '\t{} = {},\n'.format(batch, generator.batchGroupDict[batch])
enumStr += '\tNum\n'
headerF.WriteLine('enum class BatchGroup\n{{\n{}}};'.format(enumStr))

conversionStr = ''
for batch in generator.batchGroupDict:
conversionStr += '\t\tcase "{}"_hash: return BatchGroup::{};\n'.format(batch, batch)
conversionStr += '\t\tdefault: return BatchGroup::Invalid;'
headerF.WriteLine('''
//------------------------------------------------------------------------------
/**
*/
inline BatchGroup\nBatchGroupFromName(const char* name)\n{{\n\tuint code = Util::String::Hash(name, strlen(name));\n\tswitch(code)\n\t{{\n{}\n\t}}\n}}\n'''.format(conversionStr))

# Finish header
enumStr = ''
for file in files:
name = Path(file).stem
enumStr += '\tENUM_{}\n'.format(name)
enumStr += '\tNum\n'

headerF.WriteLine('enum class MaterialProperties\n{{\n{}}};'.format(enumStr))
headerF.WriteLine('extern Util::Dictionary<uint, Entry*> Lookup;')
headerF.WriteLine('extern Util::Array<Entry*> Configs[(uint)MaterialTemplates::BatchGroup::Num];\n')
headerF.WriteLine('void SetupMaterialTemplates();\n')
outHeaderPath = '{}/materialtemplates.h'.format(outDir)
outSourcePath = '{}/materialtemplates.cc'.format(outDir)
outShaderPath = '{}/material_interfaces.fx'.format(outDir)
compilerChangeTime = os.path.getmtime(sys.argv[0])

hasModifications = False
try:
outputHeaderChangeTime = os.path.getmtime(outHeaderPath)
outputSourceChangeTime = os.path.getmtime(outSourcePath)
outputShaderChangeTime = os.path.getmtime(outShaderPath)

for file in files:
inputChangeTime = os.path.getmtime(file)
if compilerChangeTime < outputHeaderChangeTime and compilerChangeTime < outputSourceChangeTime and compilerChangeTime < outputShaderChangeTime:
if inputChangeTime <= outputHeaderChangeTime and inputChangeTime <= outputSourceChangeTime and inputChangeTime <= outputShaderChangeTime:
continue

hasModifications = True
except FileNotFoundError:
hasModifications = True

generator.EndHeader(headerF)
headerF.Close()

# Finish source
setupStr = ''
for file in files:
name = Path(file).stem
setupStr += '\t{}::SetupMaterialTemplates();\n'.format(name)
if hasModifications:
generator.SetName("materialtemplates")
headerF = IDLC.filewriter.FileWriter()
headerF.Open(outHeaderPath)
generator.BeginHeader(headerF)

sourceF = IDLC.filewriter.FileWriter()
sourceF.Open(outSourcePath)
generator.BeginSource(sourceF)

sourceF.WriteLine('Util::Dictionary<uint, Entry*> Lookup;')
sourceF.WriteLine('Util::Array<Entry*> Configs[(uint)MaterialTemplates::BatchGroup::Num];')

shaderF = IDLC.filewriter.FileWriter()
shaderF.Open(outShaderPath)
generator.BeginShader(shaderF)

for file in files:
path = Path(file).stem

print("[Material Template Compiler] '{}' -> '{}/materialtemplates.h' & '{}/materialtemplates.cc & '{}/material_interfaces.fx' ".format(file, outDir, outDir, outDir))
generator.SetDocument(file)
generator.SetName(path)
generator.Parse()
generator.FormatHeader(headerF)
generator.FormatSource(sourceF)
generator.FormatShader(shaderF)

enumStr = '\tInvalid = -1,\n'
for batch in generator.batchGroupDict:
enumStr += '\t{} = {},\n'.format(batch, generator.batchGroupDict[batch])
enumStr += '\tNum\n'
headerF.WriteLine('enum class BatchGroup\n{{\n{}}};'.format(enumStr))

conversionStr = ''
for batch in generator.batchGroupDict:
conversionStr += '\t\tcase "{}"_hash: return BatchGroup::{};\n'.format(batch, batch)
conversionStr += '\t\tdefault: return BatchGroup::Invalid;'
headerF.WriteLine('''
//------------------------------------------------------------------------------
/**
*/
inline BatchGroup\nBatchGroupFromName(const char* name)\n{{\n\tuint code = Util::String::Hash(name, strlen(name));\n\tswitch(code)\n\t{{\n{}\n\t}}\n}}\n'''.format(conversionStr))

# Finish header
enumStr = ''
for file in files:
name = Path(file).stem
enumStr += '\tENUM_{}\n'.format(name)
enumStr += '\tNum\n'

headerF.WriteLine('enum class MaterialProperties\n{{\n{}}};'.format(enumStr))
headerF.WriteLine('extern Util::Dictionary<uint, Entry*> Lookup;')
headerF.WriteLine('extern Util::Array<Entry*> Configs[(uint)MaterialTemplates::BatchGroup::Num];\n')
headerF.WriteLine('void SetupMaterialTemplates();\n')

generator.EndHeader(headerF)
headerF.Close()

# Finish source
setupStr = ''
for file in files:
name = Path(file).stem
setupStr += '\t{}::SetupMaterialTemplates();\n'.format(name)

sourceF.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates() \n{{\n{}}}'.format(setupStr))
sourceF.WriteLine('//------------------------------------------------------------------------------\n/**\n*/\nvoid\nSetupMaterialTemplates() \n{{\n{}}}'.format(setupStr))

generator.EndSource(sourceF)
sourceF.Close()
generator.EndSource(sourceF)
sourceF.Close()

# Finish shader
shaderF.WriteLine("#define MATERIAL_BINDING group(BATCH_GROUP) binding(51)")
shaderF.WriteLine("const uint MaterialBindingSlot = 51;")
shaderF.WriteLine("const uint MaterialBufferSlot = 52;")
# Finish shader
shaderF.WriteLine("#define MATERIAL_BINDING group(BATCH_GROUP) binding(51)")
shaderF.WriteLine("const uint MaterialBindingSlot = 51;")
shaderF.WriteLine("const uint MaterialBufferSlot = 52;")

bindingsContent = ''
for file in files:
fileName = Path(file).stem
bindingsContent += "\tMATERIAL_LIST_{}\n".format(fileName)
bindingsContent = ''
for file in files:
fileName = Path(file).stem
bindingsContent += "\tMATERIAL_LIST_{}\n".format(fileName)

shaderF.WriteLine("MATERIAL_BINDING rw_buffer MaterialBindings\n{{\n{}}};".format(bindingsContent))
generator.EndShader(shaderF)
shaderF.Close()
shaderF.WriteLine("MATERIAL_BINDING rw_buffer MaterialBindings\n{{\n{}}};".format(bindingsContent))
generator.EndShader(shaderF)
shaderF.Close()


# Finally, run the AnyFX compiler
shaderBinaryOutput = "{}/material_interfaces.fxb".format(outDir)
shaderHeaderOutput = "{}/material_interfaces.h".format(outDir)

try:
outputShaderBinaryChangeTime = os.path.getmtime(shaderBinaryOutput)
outputShaderHeaderChangeTime = os.path.getmtime(shaderHeaderOutput)
shaderCompilerChangeTime = os.path.getmtime(shaderC)
if shaderCompilerChangeTime < outputShaderBinaryChangeTime and shaderCompilerChangeTime < outputShaderHeaderChangeTime:
if outputShaderChangeTime <= outputShaderBinaryChangeTime and outputShaderChangeTime <= outputShaderHeaderChangeTime:
exit(0)
except FileNotFoundError:
pass

subprocess.run([shaderC, "-i", outShaderPath, "-I", shaderInclude, "-I", outDir, "-o", shaderBinaryOutput, "-h", shaderHeaderOutput, "-t", "shader"])
27 changes: 4 additions & 23 deletions fips-files/include.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,13 @@ macro(nebula_material_template_compile)
set(out_header "materialtemplates.h")
set(out_source "materialtemplates.cc")
set(out_shader "material_interfaces.fx")
set(out_shader_header "material_interfaces.h")

set(abs_output_folder "${CMAKE_BINARY_DIR}/material_templates/render/materials")
file(MAKE_DIRECTORY ${abs_output_folder})
add_custom_target(materialtemplates
COMMAND ${PYTHON} ${NROOT}/fips-files/generators/materialtemplatec.py ${material_definition_files} "${abs_output_folder}"
BYPRODUCTS "${abs_output_folder}/${out_header}" "${abs_output_folder}/${out_source}" "${abs_output_folder}/${out_shader}"
COMMAND ${PYTHON} ${NROOT}/fips-files/generators/materialtemplatec.py ${material_definition_files} ${SHADERC} ${NROOT}/syswork/shaders/vk "${abs_output_folder}"
BYPRODUCTS "${abs_output_folder}/${out_header}" "${abs_output_folder}/${out_source}" "${abs_output_folder}/${out_shader}" "${abs_output_folder}/${out_shader_header}"
WORKING_DIRECTORY "${NROOT}"
DEPENDS ${NROOT}/fips-files/generators/materialtemplatec.py ${material_definition_files}
VERBATIM)
Expand All @@ -326,27 +327,7 @@ macro(nebula_material_template_compile)
target_sources(render PRIVATE "${abs_output_folder}/${out_header}" "${abs_output_folder}/${out_source}" "${abs_output_folder}/${out_shader}")

target_include_directories(render PUBLIC "${CMAKE_BINARY_DIR}/material_templates/render")

set(depoutput ${abs_output_folder}/material_interfaces.dep)
set(headerOutput ${abs_output_folder}/material_interfaces.h)
set(shaderInput ${abs_output_folder}/material_interfaces.fx)
set(binaryOutput ${abs_output_folder}/material_interfaces.fxb)
execute_process(COMMAND ${SHADERC} -M -i ${shaderInput} -I ${NROOT}/syswork/shaders/vk -I ${abs_output_folder} -o ${depoutput} -h ${headerOutput}.h -t shader)

if(N_NEBULA_DEBUG_SHADERS)
set(shader_debug "-debug")
endif()

add_custom_target(materialinterface
COMMAND ${SHADERC} -i ${shaderInput} -I ${NROOT}/syswork/shaders/vk -I ${abs_output_folder} -o ${binaryOutput} -h ${headerOutput} -t shader ${shader_debug}
BYPRODUCTS ${headerOutput}.h
WORKING_DIRECTORY ${FIPS_PROJECT_DIR}
DEPENDS ${SHADERC} ${depoutput}
VERBATIM
)
set_target_properties(materialinterface PROPERTIES FOLDER "Material Definitions")
add_dependencies(materialinterface materialtemplates)
add_dependencies(render materialinterface)
add_dependencies(render materialtemplates)
endmacro()

macro(nebula_framescript_add)
Expand Down

0 comments on commit 1a9adb4

Please sign in to comment.