public DataStorageItem <T> Add <T>(string name, int length) { DataStorageItem <T> ret = new DataStorageItem <T>(name, length); m_Storage.Add(name, ret); return(ret); }
private void PrepareShaderStage(StageType stage, object shaderInstance) { Type type = shaderInstance.GetType(); Expression primiteVertexIndexExpression = IntrospectionUtil.GetFieldExpression(this, nameof(PrimitiveVertexIndex)); foreach (var fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { string debugFieldName = string.Format("{0}.{1}", type.Name, fieldInfo.Name); var fieldExpression = IntrospectionUtil.GetFieldExpression(shaderInstance, fieldInfo); // BUILTIN if (m_ShaderBuiltins.IsBuiltin(stage, fieldInfo.Name)) { if (!m_ShaderBuiltins.Validate(stage, fieldInfo)) { DebugMsg(string.Format("ERROR: failed to bind: invalid builtin {0}", debugFieldName)); continue; } var builtin = m_ShaderBuiltins.Get(stage, fieldInfo.Name); var directionIn = builtin.Flags.HasFlag(BuiltinFlags.In); var directionOut = builtin.Flags.HasFlag(BuiltinFlags.Out); if (directionIn || directionOut) { Expression builtinVarExpression = IntrospectionUtil.GetFieldExpression(this, builtin.Name); Expression builtinExpression = builtinVarExpression; // Indexed? if (builtin.Flags.HasFlag(BuiltinFlags.IndexedPerVertex)) { builtinExpression = IntrospectionUtil.GetArrayAccessExpression(builtinVarExpression, primiteVertexIndexExpression); } if (!ValidateFieldType(fieldInfo, builtinExpression.Type)) { continue; } if (directionIn) { // m_Stages[stage].AddPreaction(IntrospectionUtil.CreateAssign(fieldExpression, builtinExpression)); m_PipelineProgramDefinition.PreActions[stage].Add(Expression.Assign(fieldExpression, builtinExpression)); } if (directionOut) { // m_Stages[stage].AddPostAction(IntrospectionUtil.CreateAssign(builtinExpression, fieldExpression)); m_PipelineProgramDefinition.PostActions[stage].Add(Expression.Assign(builtinExpression, fieldExpression)); } } if (builtin.Flags.HasFlag(BuiltinFlags.HasAction)) { builtin.UseAction.Invoke(); } continue; } // ----- Verify ShaderAttribute ----- var attrs = fieldInfo.GetCustomAttributes(typeof(ShaderLayoutAttribute)).ToArray(); if (attrs.Length < 1) { continue; } if (attrs.Length > 1) { DebugMsg(string.Format("Ambiguous attributes for field {0}", debugFieldName)); continue; } ShaderLayoutAttribute atr = (ShaderLayoutAttribute)attrs[0]; // ----- User variable with ShaderAttribute ----- if (atr.type == ShaderLayoutType.Uniform) { var readUniformCall = GetReadUniformExpression(fieldInfo, atr.binding, atr.set); if (readUniformCall != null) { m_PipelineProgramDefinition.UniformLoader.Add(Expression.Assign(fieldExpression, readUniformCall)); } continue; } if (stage == StageType.VertexShader) { // IF IN: obj.var = ReadVertexBuffer(location) // IF OUT: storage[var][index] = obj.var if (atr.type == ShaderLayoutType.In) { Type vertexBufferType = GetVertexBufferType(fieldInfo, atr.location); if (vertexBufferType == null) { // incompatible or not found continue; } if (!ValidateFieldType(fieldInfo, vertexBufferType)) { continue; } var readVertexBufferCall = GetReadVertexBufferExpression(fieldInfo, atr.location); if (readVertexBufferCall != null) { m_PipelineProgramDefinition.PreActions[stage].Add(Expression.Assign(fieldExpression, readVertexBufferCall)); } } else if (atr.type == ShaderLayoutType.Out) { DataStorageItem storage = m_Storage.AddGeneric(fieldInfo.Name, fieldInfo.FieldType, PrimitiveLength); Expression storageExpression = storage.GetIndexedExpression(primiteVertexIndexExpression); m_PipelineProgramDefinition.PostActions[stage].Add(Expression.Assign(storageExpression, fieldExpression)); } } else if (stage == StageType.FragmentShader) { // IF IN: obj.var = ReadSmoth(storage[var]) // IF OUT: WriteColorOutput(location, obj.var) if (atr.type == ShaderLayoutType.In) { if (!m_Storage.HasKey(fieldInfo.Name)) { DebugMsg(string.Format("ERROR: failed to bind field {0} (not found)", debugFieldName)); continue; } DataStorageItem storage = m_Storage.Get(fieldInfo.Name); if (!ValidateFieldType(fieldInfo, storage.DataType)) { continue; } var storageArrayExpression = storage.GetArrayExpression(); var readSmothCall = GetReadSmothExpression(fieldInfo, storageArrayExpression); m_PipelineProgramDefinition.PreActions[stage].Add(Expression.Assign(fieldExpression, readSmothCall)); } else if (atr.type == ShaderLayoutType.Out) { if (!ValidateFieldType(fieldInfo, P_WRITE_COLOR_TYPE)) { continue; } var writeColorOutputCall = GetWriteColorOutputExpression(atr.location, fieldExpression); m_PipelineProgramDefinition.PostActions[stage].Add(writeColorOutputCall); } } } }