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.

145 lines
5.4 KiB

  1. unit uvkuInstance;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. Vulkan, uvkuPhysicalDevice;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TvkuInstance = class(TObject)
  10. private
  11. fHandle: VkInstance;
  12. fAllocCallbacks: PVkAllocationCallbacks;
  13. fPhysicalDevices: array of TvkuPhysicalDevice;
  14. function GetPhysicalDeviceCount: Integer;
  15. function GetPhysicalDevices(const aIndex: Integer): TvkuPhysicalDevice;
  16. procedure UpdatePhysicalDevices;
  17. procedure ClearPhysicalDevices;
  18. protected
  19. procedure CreateHandle(aCreateInfo: PVkInstanceCreateInfo; aAllocCallbacks: PVkAllocationCallbacks);
  20. constructor Create;
  21. public
  22. property Handle: VkInstance read fHandle;
  23. property PhysicalDeviceCount: Integer read GetPhysicalDeviceCount;
  24. property PhysicalDevices[const aIndex: Integer]: TvkuPhysicalDevice read GetPhysicalDevices;
  25. constructor Create(const aCreateInfo: TVkInstanceCreateInfo);
  26. constructor Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks);
  27. destructor Destroy; override;
  28. end;
  29. implementation
  30. uses
  31. uvkuUtils;
  32. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  33. //TvkuInstance///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  34. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. function TvkuInstance.GetPhysicalDeviceCount: Integer;
  36. begin
  37. UpdatePhysicalDevices;
  38. result := Length(fPhysicalDevices);
  39. end;
  40. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. function TvkuInstance.GetPhysicalDevices(const aIndex: Integer): TvkuPhysicalDevice;
  42. begin
  43. UpdatePhysicalDevices;
  44. if (aIndex < Low(fPhysicalDevices)) or (aIndex > High(fPhysicalDevices)) then
  45. raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPhysicalDevices), High(fPhysicalDevices)]);
  46. result := fPhysicalDevices[aIndex];
  47. end;
  48. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. procedure TvkuInstance.UpdatePhysicalDevices;
  50. var
  51. i: Integer;
  52. c: VkUint32;
  53. arr: array of VkPhysicalDevice;
  54. err: TVkResult;
  55. begin
  56. if (Length(fPhysicalDevices) > 0) then
  57. exit;
  58. err := vkEnumeratePhysicalDevices(fHandle, @c, nil);
  59. if (err < VK_SUCCESS) then
  60. raise TvkuErrorException.Create('unable to get physical device number', err);
  61. SetLength(arr, c);
  62. err := vkEnumeratePhysicalDevices(fHandle, @c, @arr[0]);
  63. if (err < VK_SUCCESS) then
  64. raise TvkuErrorException.Create('unable to get physical devices', err);
  65. SetLength(fPhysicalDevices, c);
  66. for i := 0 to c-1 do
  67. fPhysicalDevices[i] := TvkuPhysicalDevice.Create(arr[i]);
  68. end;
  69. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. procedure TvkuInstance.ClearPhysicalDevices;
  71. var i: Integer;
  72. begin
  73. for i := low(fPhysicalDevices) to high(fPhysicalDevices) do
  74. FreeAndNil(fPhysicalDevices[i]);
  75. SetLength(fPhysicalDevices, 0);
  76. end;
  77. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  78. procedure TvkuInstance.CreateHandle(aCreateInfo: PVkInstanceCreateInfo; aAllocCallbacks: PVkAllocationCallbacks);
  79. var e: TVkResult;
  80. begin
  81. if Assigned(aAllocCallbacks) then begin
  82. new(fAllocCallbacks);
  83. fAllocCallbacks^ := aAllocCallbacks^;
  84. end;
  85. e := vkCreateInstance(aCreateInfo, fAllocCallbacks, @fHandle);
  86. if (e < VK_SUCCESS) then
  87. raise TvkuErrorException.Create('unable to create vulkan instance', e);
  88. end;
  89. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. constructor TvkuInstance.Create;
  91. begin
  92. inherited Create;
  93. fHandle := nil;
  94. fAllocCallbacks := nil;
  95. end;
  96. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo);
  98. begin
  99. Create;
  100. CreateHandle(@aCreateInfo, nil);
  101. end;
  102. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. constructor TvkuInstance.Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks);
  104. begin
  105. Create;
  106. CreateHandle(@aCreateInfo, @aAllocCallbacks);
  107. end;
  108. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. destructor TvkuInstance.Destroy;
  110. begin
  111. ClearPhysicalDevices;
  112. if Assigned(fHandle) then begin
  113. vkDestroyInstance(fHandle, fAllocCallbacks);
  114. fHandle := nil;
  115. end;
  116. if Assigned(fAllocCallbacks) then begin
  117. Dispose(fAllocCallbacks);
  118. fAllocCallbacks := nil;
  119. end;
  120. inherited Destroy;
  121. end;
  122. end.