Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

215 rader
9.1 KiB

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