You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

243 lines
10 KiB

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