diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-12-07 03:51:58 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-12-07 03:51:58 +0100 |
| commit | 2af048902ea6952eaac368b8880788214f2e95af (patch) | |
| tree | 00e0e958232227f9a8b750c2cbaa19c1f5a3a279 | |
| parent | 6571d8e5bfc0593afb466e2fced7a2db43bc13e2 (diff) | |
tell rewriter to set the stype property to ensure it's always the good one
| -rw-r--r-- | tests/Program.cs | 22 | ||||
| -rw-r--r-- | vk.generator/Program.cs | 68 | ||||
| -rw-r--r-- | vk.rewrite/Program.cs | 54 | ||||
| -rw-r--r-- | vulkan/ExtensionMethods.cs | 2 | ||||
| -rw-r--r-- | vulkan/PinAttribute.cs | 14 | ||||
| -rw-r--r-- | vulkan/StructTypeAttribute.cs | 20 |
6 files changed, 119 insertions, 61 deletions
diff --git a/tests/Program.cs b/tests/Program.cs index 0a3d501..1e431fd 100644 --- a/tests/Program.cs +++ b/tests/Program.cs @@ -18,22 +18,24 @@ namespace tests using (VkApplicationInfo ai = new VkApplicationInfo( new Version (1,0,0), new Version (1,0,0), - new Version (1,2,0)) {pApplicationName = "new application name"}){ + new Version (1,2,0)) { + pApplicationName = "new application name" + }){ VkClearColorValue clear = new VkClearColorValue(255,0,0); clear.floats[2] = 210; - VkInstanceCreateInfo ci = VkInstanceCreateInfo.New(); - ci.pApplicationInfo = ai; + using (VkInstanceCreateInfo ci = new VkInstanceCreateInfo() { + pApplicationInfo = ai}){ - VkResult res = vkCreateInstance (ref ci, IntPtr.Zero, out instance); - if (res != VkResult.Success) { - Console.WriteLine ($"Error: {res}"); - return; - }else - Console.WriteLine ($"Success: {res}"); + VkResult res = vkCreateInstance (ci, IntPtr.Zero, out instance); + if (res != VkResult.Success) { + Console.WriteLine ($"Error: {res}"); + return; + }else + Console.WriteLine ($"Success: {res}"); - ci.Dispose(); + } } vkDestroyInstance (instance, IntPtr.Zero); diff --git a/vk.generator/Program.cs b/vk.generator/Program.cs index 8dd0bcf..f233098 100644 --- a/vk.generator/Program.cs +++ b/vk.generator/Program.cs @@ -599,31 +599,6 @@ namespace vk.generator { tw.WriteLine ($"namespace {vknamespace} {{"); } static EnumDef structTypeEnum = null; - static void writeStructNew (IndentedTextWriter tw, StructDef sd) { - MemberDef md = sd.members.Where (mb => mb.Name == "sType").First (); - string csStructName = $"{structTypeEnum.CSName}.{structTypeEnum.AllValues.FirstOrDefault(st=>st.Name == md.defaultValue).CSName}"; - - tw.WriteLine ($"public static {sd.Name} New () {{"); - tw.Indent++; - - tw.WriteLine ($"return new {sd.Name} {{"); - tw.Indent++; - - tw.WriteLine ($"sType = {csStructName},"); - tw.Indent--; - tw.WriteLine (@"};"); - tw.Indent--; - tw.WriteLine (@"}"); - - /*tw.WriteLine ($"public {sd.Name} (IntPtr pNext) : this () {{"); - tw.Indent++; - - tw.WriteLine ($"sType = {csStructName};"); - tw.WriteLine ($"this.pNext = pNext;"); - - tw.Indent--; - tw.WriteLine (@"}");*/ - } static bool tryGetVectorType (string type, int dim, out string vectorType) { vectorType = null; switch (type) { @@ -867,6 +842,15 @@ namespace vk.generator { else tw.WriteLine ($"[StructLayout(LayoutKind.Sequential)]"); + MemberDef mdSType = sd.members.Where (mb => mb.Name == "sType").FirstOrDefault (); + EnumerantValue evSType = mdSType == null ? null : + mdSType.defaultValue == null ? null : + structTypeEnum.AllValues.FirstOrDefault(st=>st.Name == mdSType.defaultValue); + string csStructName = evSType == null ? null : $"{structTypeEnum.CSName}.{evSType.CSName}"; + if (csStructName!=null) { + tw.WriteLine ($"[StructureType ({evSType.value})]"); + } + getStructurePtrProxies (sd, out IEnumerable<string> ptrProxies, out IEnumerable<string> utf8StringPointers); if (ptrProxies.Count() == 0 && utf8StringPointers.Count() == 0) @@ -945,8 +929,7 @@ namespace vk.generator { tw.WriteLine ($"public {typeStr} {mb.Name};"); } - if (sd.members.Any (mb => mb.Name == "sType" && !string.IsNullOrEmpty (mb.defaultValue))) { - writeStructNew (tw, sd); + if (csStructName != null) { //write CTOR IEnumerable<MemberDef> members = sd.members.Where (m=> m.Name != "sType" && m.Name != "pNext"). @@ -956,8 +939,6 @@ namespace vk.generator { List<string> ctorDefaults = new List<string>(); if (sd.members.Where (m=>!m.optional && m.Name != "sType").Count()>0) { - MemberDef md = sd.members.Where (mb => mb.Name == "sType").First (); - string csStructName = $"{structTypeEnum.CSName}.{structTypeEnum.AllValues.FirstOrDefault(st=>st.Name == md.defaultValue).CSName}"; foreach (MemberDef mdef in members) { @@ -1342,12 +1323,12 @@ namespace vk.generator { static string getByRefParamSig (MemberDef md, bool isLast) { if (!md.paramDef.tryGetTypeDef (out TypeDef td)) throw new Exception ($"type not found: {md.paramDef.Name}"); - string typeName = td.CSName; //md.paramDef.CSName == "void" ? "IntPtr" : md.paramDef.CSName; + string typeName = td.CSName; switch (md.paramDef.IndirectionLevel) { case 1: return md.paramDef.IsConst ? - (string.Format ($"ref {typeName} {md.Name}{(isLast ? ", " : ")")}")) : - (string.Format ($"out {typeName} {md.Name}{(isLast ? ", " : ")")}")); + string.Format ($"ref {typeName} {md.Name}{(isLast ? ", " : ")")}") : + string.Format ($"out {typeName} {md.Name}{(isLast ? ", " : ")")}"); case 2: return md.paramDef.IsConst ? string.Format ($"ref IntPtr {md.Name}{(isLast ? ", " : ")")}") : @@ -1355,6 +1336,22 @@ namespace vk.generator { } return null; } + static string getPinParamSig (MemberDef md, bool isLast) { + if (!md.paramDef.tryGetTypeDef (out TypeDef td)) + throw new Exception ($"type not found: {md.paramDef.Name}"); + string typeName = td.CSName; + switch (md.paramDef.IndirectionLevel) { + case 1: + return md.paramDef.IsConst ? + string.Format ($"[Pin]{typeName} {md.Name}{(isLast ? ", " : ")")}") : + string.Format ($"out {typeName} {md.Name}{(isLast ? ", " : ")")}"); + case 2: + return md.paramDef.IsConst ? + string.Format ($"[Pin]IntPtr {md.Name}{(isLast ? ", " : ")")}") : + string.Format ($"out IntPtr {md.Name}{(isLast ? ", " : ")")}"); + } + return null; + } static void writeCmd (IndentedTextWriter tw, string sig) { tw.WriteLine (@"[CalliRewrite]"); @@ -1369,8 +1366,11 @@ namespace vk.generator { for (int i = 0; i < cd.parameters.Count; i++) { MemberDef md = cd.parameters[i]; List<string> typeSigs = new List<string> () { getDefaultParamSig (md, i < cd.parameters.Count - 1) }; - if (md.paramDef.IndirectionLevel == 1 && md.paramDef.Name != "void") - typeSigs.Add (getByRefParamSig (md, i < cd.parameters.Count - 1)); + if (md.paramDef.IndirectionLevel == 1 && md.paramDef.Name != "void") { + if (md.paramDef.IsConst) + typeSigs.Add (getByRefParamSig (md, i < cd.parameters.Count - 1)); + typeSigs.Add (getPinParamSig (md, i < cd.parameters.Count - 1)); + } string[] prevSigs = new string[signatures.Count]; Array.Copy (signatures.ToArray (), prevSigs, prevSigs.Length); diff --git a/vk.rewrite/Program.cs b/vk.rewrite/Program.cs index d2a254e..90e330f 100644 --- a/vk.rewrite/Program.cs +++ b/vk.rewrite/Program.cs @@ -17,7 +17,9 @@ namespace Vk.Rewrite { const string mainVkNamespace = "Vulkan"; - static TypeReference s_calliRewriteRef; + static TypeReference trefCalliRewrite; + static TypeReference trefPin; + static TypeReference trefStructureType; public static int Main(string[] args) { @@ -56,14 +58,16 @@ namespace Vk.Rewrite { ModuleDefinition mainModule = vkDll.Modules[0]; - s_calliRewriteRef = mainModule.GetType (mainVkNamespace+".Generator.CalliRewriteAttribute"); + trefCalliRewrite = mainModule.GetType (mainVkNamespace+".Generator.CalliRewriteAttribute"); + trefPin = mainModule.GetType (mainVkNamespace+".Generator.PinAttribute"); + trefStructureType = mainModule.GetType (mainVkNamespace+".StructureTypeAttribute"); foreach (TypeDefinition type in mainModule.Types) { foreach (MethodDefinition method in type.Methods) { - if (method.CustomAttributes.Any(ca => ca.AttributeType == s_calliRewriteRef)) + if (method.CustomAttributes.Any(ca => ca.AttributeType == trefCalliRewrite)) RewriteMethod (method); } } @@ -76,24 +80,48 @@ namespace Vk.Rewrite ILProcessor il = method.Body.GetILProcessor(); il.Body.Instructions.Clear(); - List<VariableDefinition> stringParams = new List<VariableDefinition>(); for (int i = 0; i < method.Parameters.Count; i++) { EmitLoadArgument (il, i, method.Parameters); TypeReference parameterType = method.Parameters[i].ParameterType; + TypeDefinition td = parameterType as TypeDefinition; + PropertyDefinition fd = td?.Properties.FirstOrDefault (f=>f.Name == "sType"); - if (parameterType.IsGenericInstance) { - if (parameterType.Name == "Nullable`1") - System.Diagnostics.Debugger.Break (); + CustomAttribute ca = td == null ? null : td.CustomAttributes.FirstOrDefault (ca => ca.AttributeType == trefStructureType); + int structType = 0; + if (ca != null) { + PropertyDefinition pd = (ca.AttributeType as TypeDefinition).Properties[0]; + structType = (int)ca.ConstructorArguments[0].Value; } - if (parameterType.IsByReference) - { + if (method.Parameters[i].CustomAttributes.Any(ca => ca.AttributeType == trefPin)) { + VariableDefinition variable = new VariableDefinition(parameterType); + method.Body.Variables.Add(variable); + il.Emit(OpCodes.Stloc, variable); + if (ca != null) { + il.Emit(OpCodes.Ldloca, variable); + il.Emit(OpCodes.Ldc_I4, structType); + il.Emit(OpCodes.Call, fd.SetMethod); + } + il.Emit(OpCodes.Ldloca, variable); + variable = new VariableDefinition(new PinnedType(new ByReferenceType(parameterType))); + method.Body.Variables.Add(variable); + il.Emit(OpCodes.Stloc, variable); + il.Emit(OpCodes.Ldloc, variable); + il.Emit(OpCodes.Conv_I); + } else if (parameterType.IsByReference) { VariableDefinition byRefVariable = new VariableDefinition(new PinnedType(parameterType)); method.Body.Variables.Add(byRefVariable); il.Emit(OpCodes.Stloc, byRefVariable); il.Emit(OpCodes.Ldloc, byRefVariable); il.Emit(OpCodes.Conv_I); + } else if (ca != null) { + VariableDefinition variable = new VariableDefinition(parameterType); + method.Body.Variables.Add(variable); + il.Emit(OpCodes.Stloc, variable); + il.Emit(OpCodes.Ldloca, variable); + il.Emit(OpCodes.Ldc_I4, structType); + il.Emit(OpCodes.Call, fd.SetMethod); } } @@ -110,7 +138,7 @@ namespace Vk.Rewrite { TypeReference parameterType; - if (pd.ParameterType.IsByReference) + if (pd.ParameterType.IsByReference || pd.CustomAttributes.Any(ca => ca.AttributeType == trefPin)) parameterType = new PointerType(pd.ParameterType.GetElementType()); else parameterType = pd.ParameterType; @@ -121,12 +149,6 @@ namespace Vk.Rewrite } il.Emit(OpCodes.Calli, callSite); - /*foreach (VariableDefinition stringVar in stringParams) - { - il.Emit(OpCodes.Ldloc, stringVar); - il.Emit(OpCodes.Call, s_freeHGlobalRef); - }*/ - il.Emit(OpCodes.Ret); if (method.Body.Variables.Count > 0) diff --git a/vulkan/ExtensionMethods.cs b/vulkan/ExtensionMethods.cs index d14625e..c40e56d 100644 --- a/vulkan/ExtensionMethods.cs +++ b/vulkan/ExtensionMethods.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// Copyright (c) 2019-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; diff --git a/vulkan/PinAttribute.cs b/vulkan/PinAttribute.cs new file mode 100644 index 0000000..9e7ae3a --- /dev/null +++ b/vulkan/PinAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; + +namespace Vulkan.Generator +{ + /// <summary> + /// tel the rewrite to take adress of arg and pin it + /// </summary> + public class PinAttribute : Attribute + { + } +} diff --git a/vulkan/StructTypeAttribute.cs b/vulkan/StructTypeAttribute.cs new file mode 100644 index 0000000..55f8177 --- /dev/null +++ b/vulkan/StructTypeAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; + +namespace Vulkan +{ + /// <summary> + /// tel the rewriter to automatically set the structure type + /// </summary> + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)] + public class StructureTypeAttribute : Attribute + { + int structureType; + public StructureTypeAttribute (int value) : base() { + structureType = value; + } + public int StructureType => structureType; + } +} |