Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

233 linhas
9.9 KiB

  1. unit uvkuDeviceFactory;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. Vulkan, uvkuInstance, uvkuDevice, uvkuAllocationHandler;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TvkuQueuePriorityArr = array of VkFloat;
  10. TvkuQueueCreateInfo = packed record
  11. Flags: VkDeviceQueueCreateFlags;
  12. FamilyIndex: VkUint32;
  13. Priorities: TvkuQueuePriorityArr;
  14. end;
  15. TvkuQueueCreateInfoArr = array of TvkuQueueCreateInfo;
  16. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. TvkuDeviceEx = class(TvkuDevice)
  18. private
  19. fAllocHandler: TvkuAllocationHandler;
  20. fOwnsHandler: Boolean;
  21. public
  22. destructor Destroy; override;
  23. end;
  24. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  25. TvkuDeviceFactory = class(TObject)
  26. private
  27. fInstanceCommands: TVkInstanceCommands;
  28. fFeatures: TVkPhysicalDeviceFeatures;
  29. fFlags: VkDeviceCreateFlags;
  30. fLayers: TStringList;
  31. fExtensions: TStringList;
  32. fQueueCreateInfos: TvkuQueueCreateInfoArr;
  33. function GetLayers: TStrings;
  34. function GetExtensions: TStrings;
  35. function GetQueueCreateInfoCount: Integer;
  36. function GetQueueCreateInfo(const aIndex: Integer): TvkuQueueCreateInfo;
  37. function GetQueueCreateInfos: TvkuQueueCreateInfoArr;
  38. procedure SetQueueCreateInfoCount(aValue: Integer);
  39. procedure SetQueueCreateInfo(const aIndex: Integer; aValue: TvkuQueueCreateInfo);
  40. procedure SetQueueCreateInfos(aValue: TvkuQueueCreateInfoArr);
  41. public
  42. property Flags: VkDeviceCreateFlags read fFlags write fFlags;
  43. property EnabledLayers: TStrings read GetLayers;
  44. property EnabledExtensions: TStrings read GetExtensions;
  45. property EnabledFeatures: TVkPhysicalDeviceFeatures read fFeatures;
  46. property QueueCreateInfos: TvkuQueueCreateInfoArr read GetQueueCreateInfos write SetQueueCreateInfos;
  47. property QueueCreateInfoCount: Integer read GetQueueCreateInfoCount write SetQueueCreateInfoCount;
  48. property QueueCreateInfo[const aIndex: Integer]: TvkuQueueCreateInfo read GetQueueCreateInfo write SetQueueCreateInfo;
  49. function CreateDevice(
  50. const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
  51. function CreateDevice(
  52. const aPhysicalDevice: VkPhysicalDevice;
  53. const aAllocHandler: TvkuAllocationHandler;
  54. const aOwnsHandler: Boolean): TvkuDevice;
  55. constructor Create(const aInstance: TvkuInstance);
  56. constructor Create(const aInstanceCommands: TVkInstanceCommands);
  57. destructor Destroy; override;
  58. end;
  59. implementation
  60. uses
  61. uvkuUtils;
  62. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. //TvkuDeviceEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. destructor TvkuDeviceEx.Destroy;
  66. begin
  67. inherited Destroy;
  68. if fOwnsHandler then
  69. FreeAndNil(fAllocHandler);
  70. end;
  71. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  72. //TvkuDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. function TvkuDeviceFactory.GetLayers: TStrings;
  75. begin
  76. result := fLayers;
  77. end;
  78. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. function TvkuDeviceFactory.GetExtensions: TStrings;
  80. begin
  81. result := fExtensions;
  82. end;
  83. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  84. function TvkuDeviceFactory.GetQueueCreateInfoCount: Integer;
  85. begin
  86. result := Length(fQueueCreateInfos);
  87. end;
  88. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  89. function TvkuDeviceFactory.GetQueueCreateInfo(const aIndex: Integer): TvkuQueueCreateInfo;
  90. begin
  91. if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
  92. raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
  93. result := fQueueCreateInfos[aIndex];
  94. end;
  95. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  96. function TvkuDeviceFactory.GetQueueCreateInfos: TvkuQueueCreateInfoArr;
  97. begin
  98. result := fQueueCreateInfos;
  99. end;
  100. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  101. procedure TvkuDeviceFactory.SetQueueCreateInfoCount(aValue: Integer);
  102. begin
  103. if (aValue < 0) then
  104. aValue := 0;
  105. SetLength(fQueueCreateInfos, aValue);
  106. end;
  107. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. procedure TvkuDeviceFactory.SetQueueCreateInfo(const aIndex: Integer; aValue: TvkuQueueCreateInfo);
  109. begin
  110. if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
  111. raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
  112. fQueueCreateInfos[aIndex] := aValue;
  113. end;
  114. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. procedure TvkuDeviceFactory.SetQueueCreateInfos(aValue: TvkuQueueCreateInfoArr);
  116. begin
  117. fQueueCreateInfos := aValue;
  118. end;
  119. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  120. function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
  121. begin
  122. result := CreateDevice(aPhysicalDevice, nil, false);
  123. end;
  124. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice;
  126. const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice;
  127. var
  128. CreateInfo: TVkDeviceCreateInfo;
  129. QueueInfos: array of TVkDeviceQueueCreateInfo;
  130. lay: array of PVkChar;
  131. ext: array of PVkChar;
  132. i: Integer;
  133. begin
  134. if (Length(fQueueCreateInfos) <= 0) then
  135. raise TvkuException.Create('no queue create infos assigned');
  136. SetLength(lay, fLayers.Count);
  137. for i := 0 to fLayers.Count-1 do
  138. lay[i] := PVkChar(fLayers[i]);
  139. SetLength(ext, fExtensions.Count);
  140. for i := 0 to fExtensions.Count-1 do
  141. ext[i] := PVkChar(fExtensions[i]);
  142. SetLength(QueueInfos, Length(fQueueCreateInfos));
  143. for i := 0 to high(fQueueCreateInfos) do begin
  144. FillByte(QueueInfos[i], SizeOf(QueueInfos[0]), 0);
  145. QueueInfos[i].sType := VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  146. QueueInfos[i].pNext := nil;
  147. QueueInfos[i].flags := fQueueCreateInfos[i].Flags;
  148. QueueInfos[i].queueFamilyIndex := fQueueCreateInfos[i].FamilyIndex;
  149. QueueInfos[i].queueCount := Length(fQueueCreateInfos[i].Priorities);
  150. if (QueueInfos[i].queueCount > 0)
  151. then QueueInfos[i].pQueuePriorities := @fQueueCreateInfos[i].Priorities[0]
  152. else QueueInfos[i].pQueuePriorities := nil;
  153. end;
  154. FillByte(CreateInfo, SizeOf(CreateInfo), 0);
  155. CreateInfo.sType := VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  156. CreateInfo.pNext := nil;
  157. CreateInfo.flags := fFlags;
  158. CreateInfo.queueCreateInfoCount := Length(QueueInfos);
  159. CreateInfo.pQueueCreateInfos := @QueueInfos[0];
  160. CreateInfo.enabledLayerCount := Length(lay);
  161. CreateInfo.ppEnabledLayerNames := @lay[0];
  162. CreateInfo.enabledExtensionCount := Length(ext);
  163. CreateInfo.ppEnabledExtensionNames := @ext[0];
  164. CreateInfo.pEnabledFeatures := @fFeatures;
  165. if Assigned(aAllocHandler)
  166. then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstanceCommands, aAllocHandler.GetAllocationCallbacks)
  167. else result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstanceCommands);
  168. try
  169. TvkuDeviceEx(result).fAllocHandler := aAllocHandler;
  170. TvkuDeviceEx(result).fOwnsHandler := aOwnsHandler;
  171. except
  172. FreeAndNil(result);
  173. raise;
  174. end;
  175. end;
  176. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  177. constructor TvkuDeviceFactory.Create(const aInstance: TvkuInstance);
  178. begin
  179. Create(aInstance.InstanceCommands);
  180. end;
  181. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  182. constructor TvkuDeviceFactory.Create(const aInstanceCommands: TVkInstanceCommands);
  183. begin
  184. inherited Create;
  185. FillByte(fFeatures, SizeOf(fFeatures), 0);
  186. fInstanceCommands := aInstanceCommands;
  187. fLayers := TStringList.Create;
  188. fExtensions := TStringList.Create;
  189. end;
  190. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. destructor TvkuDeviceFactory.Destroy;
  192. begin
  193. FreeAndNil(fLayers);
  194. FreeAndNil(fExtensions);
  195. inherited Destroy;
  196. end;
  197. end.