public static ShaderEntryPointInfo GeneratePixel(FrontEndTranslator translator, ShaderType shaderType, ShaderFunction function) { var entryPoint = new ShaderEntryPointInfo(); var context = new FrontEndContext(); context.mCurrentType = shaderType; var interfaceInfo = new EntryPointInterfaceInfo(); EntryPointGenerationShared.CollectInterface(translator, shaderType, interfaceInfo); // Build inputs block EntryPointGenerationShared.GenerateHardwareBuiltIns(translator, interfaceInfo.HardwareBuiltInInputs, StorageClass.Input, entryPoint.mInterfaceVariables, entryPoint.mDecorations); InputDeclarations.GenerateInputStruct(translator, shaderType, interfaceInfo.StageInputs, entryPoint.mInterfaceVariables, entryPoint.mDecorations); EntryPointGenerationShared.GenerateHardwareBuiltIns(translator, interfaceInfo.HardwareBuiltInOutputs, StorageClass.Output, entryPoint.mInterfaceVariables, entryPoint.mDecorations); OutputDeclarations.GenerateOutputFields(translator, shaderType, interfaceInfo.StageOutputs, entryPoint.mInterfaceVariables, entryPoint.mDecorations); UniformDeclarations.DeclareUniformBuffers(translator, interfaceInfo.UniformBuffers, entryPoint.mInterfaceVariables, entryPoint.mDecorations); UniformDeclarations.DeclareUniformConstants(translator, interfaceInfo.ConstantUniforms, entryPoint.mDecorations); // Create the functions required to run an entry point string entryPointName = EntryPointGenerationShared.GenerateEntryPointFunctionName(translator, shaderType, function); CreateGlobalVariableInitializeFunction(translator, shaderType, entryPoint, interfaceInfo, context); InputDeclarations.GenerateCopyInputsFunction(translator, shaderType, entryPoint, interfaceInfo); OutputDeclarations.GenerateCopyOutputsFunction(translator, shaderType, entryPoint, interfaceInfo); var entryPointFunction = GenerateSpirVEntryPointFunction(translator, shaderType, entryPointName); // Generate the entry point function body translator.TryGenerateFunctionCall(entryPoint.mGlobalsInitializationFunction, null, null, entryPointFunction.Context); EntryPointGenerationShared.ConstructShaderType(translator, shaderType, entryPointFunction.Context); var entryPointThisOp = entryPointFunction.Context.mThisOp; translator.TryGenerateFunctionCall(interfaceInfo.CopyInputsFunction.ShaderFunction, entryPointThisOp, null, entryPointFunction.Context); translator.TryGenerateFunctionCall(function, entryPointThisOp, null, entryPointFunction.Context); translator.TryGenerateFunctionCall(interfaceInfo.CopyOutputsFunction.ShaderFunction, entryPointThisOp, null, entryPointFunction.Context); translator.FixupBlockTerminators(entryPointFunction.ShaderFunction); // Make sure all global variables are added to the interface of the entry point AddGlobalVariables(translator, entryPoint, interfaceInfo); entryPoint.mEntryPointFunction = entryPointFunction.ShaderFunction; entryPoint.mStageType = shaderType.mFragmentType; shaderType.mEntryPoints.Add(entryPoint); EntryPointGenerationShared.AddExecutionMode(translator, entryPoint, entryPoint.mEntryPointFunction, Spv.ExecutionMode.ExecutionModeOriginUpperLeft); return(entryPoint); }
public static void CreateGlobalVariableInitializeFunction(FrontEndTranslator translator, ShaderType shaderType, ShaderEntryPointInfo entryPoint, EntryPointInterfaceInfo interfaceInfo, FrontEndContext context) { // First check if any global variables that need the variable initialization function exist. If not then don't emit anything. bool globalVariablesExist = false; foreach (var globalField in interfaceInfo.GlobalFields) { if (globalField.InitialValue != null) { globalVariablesExist = true; } } if (!globalVariablesExist) { return; } var library = translator.mCurrentLibrary; var voidType = library.FindType(new TypeKey(typeof(void))); var initGlobalFunction = translator.CreateFunctionAndType(shaderType, voidType, "InitGlobals", null, null); initGlobalFunction.mBlocks.Add(new ShaderBlock()); entryPoint.mGlobalsInitializationFunction = initGlobalFunction; // Add the store op for each global variable context.mCurrentFunction = initGlobalFunction; context.mCurrentBlock = initGlobalFunction.mBlocks[0]; foreach (var globalField in interfaceInfo.GlobalFields) { if (globalField.InitialValue != null) { translator.CreateStoreOp(context.mCurrentBlock, globalField.InstanceOp, globalField.InitialValue); } } translator.FixupBlockTerminators(context.mCurrentFunction); }