diff --git a/projects/triangle/triangle.lpr b/projects/triangle/triangle.lpr
index 9d6beeb..32c0b5a 100644
--- a/projects/triangle/triangle.lpr
+++ b/projects/triangle/triangle.lpr
@@ -1,12 +1,13 @@
program triangle;
{$mode objfpc}{$H+}
+{$APPTYPE CONSOLE}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
- Interfaces, Dialogs, Forms, uMainForm, Vulkan, uvkuInstance, uvkuUtils, uvkuInstanceEx, uvkuPhysicalDevice;
+ Interfaces, Dialogs, Forms, uMainForm, Vulkan;
{$R *.res}
diff --git a/projects/triangle/triangle.lps b/projects/triangle/triangle.lps
index 1ef1b0e..0cf8ed8 100644
--- a/projects/triangle/triangle.lps
+++ b/projects/triangle/triangle.lps
@@ -4,13 +4,14 @@
-
+
-
-
-
+
+
+
+
@@ -18,208 +19,216 @@
-
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
diff --git a/projects/triangle/uMainForm.pas b/projects/triangle/uMainForm.pas
index 5fcb45c..7fc4eae 100644
--- a/projects/triangle/uMainForm.pas
+++ b/projects/triangle/uMainForm.pas
@@ -6,15 +6,18 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
- Vulkan, uvkuInstanceEx;
+ Vulkan, uvkuInstanceEx, uvkuPhysicalDevice, uvkuUtils;
type
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TCustomAllocHandler = class(TvkuAllocationHandler)
protected
- procedure InternalAllocationNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
- procedure InternalFreeNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
+ function AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
+ function ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid; override;
+ procedure FreeMemory(const aMemory: PVkVoid); override;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
@@ -31,18 +34,40 @@ implementation
{$R *.lfm}
-procedure TCustomAllocHandler.InternalAllocationNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TCustomAllocHandler////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TCustomAllocHandler.AllocateMemory(const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
begin
- inherited InternalAllocationNotification(aSize, aType, aScope);
+ result := inherited AllocateMemory(aSize, aAlignment, aScope);
+ WriteLn(Format('%d bytes of memory allocated at %p', [ aSize, result ]));
end;
-procedure TCustomAllocHandler.InternalFreeNotification(const aSize: VkSize; const aType: TVkInternalAllocationType; const aScope: TVkSystemAllocationScope);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TCustomAllocHandler.ReallocateMemory(const aOriginal: PVkVoid; const aSize: VkSize; const aAlignment: VkSize; const aScope: TVkSystemAllocationScope): PVkVoid;
+var p: PVkVoid;
begin
- inherited InternalFreeNotification(aSize, aType, aScope);
+ p := aOriginal;
+ result := inherited ReallocateMemory(aOriginal, aSize, aAlignment, aScope);
+ WriteLn(Format('%d bytes of memory (from %p) reallocated at %p', [ aSize, p, result ]));
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TCustomAllocHandler.FreeMemory(const aMemory: PVkVoid);
+begin
+ WriteLn(Format('free memory at %p', [ aMemory ]));
+ inherited FreeMemory(aMemory);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TMainForm//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormCreate(Sender: TObject);
+var
+ i: Integer;
+ d: TvkuPhysicalDevice;
begin
+ WriteLn('create vulkan instance');
fIntance := TvkuInstanceEx.Create(
0,
[],
@@ -50,8 +75,17 @@ begin
TvkuInstanceEx.DefaultApplicationInfo,
TvkuAllocationHandler.Create,
true);
+
+ WriteLn('read vulkan devices:');
+ for i := 0 to fIntance.PhysicalDeviceCount-1 do begin
+ d := fIntance.PhysicalDevices[i];
+ WriteLn(vkuMakeString(d.GetFeatures, ', '));
+ WriteLn(vkuMakeString(d.GetProperties, true, true));
+ WriteLn(vkuMakeString(d.GetMemoryProperties));
+ end;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormDestroy(Sender: TObject);
begin
FreeAndNil(fIntance);
diff --git a/projects/utils/uvkuInstance.pas b/projects/utils/uvkuInstance.pas
index 1ef5e06..630770f 100644
--- a/projects/utils/uvkuInstance.pas
+++ b/projects/utils/uvkuInstance.pas
@@ -5,7 +5,8 @@ unit uvkuInstance;
interface
uses
- Classes, SysUtils, Vulkan;
+ Classes, SysUtils,
+ Vulkan, uvkuPhysicalDevice;
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -13,17 +14,19 @@ type
private
fHandle: VkInstance;
fAllocCallbacks: PVkAllocationCallbacks;
- fPhysicalDevices: array of VkPhysicalDevice;
+ fPhysicalDevices: array of TvkuPhysicalDevice;
function GetPhysicalDeviceCount: Integer;
- function GetPhysicalDevices(const aIndex: Integer): VkPhysicalDevice;
+ function GetPhysicalDevices(const aIndex: Integer): TvkuPhysicalDevice;
procedure UpdatePhysicalDevices;
+ procedure ClearPhysicalDevices;
protected
procedure CreateHandle(aCreateInfo: PVkInstanceCreateInfo; aAllocCallbacks: PVkAllocationCallbacks);
constructor Create;
public
- property PhysicalDeviceCount: Integer read GetPhysicalDeviceCount;
- property PhysicalDevices[const aIndex: Integer]: VkPhysicalDevice read GetPhysicalDevices;
+ property Handle: VkInstance read fHandle;
+ property PhysicalDeviceCount: Integer read GetPhysicalDeviceCount;
+ property PhysicalDevices[const aIndex: Integer]: TvkuPhysicalDevice read GetPhysicalDevices;
constructor Create(const aCreateInfo: TVkInstanceCreateInfo);
constructor Create(const aCreateInfo: TVkInstanceCreateInfo; const aAllocCallbacks: TVkAllocationCallbacks);
@@ -45,18 +48,20 @@ begin
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuInstance.GetPhysicalDevices(const aIndex: Integer): VkPhysicalDevice;
+function TvkuInstance.GetPhysicalDevices(const aIndex: Integer): TvkuPhysicalDevice;
begin
UpdatePhysicalDevices;
if (aIndex < Low(fPhysicalDevices)) or (aIndex > High(fPhysicalDevices)) then
- raise TvkuException.CreateFmt('index (%d) out of range (%d-%d)', [aIndex, Low(fPhysicalDevices), High(fPhysicalDevices)]);
+ raise TvkuException.CreateFmt('index (%d) out of range (%d : %d)', [aIndex, Low(fPhysicalDevices), High(fPhysicalDevices)]);
result := fPhysicalDevices[aIndex];
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TvkuInstance.UpdatePhysicalDevices;
var
+ i: Integer;
c: VkUint32;
+ arr: array of VkPhysicalDevice;
err: TVkResult;
begin
if (Length(fPhysicalDevices) > 0) then
@@ -65,11 +70,24 @@ begin
err := vkEnumeratePhysicalDevices(fHandle, @c, nil);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical device number', err);
- SetLength(fPhysicalDevices, c);
+ SetLength(arr, c);
- err := vkEnumeratePhysicalDevices(fHandle, @c, @fPhysicalDevices[0]);
+ err := vkEnumeratePhysicalDevices(fHandle, @c, @arr[0]);
if (err < VK_SUCCESS) then
raise TvkuErrorException.Create('unable to get physical devices', err);
+
+ SetLength(fPhysicalDevices, c);
+ for i := 0 to c-1 do
+ fPhysicalDevices[i] := TvkuPhysicalDevice.Create(arr[i]);
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TvkuInstance.ClearPhysicalDevices;
+var i: Integer;
+begin
+ for i := low(fPhysicalDevices) to high(fPhysicalDevices) do
+ FreeAndNil(fPhysicalDevices[i]);
+ SetLength(fPhysicalDevices, 0);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -110,6 +128,7 @@ end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TvkuInstance.Destroy;
begin
+ ClearPhysicalDevices;
if Assigned(fHandle) then begin
vkDestroyInstance(fHandle, fAllocCallbacks);
fHandle := nil;
diff --git a/projects/utils/uvkuPhysicalDevice.pas b/projects/utils/uvkuPhysicalDevice.pas
index f2333e3..cf86195 100644
--- a/projects/utils/uvkuPhysicalDevice.pas
+++ b/projects/utils/uvkuPhysicalDevice.pas
@@ -10,54 +10,41 @@ uses
type
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TVkQueueFamilyPropertiesArr = array of TVkQueueFamilyProperties;
TVkSparseImageFormatPropertiesArr = array of TVkSparseImageFormatProperties;
TvkuPhysicalDevice = class(TObject)
- private type
- TPropertyFlag = (
- pfFeatures,
- pfProperties,
- pfMemoryProperties
- );
- TPropertyFlags = set of TPropertyFlag;
private
fHandle: VkPhysicalDevice;
- fCached: TPropertyFlags;
-
- fFeatures: TVkPhysicalDeviceFeatures;
- fProperties: TVkPhysicalDeviceProperties;
- fMemoryProperties: TVkPhysicalDeviceMemoryProperties;
- fFormatProperties: array[TVkFormat] of PVkFormatProperties;
-
+ function GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties;
+ function GetQueueFamilyPropertyCount: Integer;
+ public
function GetFeatures: TVkPhysicalDeviceFeatures;
function GetProperties: TVkPhysicalDeviceProperties;
function GetMemoryProperties: TVkPhysicalDeviceMemoryProperties;
- function GetQueueFamilyPropertyCount: Integer;
- function GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties;
+ function GetQueueFamilyProperties: TVkQueueFamilyPropertiesArr;
function GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties;
- public
- property Handle: VkPhysicalDevice read fHandle;
- property Features: TVkPhysicalDeviceFeatures read GetFeatures;
- property Properties: TVkPhysicalDeviceProperties read GetProperties;
- property MemoryProperties: TVkPhysicalDeviceMemoryProperties read GetMemoryProperties;
-
- property QueueFamilyPropertyCount: Integer read GetQueueFamilyPropertyCount;
- property QueueFamilyProperties[const aIndex: Integer]: TVkQueueFamilyProperties read GetQueueFamilyProperties;
-
- property FormatProperties[const aFormat: TVkFormat]: TVkFormatProperties read GetFormatProperties;
-
function GetImageFormatProperties(
const aFormat: TVkFormat;
const aImageType: TVkImageType;
const aTiling: TVkImageTiling;
const aUsage: VkImageUsageFlags;
const aFlags: VkImageCreateFlags): TVkImageFormatProperties;
-
function GetSparseImageFormatProperties(
const aFormat: TVkFormat;
const aImageType: TVkImageType;
const aSamples: TVkSampleCountFlagBits;
const aUsage: VkImageUsageFlags;
const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr;
+ public
+ property Handle: VkPhysicalDevice read fHandle;
+ property Features: TVkPhysicalDeviceFeatures read GetFeatures;
+ property Properties: TVkPhysicalDeviceProperties read GetProperties;
+ property MemoryProperties: TVkPhysicalDeviceMemoryProperties read GetMemoryProperties;
+
+ property QueueFamilyPropertyCount: Integer read GetQueueFamilyPropertyCount;
+ property QueueFamilyProperties[const aIndex: Integer]: TVkQueueFamilyProperties read GetQueueFamilyProperties;
+
+ property FormatProperties[const aFormat: TVkFormat]: TVkFormatProperties read GetFormatProperties;
constructor Create(const aHandle: VkPhysicalDevice);
end;
@@ -70,65 +57,72 @@ uses
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TvkuPhysicalDevice/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDevice.GetFeatures: TVkPhysicalDeviceFeatures;
+function TvkuPhysicalDevice.GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties;
+var arr: TVkQueueFamilyPropertiesArr;
begin
- if not (pfFeatures in fCached) then begin
- vkGetPhysicalDeviceFeatures(fHandle, @fFeatures);
- Include(fCached, pfFeatures);
- end;
- result := fFeatures;
+ arr := GetQueueFamilyProperties();
+ if (aIndex < Low(arr)) or (aIndex > High(arr)) then
+ raise TvkuException.CreateFmt('index (%) out of range (%d : %d)', [aIndex, Low(arr), High(arr)]);
+ result := arr[aIndex];
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDevice.GetProperties: TVkPhysicalDeviceProperties;
+function TvkuPhysicalDevice.GetQueueFamilyPropertyCount: Integer;
begin
- if not (pfProperties in fCached) then begin
- vkGetPhysicalDeviceProperties(fHandle, @fProperties);
- Include(fCached, pfProperties);
- end;
- result := fProperties;
+ result := Length(GetQueueFamilyProperties);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDevice.GetMemoryProperties: TVkPhysicalDeviceMemoryProperties;
+function TvkuPhysicalDevice.GetFeatures: TVkPhysicalDeviceFeatures;
begin
- if not (pfMemoryProperties in fCached) then begin
- vkGetPhysicalDeviceMemoryProperties(fHandle, @fMemoryProperties);
- Include(fCached, pfMemoryProperties);
- end;
- result := fMemoryProperties;
+ vkGetPhysicalDeviceFeatures(fHandle, @result);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDevice.GetQueueFamilyPropertyCount: Integer;
+function TvkuPhysicalDevice.GetProperties: TVkPhysicalDeviceProperties;
begin
-
+ vkGetPhysicalDeviceProperties(fHandle, @result);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TvkuPhysicalDevice.GetQueueFamilyProperties(const aIndex: Integer): TVkQueueFamilyProperties;
+function TvkuPhysicalDevice.GetMemoryProperties: TVkPhysicalDeviceMemoryProperties;
begin
+ vkGetPhysicalDeviceMemoryProperties(fHandle, @result);
+end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TvkuPhysicalDevice.GetQueueFamilyProperties: TVkQueueFamilyPropertiesArr;
+var c: VkUint32;
+begin
+ vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, nil);
+ SetLength(result, c);
+ vkGetPhysicalDeviceQueueFamilyProperties(fHandle, @c, @result[0]);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetFormatProperties(const aFormat: TVkFormat): TVkFormatProperties;
begin
-
+ vkGetPhysicalDeviceFormatProperties(fHandle, aFormat, @result);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetImageFormatProperties(const aFormat: TVkFormat; const aImageType: TVkImageType;
const aTiling: TVkImageTiling; const aUsage: VkImageUsageFlags; const aFlags: VkImageCreateFlags): TVkImageFormatProperties;
+var err: TVkResult;
begin
-
+ err := vkGetPhysicalDeviceImageFormatProperties(fHandle, aFormat, aImageType, aTiling, aUsage, aFlags, @result);
+ if (err < VK_SUCCESS) then
+ raise TvkuErrorException.Create('unable to get physical device image format properties', err);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TvkuPhysicalDevice.GetSparseImageFormatProperties(const aFormat: TVkFormat; const aImageType: TVkImageType;
const aSamples: TVkSampleCountFlagBits; const aUsage: VkImageUsageFlags; const aTiling: TVkImageTiling): TVkSparseImageFormatPropertiesArr;
+var c: VkUint32;
begin
-
+ vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, nil);
+ SetLength(result, c);
+ vkGetPhysicalDeviceSparseImageFormatProperties(fHandle, aFormat, aImageType, aSamples, aUsage, aTiling, @c, @result[0]);
end;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/projects/utils/uvkuUtils.pas b/projects/utils/uvkuUtils.pas
index 38d1c55..259a888 100644
--- a/projects/utils/uvkuUtils.pas
+++ b/projects/utils/uvkuUtils.pas
@@ -19,6 +19,10 @@ type
constructor Create(const msg: string; const aError: TVkResult);
end;
+function vkuMakeString(const aFeatures: TVkPhysicalDeviceFeatures; const aSeperator: String = sLineBreak): String;
+function vkuMakeString(const aProperties: TVkPhysicalDeviceProperties; const aPrintLimits, aPrintSparseProps: Boolean): String;
+function vkuMakeString(const aMemoryProperties: TVkPhysicalDeviceMemoryProperties): String;
+
implementation
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -30,5 +34,420 @@ begin
fError := aError;
end;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function vkuMakeString(const aFeatures: TVkPhysicalDeviceFeatures; const aSeperator: String): String;
+
+ procedure AddToResult(const b: VkBool32; const aName: String);
+ begin
+ if (b = 0) then
+ exit;
+ if (result <> '') then
+ result := result + aSeperator;
+ result := result + aName;
+ end;
+
+begin
+ result := '';
+ AddToResult(aFeatures.robustBufferAccess, 'RobustBufferAccess');
+ AddToResult(aFeatures.fullDrawIndexUint32, 'FullDrawIndexUint32');
+ AddToResult(aFeatures.imageCubeArray, 'ImageCubeArray');
+ AddToResult(aFeatures.independentBlend, 'IndependentBlend');
+ AddToResult(aFeatures.geometryShader, 'GeometryShader');
+ AddToResult(aFeatures.tessellationShader, 'TessellationShader');
+ AddToResult(aFeatures.sampleRateShading, 'SampleRateShading');
+ AddToResult(aFeatures.dualSrcBlend, 'DualSrcBlend');
+ AddToResult(aFeatures.logicOp, 'LogicOp');
+ AddToResult(aFeatures.multiDrawIndirect, 'MultiDrawIndirect');
+ AddToResult(aFeatures.drawIndirectFirstInstance, 'DrawIndirectFirstInstance');
+ AddToResult(aFeatures.depthClamp, 'DepthClamp');
+ AddToResult(aFeatures.depthBiasClamp, 'DepthBiasClamp');
+ AddToResult(aFeatures.fillModeNonSolid, 'FillModeNonSolid');
+ AddToResult(aFeatures.depthBounds, 'DepthBounds');
+ AddToResult(aFeatures.wideLines, 'WideLines');
+ AddToResult(aFeatures.largePoints, 'LargePoints');
+ AddToResult(aFeatures.alphaToOne, 'AlphaToOne');
+ AddToResult(aFeatures.multiViewport, 'MultiViewport');
+ AddToResult(aFeatures.samplerAnisotropy, 'SamplerAnisotropy');
+ AddToResult(aFeatures.textureCompressionETC2, 'TextureCompressionETC2');
+ AddToResult(aFeatures.textureCompressionASTC_LDR, 'TextureCompressionASTC_LDR');
+ AddToResult(aFeatures.textureCompressionBC, 'TextureCompressionBC');
+ AddToResult(aFeatures.occlusionQueryPrecise, 'OcclusionQueryPrecise');
+ AddToResult(aFeatures.pipelineStatisticsQuery, 'PipelineStatisticsQuery');
+ AddToResult(aFeatures.vertexPipelineStoresAndAtomics, 'VertexPipelineStoresAndAtomics');
+ AddToResult(aFeatures.fragmentStoresAndAtomics, 'FragmentStoresAndAtomics');
+ AddToResult(aFeatures.shaderTessellationAndGeometryPointSize, 'ShaderTessellationAndGeometryPointSize');
+ AddToResult(aFeatures.shaderImageGatherExtended, 'ShaderImageGatherExtended');
+ AddToResult(aFeatures.shaderStorageImageExtendedFormats, 'ShaderStorageImageExtendedFormats');
+ AddToResult(aFeatures.shaderStorageImageMultisample, 'ShaderStorageImageMultisample');
+ AddToResult(aFeatures.shaderStorageImageReadWithoutFormat, 'ShaderStorageImageReadWithoutFormat');
+ AddToResult(aFeatures.shaderStorageImageWriteWithoutFormat, 'ShaderStorageImageWriteWithoutFormat');
+ AddToResult(aFeatures.shaderUniformBufferArrayDynamicIndexing, 'ShaderUniformBufferArrayDynamicIndexing');
+ AddToResult(aFeatures.shaderSampledImageArrayDynamicIndexing, 'ShaderSampledImageArrayDynamicIndexing');
+ AddToResult(aFeatures.shaderStorageBufferArrayDynamicIndexing, 'ShaderStorageBufferArrayDynamicIndexing');
+ AddToResult(aFeatures.shaderStorageImageArrayDynamicIndexing, 'ShaderStorageImageArrayDynamicIndexing');
+ AddToResult(aFeatures.shaderClipDistance, 'ShaderClipDistance');
+ AddToResult(aFeatures.shaderCullDistance, 'ShaderCullDistance');
+ AddToResult(aFeatures.shaderFloat64, 'ShaderFloat64');
+ AddToResult(aFeatures.shaderInt64, 'ShaderInt64');
+ AddToResult(aFeatures.shaderInt16, 'ShaderInt16');
+ AddToResult(aFeatures.shaderResourceResidency, 'ShaderResourceResidency');
+ AddToResult(aFeatures.shaderResourceMinLod, 'ShaderResourceMinLod');
+ AddToResult(aFeatures.sparseBinding, 'SparseBinding');
+ AddToResult(aFeatures.sparseResidencyBuffer, 'SparseResidencyBuffer');
+ AddToResult(aFeatures.sparseResidencyImage2D, 'SparseResidencyImage2D');
+ AddToResult(aFeatures.sparseResidencyImage3D, 'SparseResidencyImage3D');
+ AddToResult(aFeatures.sparseResidency2Samples, 'SparseResidency2Samples');
+ AddToResult(aFeatures.sparseResidency4Samples, 'SparseResidency4Samples');
+ AddToResult(aFeatures.sparseResidency8Samples, 'SparseResidency8Samples');
+ AddToResult(aFeatures.sparseResidency16Samples, 'SparseResidency16Samples');
+ AddToResult(aFeatures.sparseResidencyAliased, 'SparseResidencyAliased');
+ AddToResult(aFeatures.variableMultisampleRate, 'VariableMultisampleRate');
+ AddToResult(aFeatures.inheritedQueries, 'InheritedQueries');
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function vkuMakeString(const aProperties: TVkPhysicalDeviceProperties; const aPrintLimits,
+ aPrintSparseProps: Boolean): String;
+
+ function UUIDtoStr: String;
+ var i: Integer;
+ begin
+ result := '';
+ for i := low(aProperties.pipelineCacheUUID) to High(aProperties.pipelineCacheUUID) do begin
+ if (result <> '') then
+ result := result + ':';
+ result := result + IntToHex(aProperties.pipelineCacheUUID[i], 2);
+ end;
+ end;
+
+ function toString(const i: Int64): String;
+ begin
+ result := IntToStr(i);
+ end;
+
+ function toString(const e: Extended): String;
+ begin
+ result := Format('%.3f', [e]);
+ end;
+
+ function toString(const arr: array of VkUint32): String;
+ var i: Integer;
+ begin
+ result := '';
+ for i := low(arr) to high(arr) do begin
+ if (i <> low(arr)) then
+ result := result + '; ';
+ result := result + toString(arr[i]);
+ end;
+ end;
+
+ function toString(const arr: array of VkFloat): String;
+ var i: Integer;
+ begin
+ result := '';
+ for i := low(arr) to high(arr) do begin
+ if (i <> low(arr)) then
+ result := result + '; ';
+ result := result + toString(arr[i]);
+ end;
+ end;
+
+ function toString(const aType: TVkPhysicalDeviceType): String;
+ begin
+ case aType of
+ VK_PHYSICAL_DEVICE_TYPE_OTHER: result := 'Other';
+ VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: result := 'IntegratedGPU';
+ VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: result := 'DiscreteGPU';
+ VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: result := 'VirtualGPU';
+ VK_PHYSICAL_DEVICE_TYPE_CPU: result := 'CPU';
+ else
+ result := 'Unknown';
+ end;
+ end;
+
+ function toString(const aChar: PVkChar): String;
+ begin
+ result := String(aChar);
+ end;
+
+begin
+ result := Format(
+ 'ApiVersion: %x (v%d.%d.%d)' + sLineBreak +
+ 'DriverVersion: %s' + sLineBreak +
+ 'VendorID: %s' + sLineBreak +
+ 'DeviceID: %s' + sLineBreak +
+ 'DeviceType: %s' + sLineBreak +
+ 'deviceName: %s' + sLineBreak +
+ 'PipelineCacheUUID: %s' + sLineBreak
+ ,[
+ aProperties.apiVersion, vkGetVersionMajor(aProperties.apiVersion), vkGetVersionMinor(aProperties.apiVersion), vkgetVersionPatch(aProperties.apiVersion),
+ toString(aProperties.driverVersion),
+ toString(aProperties.vendorID),
+ toString(aProperties.deviceID),
+ toString(aProperties.deviceType),
+ toString(@aProperties.deviceName[0]),
+ UUIDtoStr
+ ]);
+ if aPrintLimits then begin
+ result := result + Format(
+ 'Limits:' + sLineBreak +
+ ' MaxImageDimension1D: %s' + sLineBreak +
+ ' MaxImageDimension2D: %s' + sLineBreak +
+ ' MaxImageDimension3D: %s' + sLineBreak +
+ ' MaxImageDimensionCube: %s' + sLineBreak +
+ ' MaxImageArrayLayers: %s' + sLineBreak +
+ ' MaxTexelBufferElements: %s' + sLineBreak +
+ ' MaxUniformBufferRange: %s' + sLineBreak +
+ ' MaxStorageBufferRange: %s' + sLineBreak +
+ ' MaxPushConstantsSize: %s' + sLineBreak +
+ ' MaxMemoryAllocationCount: %s' + sLineBreak +
+ ' MaxSamplerAllocationCount: %s' + sLineBreak +
+ ' BufferImageGranularity: %s' + sLineBreak +
+ ' SparseAddressSpaceSize: %s' + sLineBreak +
+ ' MaxBoundDescriptorSets: %s' + sLineBreak +
+ ' MaxPerStageDescriptorSamplers: %s' + sLineBreak +
+ ' MaxPerStageDescriptorUniformBuffers: %s' + sLineBreak +
+ ' MaxPerStageDescriptorStorageBuffers: %s' + sLineBreak +
+ ' MaxPerStageDescriptorSampledImages: %s' + sLineBreak +
+ ' MaxPerStageDescriptorStorageImages: %s' + sLineBreak +
+ ' MaxPerStageDescriptorInputAttachments: %s' + sLineBreak +
+ ' MaxPerStageResources: %s' + sLineBreak +
+ ' MaxDescriptorSetSamplers: %s' + sLineBreak +
+ ' MaxDescriptorSetUniformBuffers: %s' + sLineBreak +
+ ' MaxDescriptorSetUniformBuffersDynamic: %s' + sLineBreak +
+ ' MaxDescriptorSetStorageBuffers: %s' + sLineBreak +
+ ' MaxDescriptorSetStorageBuffersDynamic: %s' + sLineBreak +
+ ' MaxDescriptorSetSampledImages: %s' + sLineBreak +
+ ' MaxDescriptorSetStorageImages: %s' + sLineBreak +
+ ' MaxDescriptorSetInputAttachments: %s' + sLineBreak +
+ ' MaxVertexInputAttributes: %s' + sLineBreak +
+ ' MaxVertexInputBindings: %s' + sLineBreak +
+ ' MaxVertexInputAttributeOffset: %s' + sLineBreak +
+ ' MaxVertexInputBindingStride: %s' + sLineBreak +
+ ' MaxVertexOutputComponents: %s' + sLineBreak +
+ ' MaxTessellationGenerationLevel: %s' + sLineBreak +
+ ' MaxTessellationPatchSize: %s' + sLineBreak +
+ ' MaxTessellationControlPerVertexInputComponents: %s' + sLineBreak +
+ ' MaxTessellationControlPerVertexOutputComponents: %s' + sLineBreak +
+ ' MaxTessellationControlPerPatchOutputComponents: %s' + sLineBreak +
+ ' MaxTessellationControlTotalOutputComponents: %s' + sLineBreak +
+ ' MaxTessellationEvaluationInputComponents: %s' + sLineBreak +
+ ' MaxTessellationEvaluationOutputComponents: %s' + sLineBreak +
+ ' MaxGeometryShaderInvocations: %s' + sLineBreak +
+ ' MaxGeometryInputComponents: %s' + sLineBreak +
+ ' MaxGeometryOutputComponents: %s' + sLineBreak +
+ ' MaxGeometryOutputVertices: %s' + sLineBreak +
+ ' MaxGeometryTotalOutputComponents: %s' + sLineBreak +
+ ' MaxFragmentInputComponents: %s' + sLineBreak +
+ ' MaxFragmentOutputAttachments: %s' + sLineBreak +
+ ' MaxFragmentDualSrcAttachments: %s' + sLineBreak +
+ ' MaxFragmentCombinedOutputResources: %s' + sLineBreak +
+ ' MaxComputeSharedMemorySize: %s' + sLineBreak +
+ ' MaxComputeWorkGroupCount: %s' + sLineBreak +
+ ' MaxComputeWorkGroupInvocations: %s' + sLineBreak +
+ ' MaxComputeWorkGroupSize: %s' + sLineBreak +
+ ' SubPixelPrecisionBits: %s' + sLineBreak +
+ ' SubTexelPrecisionBits: %s' + sLineBreak +
+ ' MipmapPrecisionBits: %s' + sLineBreak +
+ ' MaxDrawIndexedIndexValue: %s' + sLineBreak +
+ ' MaxDrawIndirectCount: %s' + sLineBreak +
+ ' MaxSamplerLodBias: %s' + sLineBreak +
+ ' MaxSamplerAnisotropy: %s' + sLineBreak +
+ ' MaxViewports: %s' + sLineBreak +
+ ' MaxViewportDimensions: %s' + sLineBreak +
+ ' ViewportBoundsRange: %s' + sLineBreak +
+ ' ViewportSubPixelBits: %s' + sLineBreak +
+ ' MinMemoryMapAlignment: %s' + sLineBreak +
+ ' MinTexelBufferOffsetAlignment: %s' + sLineBreak +
+ ' MinUniformBufferOffsetAlignment: %s' + sLineBreak +
+ ' MinStorageBufferOffsetAlignment: %s' + sLineBreak +
+ ' MinTexelOffset: %s' + sLineBreak +
+ ' MaxTexelOffset: %s' + sLineBreak +
+ ' MinTexelGatherOffset: %s' + sLineBreak +
+ ' MaxTexelGatherOffset: %s' + sLineBreak +
+ ' MinInterpolationOffset: %s' + sLineBreak +
+ ' MaxInterpolationOffset: %s' + sLineBreak +
+ ' SubPixelInterpolationOffsetBits: %s' + sLineBreak +
+ ' MaxFramebufferWidth: %s' + sLineBreak +
+ ' MaxFramebufferHeight: %s' + sLineBreak +
+ ' MaxFramebufferLayers: %s' + sLineBreak +
+ ' FramebufferColorSampleCounts: %s' + sLineBreak +
+ ' FramebufferDepthSampleCounts: %s' + sLineBreak +
+ ' FramebufferStencilSampleCounts: %s' + sLineBreak +
+ ' FramebufferNoAttachmentsSampleCounts: %s' + sLineBreak +
+ ' MaxColorAttachments: %s' + sLineBreak +
+ ' SampledImageColorSampleCounts: %s' + sLineBreak +
+ ' SampledImageIntegerSampleCounts: %s' + sLineBreak +
+ ' SampledImageDepthSampleCounts: %s' + sLineBreak +
+ ' SampledImageStencilSampleCounts: %s' + sLineBreak +
+ ' StorageImageSampleCounts: %s' + sLineBreak +
+ ' MaxSampleMaskWords: %s' + sLineBreak +
+ ' TimestampComputeAndGraphics: %s' + sLineBreak +
+ ' TimestampPeriod: %s' + sLineBreak +
+ ' MaxClipDistances: %s' + sLineBreak +
+ ' MaxCullDistances: %s' + sLineBreak +
+ ' MaxCombinedClipAndCullDistances: %s' + sLineBreak +
+ ' DiscreteQueuePriorities: %s' + sLineBreak +
+ ' PointSizeRange: %s' + sLineBreak +
+ ' LineWidthRange: %s' + sLineBreak +
+ ' PointSizeGranularity: %s' + sLineBreak +
+ ' LineWidthGranularity: %s' + sLineBreak +
+ ' StrictLines: %s' + sLineBreak +
+ ' StandardSampleLocations: %s' + sLineBreak +
+ ' OptimalBufferCopyOffsetAlignment: %s' + sLineBreak +
+ ' OptimalBufferCopyRowPitchAlignment: %s' + sLineBreak +
+ ' NonCoherentAtomSize: %s' + sLineBreak
+ ,[
+ toString(aProperties.limits.maxImageDimension1D),
+ toString(aProperties.limits.maxImageDimension2D),
+ toString(aProperties.limits.maxImageDimension3D),
+ toString(aProperties.limits.maxImageDimensionCube),
+ toString(aProperties.limits.maxImageArrayLayers),
+ toString(aProperties.limits.maxTexelBufferElements),
+ toString(aProperties.limits.maxUniformBufferRange),
+ toString(aProperties.limits.maxStorageBufferRange),
+ toString(aProperties.limits.maxPushConstantsSize),
+ toString(aProperties.limits.maxMemoryAllocationCount),
+ toString(aProperties.limits.maxSamplerAllocationCount),
+ toString(aProperties.limits.bufferImageGranularity),
+ toString(aProperties.limits.sparseAddressSpaceSize),
+ toString(aProperties.limits.maxBoundDescriptorSets),
+ toString(aProperties.limits.maxPerStageDescriptorSamplers),
+ toString(aProperties.limits.maxPerStageDescriptorUniformBuffers),
+ toString(aProperties.limits.maxPerStageDescriptorStorageBuffers),
+ toString(aProperties.limits.maxPerStageDescriptorSampledImages),
+ toString(aProperties.limits.maxPerStageDescriptorStorageImages),
+ toString(aProperties.limits.maxPerStageDescriptorInputAttachments),
+ toString(aProperties.limits.maxPerStageResources),
+ toString(aProperties.limits.maxDescriptorSetSamplers),
+ toString(aProperties.limits.maxDescriptorSetUniformBuffers),
+ toString(aProperties.limits.maxDescriptorSetUniformBuffersDynamic),
+ toString(aProperties.limits.maxDescriptorSetStorageBuffers),
+ toString(aProperties.limits.maxDescriptorSetStorageBuffersDynamic),
+ toString(aProperties.limits.maxDescriptorSetSampledImages),
+ toString(aProperties.limits.maxDescriptorSetStorageImages),
+ toString(aProperties.limits.maxDescriptorSetInputAttachments),
+ toString(aProperties.limits.maxVertexInputAttributes),
+ toString(aProperties.limits.maxVertexInputBindings),
+ toString(aProperties.limits.maxVertexInputAttributeOffset),
+ toString(aProperties.limits.maxVertexInputBindingStride),
+ toString(aProperties.limits.maxVertexOutputComponents),
+ toString(aProperties.limits.maxTessellationGenerationLevel),
+ toString(aProperties.limits.maxTessellationPatchSize),
+ toString(aProperties.limits.maxTessellationControlPerVertexInputComponents),
+ toString(aProperties.limits.maxTessellationControlPerVertexOutputComponents),
+ toString(aProperties.limits.maxTessellationControlPerPatchOutputComponents),
+ toString(aProperties.limits.maxTessellationControlTotalOutputComponents),
+ toString(aProperties.limits.maxTessellationEvaluationInputComponents),
+ toString(aProperties.limits.maxTessellationEvaluationOutputComponents),
+ toString(aProperties.limits.maxGeometryShaderInvocations),
+ toString(aProperties.limits.maxGeometryInputComponents),
+ toString(aProperties.limits.maxGeometryOutputComponents),
+ toString(aProperties.limits.maxGeometryOutputVertices),
+ toString(aProperties.limits.maxGeometryTotalOutputComponents),
+ toString(aProperties.limits.maxFragmentInputComponents),
+ toString(aProperties.limits.maxFragmentOutputAttachments),
+ toString(aProperties.limits.maxFragmentDualSrcAttachments),
+ toString(aProperties.limits.maxFragmentCombinedOutputResources),
+ toString(aProperties.limits.maxComputeSharedMemorySize),
+ toString(aProperties.limits.maxComputeWorkGroupCount),
+ toString(aProperties.limits.maxComputeWorkGroupInvocations),
+ toString(aProperties.limits.maxComputeWorkGroupSize),
+ toString(aProperties.limits.subPixelPrecisionBits),
+ toString(aProperties.limits.subTexelPrecisionBits),
+ toString(aProperties.limits.mipmapPrecisionBits),
+ toString(aProperties.limits.maxDrawIndexedIndexValue),
+ toString(aProperties.limits.maxDrawIndirectCount),
+ toString(aProperties.limits.maxSamplerLodBias),
+ toString(aProperties.limits.maxSamplerAnisotropy),
+ toString(aProperties.limits.maxViewports),
+ toString(aProperties.limits.maxViewportDimensions),
+ toString(aProperties.limits.viewportBoundsRange),
+ toString(aProperties.limits.viewportSubPixelBits),
+ toString(aProperties.limits.minMemoryMapAlignment),
+ toString(aProperties.limits.minTexelBufferOffsetAlignment),
+ toString(aProperties.limits.minUniformBufferOffsetAlignment),
+ toString(aProperties.limits.minStorageBufferOffsetAlignment),
+ toString(aProperties.limits.minTexelOffset),
+ toString(aProperties.limits.maxTexelOffset),
+ toString(aProperties.limits.minTexelGatherOffset),
+ toString(aProperties.limits.maxTexelGatherOffset),
+ toString(aProperties.limits.minInterpolationOffset),
+ toString(aProperties.limits.maxInterpolationOffset),
+ toString(aProperties.limits.subPixelInterpolationOffsetBits),
+ toString(aProperties.limits.maxFramebufferWidth),
+ toString(aProperties.limits.maxFramebufferHeight),
+ toString(aProperties.limits.maxFramebufferLayers),
+ toString(aProperties.limits.framebufferColorSampleCounts),
+ toString(aProperties.limits.framebufferDepthSampleCounts),
+ toString(aProperties.limits.framebufferStencilSampleCounts),
+ toString(aProperties.limits.framebufferNoAttachmentsSampleCounts),
+ toString(aProperties.limits.maxColorAttachments),
+ toString(aProperties.limits.sampledImageColorSampleCounts),
+ toString(aProperties.limits.sampledImageIntegerSampleCounts),
+ toString(aProperties.limits.sampledImageDepthSampleCounts),
+ toString(aProperties.limits.sampledImageStencilSampleCounts),
+ toString(aProperties.limits.storageImageSampleCounts),
+ toString(aProperties.limits.maxSampleMaskWords),
+ toString(aProperties.limits.timestampComputeAndGraphics),
+ toString(aProperties.limits.timestampPeriod),
+ toString(aProperties.limits.maxClipDistances),
+ toString(aProperties.limits.maxCullDistances),
+ toString(aProperties.limits.maxCombinedClipAndCullDistances),
+ toString(aProperties.limits.discreteQueuePriorities),
+ toString(aProperties.limits.pointSizeRange),
+ toString(aProperties.limits.lineWidthRange),
+ toString(aProperties.limits.pointSizeGranularity),
+ toString(aProperties.limits.lineWidthGranularity),
+ toString(aProperties.limits.strictLines),
+ toString(aProperties.limits.standardSampleLocations),
+ toString(aProperties.limits.optimalBufferCopyOffsetAlignment),
+ toString(aProperties.limits.optimalBufferCopyRowPitchAlignment),
+ toString(aProperties.limits.nonCoherentAtomSize)
+ ]);
+ end;
+ if aPrintSparseProps then begin
+ result := result + Format(
+ 'SparseProperties:' + sLineBreak +
+ ' ResidencyStandard2DBlockShape: %s' + sLineBreak +
+ ' ResidencyStandard2DMultisampleBlockShape: %s' + sLineBreak +
+ ' ResidencyStandard3DBlockShape: %s' + sLineBreak +
+ ' ResidencyAlignedMipSize: %s' + sLineBreak +
+ ' ResidencyNonResidentStrict: %s' + sLineBreak,
+ [
+ toString(aProperties.sparseProperties.residencyStandard2DBlockShape),
+ toString(aProperties.sparseProperties.residencyStandard2DMultisampleBlockShape),
+ toString(aProperties.sparseProperties.residencyStandard3DBlockShape),
+ toString(aProperties.sparseProperties.residencyAlignedMipSize),
+ toString(aProperties.sparseProperties.residencyNonResidentStrict)
+ ]);
+ end;
+end;
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function vkuMakeString(const aMemoryProperties: TVkPhysicalDeviceMemoryProperties): String;
+var i: Integer;
+begin
+ result := 'Types:' + sLineBreak;
+ for i := 0 to aMemoryProperties.memoryTypeCount-1 do begin
+ result := result + Format(
+ ' Type %d:' + sLineBreak +
+ ' PropertyFlags: 0x%.16X' + sLineBreak +
+ ' HeapIndex: %d (0x%2:.16X)' + sLineBreak,
+ [i, aMemoryProperties.memoryTypes[i].propertyFlags, aMemoryProperties.memoryTypes[i].heapIndex]);
+ end;
+ result := result + 'Heaps:' + sLineBreak;
+ for i := 0 to aMemoryProperties.memoryHeapCount-1 do begin
+ result := result + Format(
+ ' Heap %d:' + sLineBreak +
+ ' Size: %d (0x%1:.16X)' + sLineBreak +
+ ' Flags: 0x%.16X' + sLineBreak,
+ [i, aMemoryProperties.memoryHeaps[i].size, aMemoryProperties.memoryHeaps[i].flags]);
+ end;
+end;
+
+
end.