Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

228 wiersze
9.6 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. fInstance: TvkuInstance;
  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. destructor Destroy; override;
  57. end;
  58. implementation
  59. uses
  60. uvkuUtils;
  61. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  62. //TvkuDeviceEx///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. destructor TvkuDeviceEx.Destroy;
  65. begin
  66. inherited Destroy;
  67. if fOwnsHandler then
  68. FreeAndNil(fAllocHandler);
  69. end;
  70. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. //TvkuDeviceFactory//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  72. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. function TvkuDeviceFactory.GetLayers: TStrings;
  74. begin
  75. result := fLayers;
  76. end;
  77. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  78. function TvkuDeviceFactory.GetExtensions: TStrings;
  79. begin
  80. result := fExtensions;
  81. end;
  82. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. function TvkuDeviceFactory.GetQueueCreateInfoCount: Integer;
  84. begin
  85. result := Length(fQueueCreateInfos);
  86. end;
  87. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. function TvkuDeviceFactory.GetQueueCreateInfo(const aIndex: Integer): TvkuQueueCreateInfo;
  89. begin
  90. if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
  91. raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
  92. result := fQueueCreateInfos[aIndex];
  93. end;
  94. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  95. function TvkuDeviceFactory.GetQueueCreateInfos: TvkuQueueCreateInfoArr;
  96. begin
  97. result := fQueueCreateInfos;
  98. end;
  99. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. procedure TvkuDeviceFactory.SetQueueCreateInfoCount(aValue: Integer);
  101. begin
  102. if (aValue < 0) then
  103. aValue := 0;
  104. SetLength(fQueueCreateInfos, aValue);
  105. end;
  106. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  107. procedure TvkuDeviceFactory.SetQueueCreateInfo(const aIndex: Integer; aValue: TvkuQueueCreateInfo);
  108. begin
  109. if (aIndex < low(fQueueCreateInfos)) or (aIndex > high(fQueueCreateInfos)) then
  110. raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fQueueCreateInfos), High(fQueueCreateInfos)]);
  111. fQueueCreateInfos[aIndex] := aValue;
  112. end;
  113. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  114. procedure TvkuDeviceFactory.SetQueueCreateInfos(aValue: TvkuQueueCreateInfoArr);
  115. begin
  116. fQueueCreateInfos := aValue;
  117. end;
  118. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice): TvkuDevice;
  120. begin
  121. result := CreateDevice(aPhysicalDevice, nil, false);
  122. end;
  123. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. function TvkuDeviceFactory.CreateDevice(const aPhysicalDevice: VkPhysicalDevice;
  125. const aAllocHandler: TvkuAllocationHandler; const aOwnsHandler: Boolean): TvkuDevice;
  126. var
  127. CreateInfo: TVkDeviceCreateInfo;
  128. QueueInfos: array of TVkDeviceQueueCreateInfo;
  129. lay: array of PVkChar;
  130. ext: array of PVkChar;
  131. i: Integer;
  132. prio: VkFloat;
  133. err: TVkResult;
  134. begin
  135. if (Length(fQueueCreateInfos) <= 0) then
  136. raise TvkuException.Create('no queue create infos assigned');
  137. SetLength(lay, fLayers.Count);
  138. for i := 0 to fLayers.Count-1 do
  139. lay[i] := PVkChar(fLayers[i]);
  140. SetLength(ext, fExtensions.Count);
  141. for i := 0 to fExtensions.Count-1 do
  142. ext[i] := PVkChar(fExtensions[i]);
  143. SetLength(QueueInfos, Length(fQueueCreateInfos));
  144. for i := 0 to high(fQueueCreateInfos) do begin
  145. FillByte(QueueInfos[i], SizeOf(QueueInfos[0]), 0);
  146. QueueInfos[i].sType := VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  147. QueueInfos[i].pNext := nil;
  148. QueueInfos[i].flags := fQueueCreateInfos[i].Flags;
  149. QueueInfos[i].queueFamilyIndex := fQueueCreateInfos[i].FamilyIndex;
  150. QueueInfos[i].queueCount := Length(fQueueCreateInfos[i].Priorities);
  151. if (QueueInfos[i].queueCount > 0)
  152. then QueueInfos[i].pQueuePriorities := @fQueueCreateInfos[i].Priorities[0]
  153. else QueueInfos[i].pQueuePriorities := nil;
  154. end;
  155. FillByte(CreateInfo, SizeOf(CreateInfo), 0);
  156. CreateInfo.sType := VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  157. CreateInfo.pNext := nil;
  158. CreateInfo.flags := fFlags;
  159. CreateInfo.queueCreateInfoCount := Length(QueueInfos);
  160. CreateInfo.pQueueCreateInfos := @QueueInfos[0];
  161. CreateInfo.enabledLayerCount := Length(lay);
  162. CreateInfo.ppEnabledLayerNames := @lay[0];
  163. CreateInfo.enabledExtensionCount := Length(ext);
  164. CreateInfo.ppEnabledExtensionNames := @ext[0];
  165. CreateInfo.pEnabledFeatures := @fFeatures;
  166. if Assigned(aAllocHandler)
  167. then result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstance.InstanceCommands, aAllocHandler.GetAllocationCallbacks)
  168. else result := TvkuDeviceEx.Create(aPhysicalDevice, CreateInfo, fInstance.InstanceCommands);
  169. try
  170. TvkuDeviceEx(result).fAllocHandler := aAllocHandler;
  171. TvkuDeviceEx(result).fOwnsHandler := aOwnsHandler;
  172. except
  173. FreeAndNil(result);
  174. raise;
  175. end;
  176. end;
  177. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. constructor TvkuDeviceFactory.Create(const aInstance: TvkuInstance);
  179. begin
  180. inherited Create;
  181. FillByte(fFeatures, SizeOf(fFeatures), 0);
  182. fInstance := aInstance;
  183. fLayers := TStringList.Create;
  184. fExtensions := TStringList.Create;
  185. end;
  186. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  187. destructor TvkuDeviceFactory.Destroy;
  188. begin
  189. FreeAndNil(fLayers);
  190. FreeAndNil(fExtensions);
  191. inherited Destroy;
  192. end;
  193. end.