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.

178 regels
6.8 KiB

  1. unit uvkuImage;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. Vulkan, uvkuBase;
  7. type
  8. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. TvkuImage = class(TvkuAllocHandle)
  10. private
  11. fHandle: VkImage;
  12. fDeviceCommands: TVkDeviceCommands;
  13. procedure CreateHandle(const aCreateInfo: TVkImageCreateInfo);
  14. public
  15. property Handle: VkImage read fHandle;
  16. property DeviceCommands: TVkDeviceCommands read fDeviceCommands;
  17. function GetMemoryBarrier(
  18. const aAspectMask: VkImageAspectFlags;
  19. const aOldLayout: TVkImageLayout;
  20. const aNewLayout: TVkImageLayout): TVkImageMemoryBarrier;
  21. constructor Create(
  22. const aCreateInfo: TVkImageCreateInfo;
  23. const aDeviceCommands: TVkDeviceCommands;
  24. const aAllocCallbacks: PVkAllocationCallbacks = nil);
  25. constructor Create(
  26. const aHandle: VkImage;
  27. const aOwnsHandle: Boolean;
  28. const aDeviceCommands: TVkDeviceCommands;
  29. const aAllocCallbacks: PVkAllocationCallbacks = nil);
  30. destructor Destroy; override;
  31. end;
  32. implementation
  33. uses
  34. uvkuUtils;
  35. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  36. //TvkuImage//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  37. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  38. procedure TvkuImage.CreateHandle(const aCreateInfo: TVkImageCreateInfo);
  39. var err: TVkResult;
  40. begin
  41. err := fDeviceCommands.vkCreateImage(fDeviceCommands.Device, @aCreateInfo, AllocCallbacks, @fHandle);
  42. if (err < VK_SUCCESS) then
  43. TvkuErrorException.Create('unable to create image', err);
  44. end;
  45. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. function TvkuImage.GetMemoryBarrier(
  47. const aAspectMask: VkImageAspectFlags;
  48. const aOldLayout: TVkImageLayout;
  49. const aNewLayout: TVkImageLayout): TVkImageMemoryBarrier;
  50. var
  51. range: TVkImageSubresourceRange;
  52. begin
  53. FillByte(range, SizeOf(range), 0);
  54. range.aspectMask := aAspectMask;
  55. range.baseMipLevel := 0;
  56. range.levelCount := 1;
  57. range.baseArrayLayer := 0;
  58. range.layerCount := 1;
  59. FillByte(result, SizeOf(result), 0);
  60. result.sType := VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
  61. result.pNext := nil;
  62. result.srcAccessMask := [];
  63. result.dstAccessMask := [];
  64. result.oldLayout := aOldLayout;
  65. result.newLayout := aNewLayout;
  66. result.srcQueueFamilyIndex := 0;
  67. result.dstQueueFamilyIndex := 0;
  68. result.image := fHandle;
  69. result.subresourceRange := range;
  70. case aOldLayout of
  71. // Undefined layout:
  72. // Note: Only allowed as initial layout!
  73. // Note: Make sure any writes to the image have been finished
  74. VK_IMAGE_LAYOUT_UNDEFINED: begin
  75. result.srcAccessMask := [ VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT ];
  76. end;
  77. // Old layout is color attachment:
  78. // Note: Make sure any writes to the color buffer have been finished
  79. VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: begin
  80. result.srcAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ];
  81. end;
  82. // Old layout is transfer source:
  83. // Note: Make sure any reads from the image have been finished
  84. VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: begin
  85. result.srcAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
  86. end;
  87. // Old layout is shader read (sampler, input attachment):
  88. // Note: Make sure any shader reads from the image have been finished
  89. VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: begin
  90. result.srcAccessMask := [ VK_ACCESS_SHADER_READ_BIT ];
  91. end;
  92. end;
  93. case aNewLayout of
  94. // New layout is transfer destination (copy, blit):
  95. // Note: Make sure any copyies to the image have been finished
  96. VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: begin
  97. result.dstAccessMask := [ VK_ACCESS_TRANSFER_WRITE_BIT ];
  98. end;
  99. // New layout is transfer source (copy, blit):
  100. // Note: Make sure any reads from and writes to the image have been finished
  101. VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: begin
  102. result.srcAccessMask := result.srcAccessMask + [ VK_ACCESS_TRANSFER_READ_BIT ];
  103. result.dstAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
  104. end;
  105. // New layout is color attachment:
  106. // Note: Make sure any writes to the color buffer hav been finished
  107. VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: begin
  108. result.dstAccessMask := [ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ];
  109. result.srcAccessMask := [ VK_ACCESS_TRANSFER_READ_BIT ];
  110. end;
  111. // New layout is depth attachment:
  112. // Note: Make sure any writes to depth/stencil buffer have been finished
  113. VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: begin
  114. result.dstAccessMask := result.dstAccessMask + [ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT ];
  115. end;
  116. // New layout is shader read (sampler, input attachment):
  117. // Note: Make sure any writes to the image have been finished
  118. VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: begin
  119. result.srcAccessMask := [ VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT ];
  120. result.dstAccessMask := [ VK_ACCESS_SHADER_READ_BIT ];
  121. end;
  122. end;
  123. end;
  124. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. constructor TvkuImage.Create(const aCreateInfo: TVkImageCreateInfo; const aDeviceCommands: TVkDeviceCommands;
  126. const aAllocCallbacks: PVkAllocationCallbacks);
  127. begin
  128. inherited Create;
  129. fDeviceCommands := aDeviceCommands;
  130. SetAllocCallbacks(aAllocCallbacks);
  131. CreateHandle(aCreateInfo);
  132. end;
  133. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  134. constructor TvkuImage.Create(const aHandle: VkImage; const aOwnsHandle: Boolean;
  135. const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks);
  136. begin
  137. inherited Create;
  138. fHandle := aHandle;
  139. fDeviceCommands := aDeviceCommands;
  140. OwnsHandle := aOwnsHandle;
  141. SetAllocCallbacks(aAllocCallbacks);
  142. end;
  143. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  144. destructor TvkuImage.Destroy;
  145. begin
  146. if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then
  147. fDeviceCommands.vkDestroyImage(fDeviceCommands.Device, fHandle, AllocCallbacks);
  148. fHandle := VK_INVALID_NDP_HANDLE;
  149. inherited Destroy;
  150. end;
  151. end.