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.
 
 

138 lines
5.2 KiB

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