unit uvkuDeviceMemory; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Vulkan, uvkuBase; type ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TvkuDeviceMemory = class(TvkuAllocHandle) private fHandle: VkDeviceMemory; fDeviceCommands: TVkDeviceCommands; procedure CreateHandle(const aAllocInfo: TVkMemoryAllocateInfo); public property Handle: VkDeviceMemory read fHandle; property DeviceCommands: TVkDeviceCommands read fDeviceCommands; function Map(const aOffset: VkDeviceSize; aSize: VkDeviceSize; aFlags: VkMemoryMapFlags): PVkVoid; procedure Unmap; constructor Create(const aAllocInfo: TVkMemoryAllocateInfo; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); constructor Create( const aHandle: VkDeviceMemory; const aOwnsHandle: Boolean; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks = nil); destructor Destroy; override; end; implementation uses uvkuUtils; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TvkuDeviceMemory/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDeviceMemory.CreateHandle(const aAllocInfo: TVkMemoryAllocateInfo); var err: TVkResult; begin if not Assigned(fDeviceCommands.vkAllocateMemory) then raise TvkuInvalidFuncPtrException.Create('vkAllocateMemory'); err := fDeviceCommands.vkAllocateMemory(fDeviceCommands.Device, @aAllocInfo, AllocCallbacks, @fHandle); if (err <> VK_SUCCESS) then raise TvkuErrorException.Create('unable to allocate device memory', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TvkuDeviceMemory.Map(const aOffset: VkDeviceSize; aSize: VkDeviceSize; aFlags: VkMemoryMapFlags): PVkVoid; var err: TVkResult; begin err := fDeviceCommands.vkMapMemory(fDeviceCommands.Device, fHandle, aOffset, aSize, aFlags, @result); if (err <> VK_SUCCESS) then raise TvkuErrorException.Create('unable to map device memory', err); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TvkuDeviceMemory.Unmap; begin fDeviceCommands.vkUnmapMemory(fDeviceCommands.Device, fHandle); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuDeviceMemory.Create(const aAllocInfo: TVkMemoryAllocateInfo; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fDeviceCommands := aDeviceCommands; SetAllocCallbacks(aAllocCallbacks); CreateHandle(aAllocInfo); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TvkuDeviceMemory.Create(const aHandle: VkDeviceMemory; const aOwnsHandle: Boolean; const aDeviceCommands: TVkDeviceCommands; const aAllocCallbacks: PVkAllocationCallbacks); begin inherited Create; fHandle := aHandle; fDeviceCommands := aDeviceCommands; OwnsHandle := aOwnsHandle; SetAllocCallbacks(aAllocCallbacks); end; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TvkuDeviceMemory.Destroy; begin if OwnsHandle and (fHandle <> VK_INVALID_NDP_HANDLE) then fDeviceCommands.vkFreeMemory(fDeviceCommands.Device, fHandle, AllocCallbacks); fHandle := VK_INVALID_NDP_HANDLE; inherited Destroy; end; end.