mirror of https://github.com/red-prig/fpPS4.git
2337 lines
64 KiB
Plaintext
2337 lines
64 KiB
Plaintext
unit vImage;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils,
|
|
Vulkan,
|
|
vDevice,
|
|
vPipeline,
|
|
vMemory,
|
|
vDependence;
|
|
|
|
const
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32=TVkFormat(ord(VK_FORMAT_B10G11R11_UFLOAT_PACK32)+1000000000);
|
|
|
|
type
|
|
PvImageBarrier=^TvImageBarrier;
|
|
TvImageBarrier=object
|
|
type
|
|
t_push_cb=function():TVkCommandBuffer of object;
|
|
var
|
|
//image:TVkImage;
|
|
//range:TVkImageSubresourceRange;
|
|
//
|
|
AccessMask:TVkAccessFlags;
|
|
ImgLayout :TVkImageLayout;
|
|
StageMask :TVkPipelineStageFlags;
|
|
Procedure Init({_image:TVkImage;_sub:TVkImageSubresourceRange});
|
|
function Push(cmd:TVkCommandBuffer;
|
|
cb:t_push_cb;
|
|
image:TVkImage;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags):Boolean;
|
|
end;
|
|
|
|
TvSwapChainImage=class
|
|
FHandle:TVkImage;
|
|
FView :TVkImage;
|
|
Barrier:TvImageBarrier;
|
|
procedure PushBarrier(cmd:TVkCommandBuffer;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags);
|
|
end;
|
|
|
|
TvSwapChain=class
|
|
FSurface:TvSurface;
|
|
FSize :TVkExtent2D;
|
|
FHandle :TVkSwapchainKHR;
|
|
FImages :array of TvSwapChainImage;
|
|
Constructor Create(Surface:TvSurface;mode:Integer;imageUsage:TVkImageUsageFlags);
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
TvImageView=class(TvRefsObject)
|
|
FHandle:TVkImageView;
|
|
FName :RawByteString;
|
|
procedure SetObjectName(const name:RawByteString);
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
TvCustomImage=class(TvRefsObject)
|
|
FHandle:TVkImage;
|
|
FFormat:TVkFormat; //real used format
|
|
FBind :TvPointer;
|
|
FSize :TVkDeviceSize;
|
|
FName :RawByteString;
|
|
function is_invalid:Boolean;
|
|
procedure FreeHandle; virtual;
|
|
Destructor Destroy; override;
|
|
function GetImageInfo:TVkImageCreateInfo; virtual; abstract;
|
|
function GetRequirements:TVkMemoryRequirements;
|
|
function GetDedicatedAllocation:Boolean;
|
|
function Compile(ext:Pointer):Boolean; virtual;
|
|
function BindMem(P:TvPointer):TVkResult;
|
|
procedure UnBindMem(do_free:Boolean);
|
|
function Hold(Sender:TObject):Boolean; override;
|
|
function Drop(Sender:TObject):Boolean; override;
|
|
function OnReleaseMem(Sender:TObject):Boolean; virtual;
|
|
procedure SetObjectName(const name:RawByteString);
|
|
end;
|
|
|
|
const
|
|
//usage image
|
|
TM_READ =1;
|
|
TM_WRITE =2;
|
|
TM_CLEAR =4; //Render target is cleared
|
|
TM_MIXED =8; //Mixed image usage
|
|
TM_INVAL=16; //invalid buffer/image
|
|
|
|
type
|
|
t_image_usage=(iu_attachment,iu_depthstenc,iu_sampled,iu_storage,iu_transfer,iu_buffer,iu_htile,iu_cmask,iu_degamma);
|
|
s_image_usage=set of t_image_usage;
|
|
|
|
type
|
|
TvExtent3D=packed record
|
|
width :Word; //(0..16383)
|
|
height:Word; //(0..16383)
|
|
depth :Word; //(0..8192)
|
|
end;
|
|
|
|
TvDstSel=bitpacked record
|
|
x,y,z,w:0..15; //(0..6)
|
|
end;
|
|
|
|
TvImageMemoryKey=packed object
|
|
start:QWORD;
|
|
__end:QWORD;
|
|
end;
|
|
|
|
TvTiling=bitpacked record
|
|
idx:0..31; //0..31 (5)
|
|
alt:0..1; //1
|
|
end;
|
|
|
|
TvImageKeyParams=bitpacked object
|
|
itype :0..3; //2 TVkImageType 0..2
|
|
pow2pad :0..1; //1
|
|
invalid :0..1; //1
|
|
reserved :0..15; //4
|
|
tiling :TvTiling;
|
|
samples :Byte; //TVkSampleCountFlagBits 1..4 (3)
|
|
mipLevels :Byte; //(0..15) (4)
|
|
width :Word; //(0..16383)
|
|
height :Word; //(0..16383)
|
|
depth :Word; //(0..8192)
|
|
arrayLayers:Word; //(0..16383)
|
|
pitch :Word; //(0..16383)
|
|
pad_width :Word;
|
|
pad_height :Word;
|
|
function layerCount:Word;
|
|
end;
|
|
|
|
PvImageKey=^TvImageKey;
|
|
TvImageKey=packed object
|
|
Addr :Pointer;
|
|
Addr2 :Pointer;
|
|
cformat:TVkFormat;
|
|
params :TvImageKeyParams;
|
|
end;
|
|
|
|
PvImageViewKey=^TvImageViewKey;
|
|
TvImageViewKey=bitpacked object
|
|
cformat :TVkFormat;
|
|
vtype :0..127; //TVkImageViewType 0..6
|
|
invalid :0..1;
|
|
fusage :Byte;
|
|
dstSel :TvDstSel; //word
|
|
base_level:Byte; //first mip level (0..15)
|
|
last_level:Byte; //last mip level (0..15)
|
|
base_array:Word; //first array index (0..16383)
|
|
last_array:Word; //texture height (0..16383)
|
|
minLod :TVkFloat;
|
|
function arrayLayers:Word;
|
|
function baseArrayLayer:Word;
|
|
function layerCount:Word;
|
|
end;
|
|
|
|
TvImage=class(TvCustomImage)
|
|
FExtent:TVkExtent3D;
|
|
FUsage :TVkFlags;
|
|
Fflags :TVkImageCreateFlags;
|
|
Barrier:TvImageBarrier;
|
|
Constructor Create(format:TVkFormat;extent:TVkExtent3D;usage:TVkFlags;flags:TVkImageCreateFlags;ext:Pointer=nil);
|
|
function GetImageInfo:TVkImageCreateInfo; override;
|
|
function GetViewInfo:TVkImageViewCreateInfo; virtual; abstract;
|
|
function NewView:TvImageView;
|
|
function NewViewF(Format:TVkFormat):TvImageView;
|
|
procedure PushBarrier(cmd:TVkCommandBuffer;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags);
|
|
end;
|
|
|
|
TvHostImage1D=class(TvImage)
|
|
function GetImageInfo:TVkImageCreateInfo; override;
|
|
end;
|
|
|
|
TvHostImage2D=class(TvImage)
|
|
function GetImageInfo:TVkImageCreateInfo; override;
|
|
end;
|
|
|
|
TvDeviceImage1D=class(TvImage)
|
|
function GetViewInfo:TVkImageViewCreateInfo; override;
|
|
function GetImageInfo:TVkImageCreateInfo; override;
|
|
end;
|
|
|
|
TvDeviceImage2D=class(TvImage)
|
|
function GetViewInfo:TVkImageViewCreateInfo; override;
|
|
function GetImageInfo:TVkImageCreateInfo; override;
|
|
end;
|
|
|
|
TvFramebufferAttachmentShort=packed record
|
|
cformat :TVkFormat;
|
|
width :Word;
|
|
height :Word;
|
|
layerCount:Word;
|
|
end;
|
|
|
|
AvFramebufferAttach=array[0..8] of TVkFramebufferAttachmentImageInfo;
|
|
AvFramebufferAShort=array[0..8] of TvFramebufferAttachmentShort;
|
|
|
|
AvFramebufferImages=array[0..8] of TvImageView;
|
|
AvImageViews =array[0..8] of TVkImageView;
|
|
|
|
TvFramebuffer=class(TvRefsObject)
|
|
FHandle:TVkFramebuffer;
|
|
function IsImageless:Boolean; virtual;
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
PvFramebufferImagelessKey=^TvFramebufferImagelessKey;
|
|
TvFramebufferImagelessKey=packed object
|
|
FRenderPass :TvRenderPass;
|
|
FWidth :Word;
|
|
FHeight :Word;
|
|
FLayers :Word;
|
|
FImagesCount:Word;
|
|
FImages :AvFramebufferAShort;
|
|
Procedure SetRenderPass(r:TvRenderPass);
|
|
Procedure SetSize(Size:TVkExtent2D);
|
|
Procedure AddImageAt(Key:TvImageKey);
|
|
Procedure Export(var F:AvFramebufferAttach);
|
|
end;
|
|
|
|
TvFramebufferImageless=class(TvFramebuffer)
|
|
Key:TvFramebufferImagelessKey;
|
|
function IsImageless:Boolean; override;
|
|
function Compile:Boolean;
|
|
end;
|
|
|
|
PvFramebufferBindedKey=^TvFramebufferBindedKey;
|
|
TvFramebufferBindedKey=packed object
|
|
FRenderPass :TvRenderPass;
|
|
FWidth :Word;
|
|
FHeight :Word;
|
|
FLayers :Word;
|
|
FImagesCount:Word;
|
|
FImages :AvFramebufferImages;
|
|
Procedure SetRenderPass(r:TvRenderPass);
|
|
Procedure SetSize(Size:TVkExtent2D);
|
|
Procedure AddImageView(v:TvImageView);
|
|
end;
|
|
|
|
TvFramebufferBinded=class(TvFramebuffer)
|
|
Key:TvFramebufferBindedKey;
|
|
FAcquire:bitpacked array[0..8] of Boolean;
|
|
function Compile:Boolean;
|
|
Procedure AcquireImageViews;
|
|
Procedure ReleaseImageViews;
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
Function GetAspectMaskByFormat(cformat:TVkFormat):DWORD;
|
|
|
|
Function GetDepthStencilInitLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
Function GetDepthStencilSendLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
Function GetDepthStencilAccessAttachMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags;
|
|
function GetColorSendLayout(IMAGE_USAGE:Byte):TVkImageLayout;
|
|
Function GetColorAccessAttachMask(IMAGE_USAGE:Byte):TVkAccessFlags;
|
|
|
|
Function getFormatSize(cformat:TVkFormat):Byte; //in bytes
|
|
function IsTexelFormat(cformat:TVkFormat):Boolean;
|
|
function IsDepthOrStencilFormat(cformat:TVkFormat):Boolean;
|
|
Function IsDepthAndStencil (cformat:TVkFormat):Boolean;
|
|
function GetDepthOnlyFormat (cformat:TVkFormat):TVkFormat;
|
|
function GetStencilOnlyFormat (cformat:TVkFormat):TVkFormat;
|
|
|
|
function GetDepthOnly (const key:TvImageKey):TvImageKey;
|
|
function GetStencilOnly(const key:TvImageKey):TvImageKey;
|
|
|
|
function vkGetFormatSupport(format:TVkFormat;tiling:TVkImageTiling;usage:TVkImageUsageFlags):Boolean;
|
|
function vkFixFormatSupport(format:TVkFormat;tiling:TVkImageTiling;usage:TVkImageUsageFlags):TVkFormat;
|
|
|
|
function GET_FORMATS_LEN(buf:PVkFormat):Byte;
|
|
function GET_VK_IMAGE_MUTABLE(cformat:TVkFormat):PVkFormat;
|
|
|
|
function GET_VK_FORMAT_STORAGE(cformat:TVkFormat):TVkFormat;
|
|
|
|
function GET_VK_IMAGE_USAGE_DEFAULT (cformat:TVkFormat):TVkFlags;
|
|
function GET_VK_IMAGE_USAGE_ATTACHMENT(cformat:TVkFormat):TVkFlags;
|
|
function GET_VK_IMAGE_CREATE_DEFAULT (cformat:TVkFormat):TVkFlags;
|
|
|
|
Function GetNormalizedParams(const key:TvImageKey):TvImageKeyParams;
|
|
Function CompareNormalized(const a,b:TvImageKey):Integer;
|
|
|
|
Function GetVkFormatStr(cformat:TVkFormat):RawByteString;
|
|
|
|
implementation
|
|
|
|
uses
|
|
subr_backtrace;
|
|
|
|
function TvImageKeyParams.layerCount:Word;
|
|
begin
|
|
if (TVkImageType(itype)=VK_IMAGE_TYPE_3D) then
|
|
begin
|
|
Result:=1; //3D texture array does not exist?
|
|
end else
|
|
begin
|
|
Result:=arrayLayers;
|
|
end;
|
|
end;
|
|
|
|
//
|
|
|
|
function TvImageViewKey.arrayLayers:Word;
|
|
begin
|
|
Result:=last_array-base_array+1;
|
|
end;
|
|
|
|
function TvImageViewKey.baseArrayLayer:Word;
|
|
begin
|
|
case TVkImageViewType(vtype) of
|
|
VK_IMAGE_VIEW_TYPE_3D:
|
|
begin
|
|
Result:=0; //3D texture array does not exist?
|
|
end;
|
|
VK_IMAGE_VIEW_TYPE_CUBE,
|
|
VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
|
begin
|
|
if (arrayLayers mod 6)<>0 then
|
|
begin
|
|
//broken CUBE?
|
|
Result:=0;
|
|
end else
|
|
begin
|
|
Result:=base_array;
|
|
end;
|
|
end;
|
|
else
|
|
begin
|
|
Result:=base_array;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TvImageViewKey.layerCount:Word;
|
|
begin
|
|
case TVkImageViewType(vtype) of
|
|
VK_IMAGE_VIEW_TYPE_3D:
|
|
begin
|
|
Result:=1; //3D texture array does not exist?
|
|
end;
|
|
VK_IMAGE_VIEW_TYPE_CUBE,
|
|
VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
|
begin
|
|
Result:=((arrayLayers+5) div 6)*6; //align up
|
|
end;
|
|
else
|
|
begin
|
|
Result:=arrayLayers;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Function getFormatSize(cformat:TVkFormat):Byte; //in bytes
|
|
begin
|
|
Result:=0;
|
|
Case cformat of
|
|
VK_FORMAT_UNDEFINED :Result:=0;
|
|
|
|
//pixel size
|
|
|
|
VK_FORMAT_R8_UNORM ,
|
|
VK_FORMAT_R8_SNORM ,
|
|
VK_FORMAT_R8_USCALED ,
|
|
VK_FORMAT_R8_SSCALED ,
|
|
VK_FORMAT_R8_UINT ,
|
|
VK_FORMAT_R8_SINT ,
|
|
VK_FORMAT_R8_SRGB :Result:=1;
|
|
|
|
VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT ,
|
|
VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT ,
|
|
VK_FORMAT_R4G4B4A4_UNORM_PACK16 ,
|
|
VK_FORMAT_B4G4R4A4_UNORM_PACK16 ,
|
|
VK_FORMAT_R5G6B5_UNORM_PACK16 ,
|
|
VK_FORMAT_B5G6R5_UNORM_PACK16 ,
|
|
|
|
VK_FORMAT_A1R5G5B5_UNORM_PACK16 ,
|
|
VK_FORMAT_R5G5B5A1_UNORM_PACK16 ,
|
|
|
|
VK_FORMAT_R8G8_UNORM ,
|
|
VK_FORMAT_R8G8_SNORM ,
|
|
VK_FORMAT_R8G8_USCALED ,
|
|
VK_FORMAT_R8G8_SSCALED ,
|
|
VK_FORMAT_R8G8_UINT ,
|
|
VK_FORMAT_R8G8_SINT ,
|
|
VK_FORMAT_R8G8_SRGB ,
|
|
|
|
VK_FORMAT_R16_UNORM ,
|
|
VK_FORMAT_R16_SNORM ,
|
|
VK_FORMAT_R16_USCALED ,
|
|
VK_FORMAT_R16_SSCALED ,
|
|
VK_FORMAT_R16_UINT ,
|
|
VK_FORMAT_R16_SINT ,
|
|
VK_FORMAT_R16_SFLOAT :Result:=2;
|
|
|
|
VK_FORMAT_R8G8B8A8_UNORM ,
|
|
VK_FORMAT_R8G8B8A8_SNORM ,
|
|
VK_FORMAT_R8G8B8A8_USCALED ,
|
|
VK_FORMAT_R8G8B8A8_SSCALED ,
|
|
VK_FORMAT_R8G8B8A8_UINT ,
|
|
VK_FORMAT_R8G8B8A8_SINT ,
|
|
VK_FORMAT_R8G8B8A8_SRGB ,
|
|
|
|
VK_FORMAT_B8G8R8A8_UNORM ,
|
|
VK_FORMAT_B8G8R8A8_SNORM ,
|
|
VK_FORMAT_B8G8R8A8_USCALED ,
|
|
VK_FORMAT_B8G8R8A8_SSCALED ,
|
|
VK_FORMAT_B8G8R8A8_UINT ,
|
|
VK_FORMAT_B8G8R8A8_SINT ,
|
|
VK_FORMAT_B8G8R8A8_SRGB ,
|
|
|
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_SNORM_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_USCALED_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_SSCALED_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_UINT_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_SINT_PACK32 ,
|
|
VK_FORMAT_A8B8G8R8_SRGB_PACK32 ,
|
|
|
|
VK_FORMAT_A2R10G10B10_UNORM_PACK32 ,
|
|
VK_FORMAT_A2R10G10B10_SNORM_PACK32 ,
|
|
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_UINT_PACK32 ,
|
|
VK_FORMAT_A2R10G10B10_SINT_PACK32 ,
|
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32 ,
|
|
VK_FORMAT_A2B10G10R10_SNORM_PACK32 ,
|
|
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_UINT_PACK32 ,
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32 ,
|
|
|
|
VK_FORMAT_R16G16_UNORM ,
|
|
VK_FORMAT_R16G16_SNORM ,
|
|
VK_FORMAT_R16G16_USCALED ,
|
|
VK_FORMAT_R16G16_SSCALED ,
|
|
VK_FORMAT_R16G16_UINT ,
|
|
VK_FORMAT_R16G16_SINT ,
|
|
VK_FORMAT_R16G16_SFLOAT ,
|
|
|
|
VK_FORMAT_R32_UINT ,
|
|
VK_FORMAT_R32_SINT ,
|
|
VK_FORMAT_R32_SFLOAT ,
|
|
|
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32 ,
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32 ,
|
|
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=4;
|
|
|
|
VK_FORMAT_R16G16B16A16_UNORM ,
|
|
VK_FORMAT_R16G16B16A16_SNORM ,
|
|
VK_FORMAT_R16G16B16A16_USCALED ,
|
|
VK_FORMAT_R16G16B16A16_SSCALED ,
|
|
VK_FORMAT_R16G16B16A16_UINT ,
|
|
VK_FORMAT_R16G16B16A16_SINT ,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT ,
|
|
|
|
VK_FORMAT_R32G32_UINT ,
|
|
VK_FORMAT_R32G32_SINT ,
|
|
VK_FORMAT_R32G32_SFLOAT :Result:=8;
|
|
|
|
VK_FORMAT_R32G32B32_UINT ,
|
|
VK_FORMAT_R32G32B32_SINT ,
|
|
VK_FORMAT_R32G32B32_SFLOAT :Result:=12;
|
|
|
|
VK_FORMAT_R32G32B32A32_UINT ,
|
|
VK_FORMAT_R32G32B32A32_SINT ,
|
|
VK_FORMAT_R32G32B32A32_SFLOAT :Result:=16;
|
|
|
|
//stencil
|
|
VK_FORMAT_S8_UINT :Result:=1;
|
|
//depth
|
|
VK_FORMAT_D16_UNORM :Result:=2;
|
|
VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4;
|
|
VK_FORMAT_D32_SFLOAT :Result:=4;
|
|
//depth stencil
|
|
VK_FORMAT_D16_UNORM_S8_UINT :Result:=3;
|
|
VK_FORMAT_D24_UNORM_S8_UINT :Result:=4;
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT :Result:=5;
|
|
|
|
//texel size
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
|
|
VK_FORMAT_BC4_UNORM_BLOCK..
|
|
VK_FORMAT_BC4_SNORM_BLOCK :Result:=8;
|
|
|
|
VK_FORMAT_BC2_UNORM_BLOCK..
|
|
VK_FORMAT_BC3_SRGB_BLOCK,
|
|
VK_FORMAT_BC5_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK :Result:=16;
|
|
|
|
else
|
|
Assert(false,'getFormatSize:TODO:'+IntToStr(ord(cformat)));
|
|
end;
|
|
end;
|
|
|
|
function IsTexelFormat(cformat:TVkFormat):Boolean;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK:
|
|
Result:=True;
|
|
else
|
|
Result:=False;
|
|
end;
|
|
end;
|
|
|
|
function IsDepthOrStencilFormat(cformat:TVkFormat):Boolean;
|
|
begin
|
|
Case cformat of
|
|
//stencil
|
|
VK_FORMAT_S8_UINT,
|
|
//depth
|
|
VK_FORMAT_D16_UNORM,
|
|
VK_FORMAT_X8_D24_UNORM_PACK32,
|
|
VK_FORMAT_D32_SFLOAT,
|
|
//depth stencil
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result:=True;
|
|
else
|
|
Result:=False;
|
|
end;
|
|
end;
|
|
|
|
Function IsDepthAndStencil(cformat:TVkFormat):Boolean;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result:=True;
|
|
else
|
|
Result:=False;
|
|
end;
|
|
end;
|
|
|
|
function GetDepthOnlyFormat(cformat:TVkFormat):TVkFormat;
|
|
begin
|
|
Case cformat of
|
|
//depth
|
|
VK_FORMAT_D16_UNORM,
|
|
VK_FORMAT_X8_D24_UNORM_PACK32,
|
|
VK_FORMAT_D32_SFLOAT:
|
|
Result:=cformat;
|
|
//depth stencil
|
|
VK_FORMAT_D16_UNORM_S8_UINT :Result:=VK_FORMAT_D16_UNORM;
|
|
VK_FORMAT_D24_UNORM_S8_UINT :Result:=VK_FORMAT_X8_D24_UNORM_PACK32;
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:Result:=VK_FORMAT_D32_SFLOAT;
|
|
else
|
|
Result:=VK_FORMAT_UNDEFINED;
|
|
end;
|
|
end;
|
|
|
|
function GetStencilOnlyFormat(cformat:TVkFormat):TVkFormat;
|
|
begin
|
|
Case cformat of
|
|
//stencil
|
|
VK_FORMAT_S8_UINT,
|
|
//depth stencil
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result:=VK_FORMAT_S8_UINT;
|
|
else
|
|
Result:=VK_FORMAT_UNDEFINED;
|
|
end;
|
|
end;
|
|
|
|
//
|
|
|
|
function GetDepthOnly(const key:TvImageKey):TvImageKey;
|
|
begin
|
|
Result.Addr :=key.Addr;
|
|
Result.Addr2 :=nil;
|
|
Result.cformat:=GetDepthOnlyFormat(key.cformat);
|
|
Result.params :=key.params;
|
|
end;
|
|
|
|
function GetStencilOnly(const key:TvImageKey):TvImageKey;
|
|
begin
|
|
Result.Addr :=key.Addr2;
|
|
Result.Addr2 :=nil;
|
|
Result.cformat:=GetStencilOnlyFormat(key.cformat);
|
|
Result.params :=key.params;
|
|
end;
|
|
|
|
//
|
|
|
|
function TvFramebuffer.IsImageless:Boolean;
|
|
begin
|
|
Result:=False;
|
|
end;
|
|
|
|
Destructor TvFramebuffer.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyFramebuffer(Device.FHandle,FHandle,nil);
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
//
|
|
|
|
Procedure TvFramebufferBindedKey.SetRenderPass(r:TvRenderPass);
|
|
begin
|
|
FRenderPass:=r;
|
|
end;
|
|
|
|
Procedure TvFramebufferBindedKey.SetSize(Size:TVkExtent2D);
|
|
begin
|
|
FWidth :=Size.width;
|
|
FHeight:=Size.height;
|
|
FLayers:=1;
|
|
end;
|
|
|
|
Procedure TvFramebufferBindedKey.AddImageView(v:TvImageView);
|
|
begin
|
|
Assert(v<>nil,'AddImageView');
|
|
if (FImagesCount>=Length(AvFramebufferImages)) then Exit;
|
|
FImages[FImagesCount]:=v;
|
|
Inc(FImagesCount);
|
|
end;
|
|
|
|
///
|
|
|
|
const
|
|
MUTABLE_8:array[0..7] of TVkFormat=(
|
|
VK_FORMAT_R8_UNORM,
|
|
VK_FORMAT_R8_SNORM,
|
|
VK_FORMAT_R8_USCALED,
|
|
VK_FORMAT_R8_SSCALED,
|
|
VK_FORMAT_R8_UINT,
|
|
VK_FORMAT_R8_SINT,
|
|
VK_FORMAT_R8_SRGB,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_16:array[0..18] of TVkFormat=(
|
|
//VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, //VK1.3
|
|
//VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT, //VK1.3
|
|
VK_FORMAT_R4G4B4A4_UNORM_PACK16,
|
|
VK_FORMAT_B4G4R4A4_UNORM_PACK16,
|
|
VK_FORMAT_R5G6B5_UNORM_PACK16,
|
|
VK_FORMAT_B5G6R5_UNORM_PACK16,
|
|
VK_FORMAT_R8G8_UNORM,
|
|
VK_FORMAT_R8G8_SNORM,
|
|
VK_FORMAT_R8G8_USCALED,
|
|
VK_FORMAT_R8G8_SSCALED,
|
|
VK_FORMAT_R8G8_UINT,
|
|
VK_FORMAT_R8G8_SINT,
|
|
VK_FORMAT_R8G8_SRGB,
|
|
VK_FORMAT_R16_UNORM,
|
|
VK_FORMAT_R16_SNORM,
|
|
VK_FORMAT_R16_USCALED,
|
|
VK_FORMAT_R16_SSCALED,
|
|
VK_FORMAT_R16_UINT,
|
|
VK_FORMAT_R16_SINT,
|
|
VK_FORMAT_R16_SFLOAT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_8888:array[0..44] of TVkFormat=(
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
VK_FORMAT_R8G8B8A8_SNORM,
|
|
VK_FORMAT_R8G8B8A8_USCALED,
|
|
VK_FORMAT_R8G8B8A8_SSCALED,
|
|
VK_FORMAT_R8G8B8A8_UINT,
|
|
VK_FORMAT_R8G8B8A8_SINT,
|
|
VK_FORMAT_R8G8B8A8_SRGB,
|
|
VK_FORMAT_B8G8R8A8_UNORM,
|
|
VK_FORMAT_B8G8R8A8_SNORM,
|
|
VK_FORMAT_B8G8R8A8_USCALED,
|
|
VK_FORMAT_B8G8R8A8_SSCALED,
|
|
VK_FORMAT_B8G8R8A8_UINT,
|
|
VK_FORMAT_B8G8R8A8_SINT,
|
|
VK_FORMAT_B8G8R8A8_SRGB,
|
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SNORM_PACK32,
|
|
VK_FORMAT_A8B8G8R8_USCALED_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
|
|
VK_FORMAT_A8B8G8R8_UINT_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SINT_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SRGB_PACK32,
|
|
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SNORM_PACK32,
|
|
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_UINT_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SINT_PACK32,
|
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SNORM_PACK32,
|
|
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_UINT_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32,
|
|
VK_FORMAT_R16G16_UNORM,
|
|
VK_FORMAT_R16G16_SNORM,
|
|
VK_FORMAT_R16G16_USCALED,
|
|
VK_FORMAT_R16G16_SSCALED,
|
|
VK_FORMAT_R16G16_UINT,
|
|
VK_FORMAT_R16G16_SINT,
|
|
VK_FORMAT_R16G16_SFLOAT,
|
|
VK_FORMAT_R32_UINT,
|
|
VK_FORMAT_R32_SINT,
|
|
VK_FORMAT_R32_SFLOAT,
|
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_5999:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_3232:array[0..10] of TVkFormat=(
|
|
VK_FORMAT_R16G16B16A16_UNORM,
|
|
VK_FORMAT_R16G16B16A16_SNORM,
|
|
VK_FORMAT_R16G16B16A16_USCALED,
|
|
VK_FORMAT_R16G16B16A16_SSCALED,
|
|
VK_FORMAT_R16G16B16A16_UINT,
|
|
VK_FORMAT_R16G16B16A16_SINT,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
VK_FORMAT_R32G32_UINT,
|
|
VK_FORMAT_R32G32_SINT,
|
|
VK_FORMAT_R32G32_SFLOAT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_323232:array[0..3] of TVkFormat=(
|
|
VK_FORMAT_R32G32B32_UINT,
|
|
VK_FORMAT_R32G32B32_SINT,
|
|
VK_FORMAT_R32G32B32_SFLOAT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_32323232:array[0..3] of TVkFormat=(
|
|
VK_FORMAT_R32G32B32A32_UINT,
|
|
VK_FORMAT_R32G32B32A32_SINT,
|
|
VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_D16_UNORM:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_D16_UNORM,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_X8_D24_UNORM:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_X8_D24_UNORM_PACK32,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_D32_SFLOAT:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_D32_SFLOAT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_S8_UINT:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_S8_UINT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_D16_UNORM_S8_UINT:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_D24_UNORM_S8_UINT:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_D32_SFLOAT_S8_UINT:array[0..1] of TVkFormat=(
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC1_RGB:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK,
|
|
VK_FORMAT_BC1_RGB_SRGB_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC1_RGBA:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
|
|
VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC2:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC2_UNORM_BLOCK,
|
|
VK_FORMAT_BC2_SRGB_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC3:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC3_UNORM_BLOCK,
|
|
VK_FORMAT_BC3_SRGB_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC4:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC4_UNORM_BLOCK,
|
|
VK_FORMAT_BC4_SNORM_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC5:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC5_UNORM_BLOCK,
|
|
VK_FORMAT_BC5_SNORM_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC6:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC6H_UFLOAT_BLOCK,
|
|
VK_FORMAT_BC6H_SFLOAT_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
MUTABLE_BC7:array[0..2] of TVkFormat=(
|
|
VK_FORMAT_BC7_UNORM_BLOCK,
|
|
VK_FORMAT_BC7_SRGB_BLOCK,
|
|
VK_FORMAT_UNDEFINED
|
|
);
|
|
|
|
function GET_FORMATS_LEN(buf:PVkFormat):Byte;
|
|
begin
|
|
Result:=0;
|
|
if (buf=nil) then Exit;
|
|
while (buf[0]<>VK_FORMAT_UNDEFINED) do
|
|
begin
|
|
Inc(Result);
|
|
Inc(buf);
|
|
end;
|
|
end;
|
|
|
|
function GET_VK_IMAGE_MUTABLE(cformat:TVkFormat):PVkFormat;
|
|
begin
|
|
Result:=nil;
|
|
|
|
case cformat of
|
|
|
|
VK_FORMAT_R8_UNORM :Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_SNORM :Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_USCALED:Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_SSCALED:Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_UINT :Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_SINT :Result:=@MUTABLE_8;
|
|
VK_FORMAT_R8_SRGB :Result:=@MUTABLE_8;
|
|
|
|
VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT:Result:=@MUTABLE_16;
|
|
VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT:Result:=@MUTABLE_16;
|
|
VK_FORMAT_R4G4B4A4_UNORM_PACK16 :Result:=@MUTABLE_16;
|
|
VK_FORMAT_B4G4R4A4_UNORM_PACK16 :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R5G6B5_UNORM_PACK16 :Result:=@MUTABLE_16;
|
|
VK_FORMAT_B5G6R5_UNORM_PACK16 :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_UNORM :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_SNORM :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_USCALED :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_SSCALED :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_UINT :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_SINT :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R8G8_SRGB :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_UNORM :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_SNORM :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_USCALED :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_SSCALED :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_UINT :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_SINT :Result:=@MUTABLE_16;
|
|
VK_FORMAT_R16_SFLOAT :Result:=@MUTABLE_16;
|
|
|
|
VK_FORMAT_R8G8B8A8_UNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_SNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_USCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_SSCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_UINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_SINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R8G8B8A8_SRGB :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_UNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_SNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_USCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_SSCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_UINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_SINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B8G8R8A8_SRGB :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_SNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_USCALED_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_SSCALED_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_UINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_SINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A8B8G8R8_SRGB_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_UNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_SNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_USCALED_PACK32:Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_SSCALED_PACK32:Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_UINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2R10G10B10_SINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_SNORM_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_USCALED_PACK32:Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_SSCALED_PACK32:Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_UINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_UNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_SNORM :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_USCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_SSCALED :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_UINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_SINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R16G16_SFLOAT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R32_UINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R32_SINT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R32_SFLOAT :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32 :Result:=@MUTABLE_8888;
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32 :Result:=@MUTABLE_8888;
|
|
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=@MUTABLE_5999;
|
|
|
|
VK_FORMAT_R16G16B16A16_UNORM :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_SNORM :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_USCALED:Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_SSCALED:Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_UINT :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_SINT :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R16G16B16A16_SFLOAT :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R32G32_UINT :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R32G32_SINT :Result:=@MUTABLE_3232;
|
|
VK_FORMAT_R32G32_SFLOAT :Result:=@MUTABLE_3232;
|
|
|
|
VK_FORMAT_R32G32B32_UINT :Result:=@MUTABLE_323232;
|
|
VK_FORMAT_R32G32B32_SINT :Result:=@MUTABLE_323232;
|
|
VK_FORMAT_R32G32B32_SFLOAT :Result:=@MUTABLE_323232;
|
|
|
|
VK_FORMAT_R32G32B32A32_UINT :Result:=@MUTABLE_32323232;
|
|
VK_FORMAT_R32G32B32A32_SINT :Result:=@MUTABLE_32323232;
|
|
VK_FORMAT_R32G32B32A32_SFLOAT :Result:=@MUTABLE_32323232;
|
|
|
|
VK_FORMAT_D16_UNORM:Result:=@MUTABLE_D16_UNORM;
|
|
|
|
VK_FORMAT_X8_D24_UNORM_PACK32:Result:=@MUTABLE_X8_D24_UNORM;
|
|
|
|
VK_FORMAT_D32_SFLOAT:Result:=@MUTABLE_D32_SFLOAT;
|
|
|
|
VK_FORMAT_S8_UINT:Result:=@MUTABLE_S8_UINT;
|
|
|
|
VK_FORMAT_D16_UNORM_S8_UINT:Result:=@MUTABLE_D16_UNORM_S8_UINT;
|
|
|
|
VK_FORMAT_D24_UNORM_S8_UINT:Result:=@MUTABLE_D24_UNORM_S8_UINT;
|
|
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:Result:=@MUTABLE_D32_SFLOAT_S8_UINT;
|
|
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK:Result:=@MUTABLE_BC1_RGB;
|
|
VK_FORMAT_BC1_RGB_SRGB_BLOCK :Result:=@MUTABLE_BC1_RGB;
|
|
|
|
VK_FORMAT_BC1_RGBA_UNORM_BLOCK:Result:=@MUTABLE_BC1_RGBA;
|
|
VK_FORMAT_BC1_RGBA_SRGB_BLOCK :Result:=@MUTABLE_BC1_RGBA;
|
|
|
|
VK_FORMAT_BC2_UNORM_BLOCK:Result:=@MUTABLE_BC2;
|
|
VK_FORMAT_BC2_SRGB_BLOCK :Result:=@MUTABLE_BC2;
|
|
|
|
VK_FORMAT_BC3_UNORM_BLOCK:Result:=@MUTABLE_BC3;
|
|
VK_FORMAT_BC3_SRGB_BLOCK :Result:=@MUTABLE_BC3;
|
|
|
|
VK_FORMAT_BC4_UNORM_BLOCK:Result:=@MUTABLE_BC4;
|
|
VK_FORMAT_BC4_SNORM_BLOCK:Result:=@MUTABLE_BC4;
|
|
|
|
VK_FORMAT_BC5_UNORM_BLOCK:Result:=@MUTABLE_BC5;
|
|
VK_FORMAT_BC5_SNORM_BLOCK:Result:=@MUTABLE_BC5;
|
|
|
|
VK_FORMAT_BC6H_UFLOAT_BLOCK:Result:=@MUTABLE_BC6;
|
|
VK_FORMAT_BC6H_SFLOAT_BLOCK:Result:=@MUTABLE_BC6;
|
|
|
|
VK_FORMAT_BC7_UNORM_BLOCK:Result:=@MUTABLE_BC7;
|
|
VK_FORMAT_BC7_SRGB_BLOCK :Result:=@MUTABLE_BC7;
|
|
|
|
else;
|
|
end;
|
|
|
|
end;
|
|
|
|
function GET_VK_FORMAT_STORAGE(cformat:TVkFormat):TVkFormat;
|
|
begin
|
|
Result:=cformat;
|
|
|
|
case cformat of
|
|
|
|
VK_FORMAT_R8_SNORM,
|
|
VK_FORMAT_R8_USCALED,
|
|
VK_FORMAT_R8_SSCALED,
|
|
VK_FORMAT_R8_SINT:Result:=VK_FORMAT_R8_UINT;
|
|
|
|
VK_FORMAT_R8_SRGB:Result:=VK_FORMAT_R8_UNORM;
|
|
|
|
VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
|
|
VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
|
|
VK_FORMAT_R4G4B4A4_UNORM_PACK16,
|
|
VK_FORMAT_B4G4R4A4_UNORM_PACK16,
|
|
VK_FORMAT_R5G6B5_UNORM_PACK16,
|
|
VK_FORMAT_B5G6R5_UNORM_PACK16,
|
|
VK_FORMAT_R8G8_SNORM,
|
|
VK_FORMAT_R8G8_USCALED,
|
|
VK_FORMAT_R8G8_SSCALED,
|
|
VK_FORMAT_R8G8_SINT:Result:=VK_FORMAT_R8G8_UINT;
|
|
|
|
VK_FORMAT_R8G8_SRGB:Result:=VK_FORMAT_R8G8_UNORM;
|
|
|
|
VK_FORMAT_R16_SNORM,
|
|
VK_FORMAT_R16_USCALED,
|
|
VK_FORMAT_R16_SSCALED,
|
|
VK_FORMAT_R16_SINT,
|
|
VK_FORMAT_R16_SFLOAT:Result:=VK_FORMAT_R16_UINT;
|
|
|
|
VK_FORMAT_R8G8B8A8_SNORM,
|
|
VK_FORMAT_R8G8B8A8_USCALED,
|
|
VK_FORMAT_R8G8B8A8_SSCALED,
|
|
VK_FORMAT_R8G8B8A8_SINT:Result:=VK_FORMAT_R8G8B8A8_UINT;
|
|
|
|
VK_FORMAT_R8G8B8A8_SRGB:Result:=VK_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
VK_FORMAT_B8G8R8A8_SNORM,
|
|
VK_FORMAT_B8G8R8A8_USCALED,
|
|
VK_FORMAT_B8G8R8A8_SSCALED,
|
|
VK_FORMAT_B8G8R8A8_UINT,
|
|
VK_FORMAT_B8G8R8A8_SINT:Result:=VK_FORMAT_R8G8B8A8_UINT;
|
|
|
|
VK_FORMAT_B8G8R8A8_SRGB:Result:=VK_FORMAT_B8G8R8A8_UNORM;
|
|
|
|
VK_FORMAT_A8B8G8R8_SNORM_PACK32,
|
|
VK_FORMAT_A8B8G8R8_USCALED_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
|
|
VK_FORMAT_A8B8G8R8_SINT_PACK32:Result:=VK_FORMAT_A8B8G8R8_UINT_PACK32;
|
|
|
|
VK_FORMAT_A8B8G8R8_SRGB_PACK32:Result:=VK_FORMAT_A8B8G8R8_UNORM_PACK32;
|
|
|
|
VK_FORMAT_A2R10G10B10_SNORM_PACK32,
|
|
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
|
|
VK_FORMAT_A2R10G10B10_UINT_PACK32,
|
|
VK_FORMAT_A2R10G10B10_SINT_PACK32:Result:=VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
|
|
|
VK_FORMAT_A2B10G10R10_SNORM_PACK32,
|
|
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
|
|
VK_FORMAT_A2B10G10R10_UINT_PACK32,
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32:Result:=VK_FORMAT_A2B10G10R10_UNORM_PACK32;
|
|
|
|
VK_FORMAT_R16G16_SNORM,
|
|
VK_FORMAT_R16G16_USCALED,
|
|
VK_FORMAT_R16G16_SSCALED,
|
|
VK_FORMAT_R16G16_UINT,
|
|
VK_FORMAT_R16G16_SINT,
|
|
VK_FORMAT_R16G16_SFLOAT:Result:=VK_FORMAT_R16G16_UNORM;
|
|
|
|
VK_FORMAT_R32_SINT,
|
|
VK_FORMAT_R32_SFLOAT,
|
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32:Result:=VK_FORMAT_R32_UINT;
|
|
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32:Result:=VK_FORMAT_R32_UINT;
|
|
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:Result:=VK_FORMAT_R32_UINT;
|
|
|
|
VK_FORMAT_R16G16B16A16_SNORM,
|
|
VK_FORMAT_R16G16B16A16_USCALED,
|
|
VK_FORMAT_R16G16B16A16_SSCALED,
|
|
VK_FORMAT_R16G16B16A16_SINT,
|
|
VK_FORMAT_R16G16B16A16_SFLOAT:Result:=VK_FORMAT_R16G16B16A16_UINT;
|
|
|
|
VK_FORMAT_R32G32_SINT,
|
|
VK_FORMAT_R32G32_SFLOAT:Result:=VK_FORMAT_R32G32_UINT;
|
|
|
|
VK_FORMAT_R32G32B32_SINT,
|
|
VK_FORMAT_R32G32B32_SFLOAT:Result:=VK_FORMAT_R32G32B32_UINT;
|
|
|
|
VK_FORMAT_R32G32B32A32_SINT,
|
|
VK_FORMAT_R32G32B32A32_SFLOAT:Result:=VK_FORMAT_R32G32B32A32_UINT;
|
|
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
|
|
VK_FORMAT_BC4_UNORM_BLOCK..
|
|
VK_FORMAT_BC4_SNORM_BLOCK:Result:=VK_FORMAT_R32G32_UINT;
|
|
|
|
VK_FORMAT_BC2_UNORM_BLOCK..
|
|
VK_FORMAT_BC3_SRGB_BLOCK,
|
|
VK_FORMAT_BC5_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK:Result:=VK_FORMAT_R32G32B32A32_UINT;
|
|
|
|
else;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
VK_IMAGE_USAGE_=
|
|
ord(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) or
|
|
ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT) or
|
|
ord(VK_IMAGE_USAGE_SAMPLED_BIT);
|
|
|
|
VK_IMAGE_USAGE_DEFAULT=
|
|
VK_IMAGE_USAGE_ or
|
|
ord(VK_IMAGE_USAGE_STORAGE_BIT);
|
|
|
|
VK_IMAGE_USAGE_DEFAULT_COLOR=
|
|
VK_IMAGE_USAGE_ or
|
|
ord(VK_IMAGE_USAGE_STORAGE_BIT) or
|
|
ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
|
|
|
VK_IMAGE_USAGE_DEFAULT_DEPTH=
|
|
VK_IMAGE_USAGE_ or
|
|
ord(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
|
|
|
function GET_VK_IMAGE_USAGE_DEFAULT(cformat:TVkFormat):TVkFlags;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_R4G4_UNORM_PACK8..
|
|
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
|
|
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32..
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32,
|
|
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32,
|
|
|
|
//VK_FORMAT_B10G11R11_UFLOAT_PACK32..
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
|
Result:=VK_IMAGE_USAGE_DEFAULT;
|
|
|
|
VK_FORMAT_D16_UNORM..
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result:=VK_IMAGE_USAGE_DEFAULT_DEPTH;
|
|
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK:
|
|
Result:=VK_IMAGE_USAGE_DEFAULT;
|
|
|
|
else
|
|
Result:=VK_IMAGE_USAGE_DEFAULT_COLOR;
|
|
end;
|
|
end;
|
|
|
|
function GET_VK_IMAGE_USAGE_ATTACHMENT(cformat:TVkFormat):TVkFlags;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_R4G4_UNORM_PACK8..
|
|
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
|
|
|
|
VK_FORMAT_A8B8G8R8_UNORM_PACK32..
|
|
VK_FORMAT_A2B10G10R10_SINT_PACK32,
|
|
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32,
|
|
|
|
VK_FORMAT_B10G11R11_UFLOAT_PACK32..
|
|
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
|
Result:=ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
|
|
|
VK_FORMAT_D16_UNORM..
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result:=ord(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
|
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK:
|
|
Result:=0; //prohibited
|
|
|
|
else
|
|
Result:=ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
|
end;
|
|
end;
|
|
|
|
function GET_VK_IMAGE_CREATE_DEFAULT(cformat:TVkFormat):TVkFlags;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_BC1_RGB_UNORM_BLOCK..
|
|
VK_FORMAT_BC7_SRGB_BLOCK:
|
|
Result:=ord(VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) or
|
|
ord(VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) or
|
|
ord(VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT);
|
|
|
|
else
|
|
Result:=ord(VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) or
|
|
ord(VK_IMAGE_CREATE_EXTENDED_USAGE_BIT);
|
|
end;
|
|
end;
|
|
|
|
procedure FixToNormalizedTiling(var tiling:TvTiling); inline;
|
|
begin
|
|
case tiling.idx of
|
|
9,13,27:tiling.idx:=5;
|
|
14,28:tiling.idx:=10;
|
|
16,29:tiling.idx:=11;
|
|
17,30:tiling.idx:=12;
|
|
else;
|
|
end;
|
|
end;
|
|
|
|
Function GetNormalizedParams(const key:TvImageKey):TvImageKeyParams;
|
|
begin
|
|
Result:=key.params;
|
|
|
|
if IsTexelFormat(key.cformat) then
|
|
begin
|
|
Result.width :=(Result.width +3) shr 2;
|
|
Result.height:=(Result.height+3) shr 2;
|
|
end;
|
|
|
|
FixToNormalizedTiling(Result.tiling);
|
|
|
|
Result.pitch :=0;
|
|
Result.pad_width :=0;
|
|
Result.pad_height:=0;
|
|
end;
|
|
|
|
Function CompareNormalized(const a,b:TvImageKey):Integer;
|
|
begin
|
|
//1 Addr
|
|
Result:=Integer(a.Addr>b.Addr)-Integer(a.Addr<b.Addr);
|
|
if (Result<>0) then Exit;
|
|
//1 Stencil
|
|
Result:=Integer(a.Addr2>b.Addr2)-Integer(a.Addr2<b.Addr2);
|
|
if (Result<>0) then Exit;
|
|
//2 cformat
|
|
Result:=getFormatSize(a.cformat)-getFormatSize(b.cformat);
|
|
if (Result<>0) then Exit;
|
|
//3 params
|
|
Result:=CompareByte(GetNormalizedParams(a),GetNormalizedParams(b),SizeOf(TvImageKeyParams));
|
|
end;
|
|
|
|
Function GetVkFormatStr(cformat:TVkFormat):RawByteString;
|
|
begin
|
|
case cformat of
|
|
VK_FORMAT_R10G11B11_UFLOAT_FAKE32:Result:='R10G11B11_UFLOAT_FAKE32';
|
|
{$I VK_FORMAT_STR.inc}
|
|
else
|
|
Result:='0x'+HexStr(ord(cformat),8);
|
|
end;
|
|
end;
|
|
|
|
//
|
|
|
|
Procedure TvFramebufferImagelessKey.SetRenderPass(r:TvRenderPass);
|
|
begin
|
|
FRenderPass:=r;
|
|
end;
|
|
|
|
Procedure TvFramebufferImagelessKey.SetSize(Size:TVkExtent2D);
|
|
begin
|
|
FWidth :=Size.width;
|
|
FHeight:=Size.height;
|
|
FLayers:=1;
|
|
end;
|
|
|
|
Procedure TvFramebufferImagelessKey.AddImageAt(Key:TvImageKey);
|
|
begin
|
|
if (FImagesCount>=Length(FImages)) then Exit;
|
|
|
|
if (Key.params.width>FWidth) then
|
|
begin
|
|
FWidth:=Key.params.width;
|
|
end;
|
|
|
|
if (Key.params.height>FHeight) then
|
|
begin
|
|
FHeight:=Key.params.height;
|
|
end;
|
|
|
|
if (Key.params.layerCount>FLayers) then
|
|
begin
|
|
FLayers:=Key.params.layerCount;
|
|
end;
|
|
|
|
with FImages[FImagesCount] do
|
|
begin
|
|
cformat :=Key.cformat;
|
|
width :=Key.params.width;
|
|
height :=Key.params.height;
|
|
layerCount:=key.params.layerCount;
|
|
end;
|
|
|
|
Inc(FImagesCount);
|
|
end;
|
|
|
|
Procedure TvFramebufferImagelessKey.Export(var F:AvFramebufferAttach);
|
|
var
|
|
cformat:TVkFormat;
|
|
MUTABLE:PVkFormat;
|
|
i:Word;
|
|
begin
|
|
|
|
if (FImagesCount<>0) then
|
|
For i:=0 to FImagesCount-1 do
|
|
begin
|
|
cformat:=FImages[i].cformat;
|
|
MUTABLE:=GET_VK_IMAGE_MUTABLE(cformat);
|
|
|
|
with F[i] do
|
|
begin
|
|
sType :=VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO;
|
|
pNext :=nil;
|
|
flags :=GET_VK_IMAGE_CREATE_DEFAULT (cformat);
|
|
usage :=GET_VK_IMAGE_USAGE_ATTACHMENT(cformat);
|
|
width :=FImages[i].width;
|
|
height :=FImages[i].height;
|
|
layerCount :=FImages[i].layerCount;
|
|
viewFormatCount:=GET_FORMATS_LEN(MUTABLE);
|
|
pViewFormats :=MUTABLE;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
///
|
|
|
|
function TvFramebufferImageless.IsImageless:Boolean;
|
|
begin
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvFramebufferImageless.Compile:Boolean;
|
|
var
|
|
r:TVkResult;
|
|
info:TVkFramebufferCreateInfo;
|
|
imgs:TVkFramebufferAttachmentsCreateInfo;
|
|
fatt:AvFramebufferAttach;
|
|
begin
|
|
Result:=False;
|
|
if (FHandle<>VK_NULL_HANDLE) then Exit(True);
|
|
|
|
if (Key.FRenderPass=nil) then Exit;
|
|
if (Key.FRenderPass.FHandle=VK_NULL_HANDLE) then Exit;
|
|
if (Key.FImagesCount=0) then Exit;
|
|
if (Key.FWidth=0) or (Key.FHeight=0) then Exit;
|
|
|
|
info:=Default(TVkFramebufferCreateInfo);
|
|
info.sType :=VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
info.renderPass :=Key.FRenderPass.FHandle;
|
|
info.attachmentCount:=Key.FImagesCount;
|
|
info.width :=Key.FWidth;
|
|
info.height :=Key.FHeight;
|
|
info.layers :=Key.FLayers;
|
|
info.flags :=ord(VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT);
|
|
info.pAttachments :=nil;
|
|
|
|
Key.Export(fatt);
|
|
|
|
imgs:=Default(TVkFramebufferAttachmentsCreateInfo);
|
|
imgs.sType:=VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO;
|
|
imgs.attachmentImageInfoCount:=Key.FImagesCount;
|
|
imgs.pAttachmentImageInfos :=@fatt;
|
|
|
|
info.pNext:=@imgs;
|
|
|
|
r:=vkCreateFramebuffer(Device.FHandle,@info,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateFramebuffer');
|
|
end;
|
|
|
|
Result:=(r=VK_SUCCESS);
|
|
end;
|
|
|
|
///
|
|
|
|
Procedure TvFramebufferBinded.AcquireImageViews;
|
|
var
|
|
i:Word;
|
|
begin
|
|
if (Key.FImagesCount<>0) then
|
|
For i:=0 to Key.FImagesCount-1 do
|
|
if (Key.FImages[i]<>nil) then
|
|
if (not FAcquire[i]) then
|
|
begin
|
|
Key.FImages[i].Acquire(Self);
|
|
FAcquire[i]:=True;
|
|
end;
|
|
end;
|
|
|
|
Procedure TvFramebufferBinded.ReleaseImageViews;
|
|
var
|
|
i:Word;
|
|
begin
|
|
if (Key.FImagesCount<>0) then
|
|
For i:=0 to Key.FImagesCount-1 do
|
|
if (Key.FImages[i]<>nil) then
|
|
if (FAcquire[i]) then
|
|
begin
|
|
Key.FImages[i].Release(Self);
|
|
FAcquire[i]:=False;
|
|
end;
|
|
end;
|
|
|
|
function TvFramebufferBinded.Compile:Boolean;
|
|
var
|
|
i:TVkUInt32;
|
|
r:TVkResult;
|
|
info:TVkFramebufferCreateInfo;
|
|
FImageViews:AvImageViews;
|
|
begin
|
|
Result:=False;
|
|
if (FHandle<>VK_NULL_HANDLE) then Exit(True);
|
|
|
|
if (Key.FRenderPass=nil) then Exit;
|
|
if (Key.FRenderPass.FHandle=VK_NULL_HANDLE) then Exit;
|
|
if (Key.FImagesCount=0) then Exit;
|
|
if (Key.FWidth=0) or (Key.FHeight=0) then Exit;
|
|
|
|
AcquireImageViews;
|
|
|
|
info:=Default(TVkFramebufferCreateInfo);
|
|
info.sType :=VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
info.renderPass :=Key.FRenderPass.FHandle;
|
|
info.attachmentCount:=Key.FImagesCount;
|
|
info.width :=Key.FWidth;
|
|
info.height :=Key.FHeight;
|
|
info.layers :=Key.FLayers;
|
|
|
|
For i:=0 to Key.FImagesCount-1 do
|
|
begin
|
|
if (Key.FImages[i]<>nil) then
|
|
begin
|
|
FImageViews[i]:=Key.FImages[i].FHandle;
|
|
end;
|
|
end;
|
|
|
|
info.pAttachments:=@FImageViews;
|
|
|
|
r:=vkCreateFramebuffer(Device.FHandle,@info,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateFramebuffer');
|
|
end;
|
|
|
|
Result:=(r=VK_SUCCESS);
|
|
end;
|
|
|
|
Destructor TvFramebufferBinded.Destroy;
|
|
begin
|
|
ReleaseImageViews;
|
|
inherited;
|
|
end;
|
|
|
|
Constructor TvSwapChain.Create(Surface:TvSurface;mode:Integer;imageUsage:TVkImageUsageFlags);
|
|
var
|
|
queueFamilyIndices:array[0..1] of TVkUInt32;
|
|
cinfo:TVkSwapchainCreateInfoKHR;
|
|
r:TVkResult;
|
|
i,count:TVkUInt32;
|
|
cimg:TVkImageViewCreateInfo;
|
|
FImage:array of TVkImage;
|
|
FView:TVkImageView;
|
|
begin
|
|
FSurface:=Surface;
|
|
|
|
Case mode of
|
|
1,2,3:;
|
|
else
|
|
mode:=1;
|
|
end;
|
|
|
|
FSize:=Surface.GetSize;
|
|
if (FSize.width=0) or (FSize.height=0) then Exit;
|
|
|
|
cinfo:=Default(TVkSwapchainCreateInfoKHR);
|
|
cinfo.sType :=VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
|
cinfo.surface :=FSurface.FHandle;
|
|
cinfo.minImageCount :=2;
|
|
cinfo.imageFormat :=FSurface.Fformat.format;
|
|
cinfo.imageColorSpace :=FSurface.Fformat.colorSpace;
|
|
cinfo.imageExtent :=FSize;
|
|
cinfo.imageArrayLayers:=1;
|
|
cinfo.imageUsage :=imageUsage or ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
|
|
|
if (VulkanApp.FGFamily<>Surface.FPFamily) then
|
|
begin
|
|
queueFamilyIndices[0]:=VulkanApp.FGFamily;
|
|
queueFamilyIndices[1]:=Surface.FPFamily;
|
|
cinfo.imageSharingMode :=VK_SHARING_MODE_CONCURRENT;
|
|
cinfo.queueFamilyIndexCount :=2;
|
|
cinfo.pQueueFamilyIndices :=@queueFamilyIndices;
|
|
end else
|
|
begin
|
|
cinfo.imageSharingMode :=VK_SHARING_MODE_EXCLUSIVE;
|
|
cinfo.queueFamilyIndexCount :=0;
|
|
cinfo.pQueueFamilyIndices :=nil;
|
|
end;
|
|
|
|
cinfo.preTransform :=VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
|
cinfo.compositeAlpha:=VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
|
cinfo.presentMode :=Surface.FModes[mode-1];
|
|
cinfo.clipped :=VK_TRUE;
|
|
cinfo.oldSwapchain :=VK_NULL_HANDLE;
|
|
|
|
r:=vkCreateSwapchainKHR(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateSwapchainKHR:',r);
|
|
Exit;
|
|
end;
|
|
|
|
count:=1;
|
|
Case mode of
|
|
1,2:count:=2;
|
|
3:count:=3;
|
|
end;
|
|
|
|
SetLength(FImage,count);
|
|
SetLength(FImages,count);
|
|
|
|
r:=vkGetSwapchainImagesKHR(Device.FHandle,FHandle,@count,@FImage[0]);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkGetSwapchainImagesKHR:',r);
|
|
Exit;
|
|
end;
|
|
|
|
cimg:=Default(TVkImageViewCreateInfo);
|
|
cimg.sType :=VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
cimg.viewType :=VK_IMAGE_VIEW_TYPE_2D;
|
|
cimg.format :=Surface.Fformat.format;
|
|
cimg.components.r:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
cimg.components.g:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
cimg.components.b:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
cimg.components.a:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
cimg.subresourceRange.aspectMask :=TVkImageAspectFlags(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
cimg.subresourceRange.baseMipLevel :=0;
|
|
cimg.subresourceRange.levelCount :=1;
|
|
cimg.subresourceRange.baseArrayLayer:=0;
|
|
cimg.subresourceRange.layerCount :=1;
|
|
|
|
For i:=0 to count-1 do
|
|
begin
|
|
cimg.image:=FImage[i];
|
|
FView:=VK_NULL_HANDLE;
|
|
r:=vkCreateImageView(Device.FHandle,@cimg,nil,@FView);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateImageView:',r);
|
|
Exit;
|
|
end;
|
|
FImages[i]:=TvSwapChainImage.Create;
|
|
FImages[i].FHandle:=FImage[i];
|
|
FImages[i].FView :=FView;
|
|
FImages[i].Barrier.Init;
|
|
end;
|
|
end;
|
|
|
|
Destructor TvSwapChain.Destroy;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
For i:=0 to High(FImages) do
|
|
begin
|
|
if (FImages[i].FView<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyImageView(Device.FHandle,FImages[i].FView,nil);
|
|
end;
|
|
FImages[i].Free;
|
|
end;
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroySwapchainKHR(Device.FHandle,FHandle,nil);
|
|
end;
|
|
end;
|
|
|
|
function TvCustomImage.is_invalid:Boolean;
|
|
begin
|
|
Result:=(FHandle=VK_NULL_HANDLE);
|
|
end;
|
|
|
|
procedure TvCustomImage.FreeHandle;
|
|
var
|
|
F:TVkImage;
|
|
begin
|
|
F:=System.InterlockedExchange64(FHandle,VK_NULL_HANDLE);
|
|
if (F<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyImage(Device.FHandle,F,nil);
|
|
end;
|
|
end;
|
|
|
|
Destructor TvCustomImage.Destroy;
|
|
begin
|
|
FreeHandle;
|
|
//
|
|
UnBindMem(True);
|
|
//
|
|
inherited;
|
|
end;
|
|
|
|
function TvCustomImage.GetRequirements:TVkMemoryRequirements;
|
|
begin
|
|
Result:=Default(TVkMemoryRequirements);
|
|
vkGetImageMemoryRequirements(Device.FHandle,FHandle,@Result);
|
|
end;
|
|
|
|
function TvCustomImage.GetDedicatedAllocation:Boolean;
|
|
var
|
|
info:TVkImageMemoryRequirementsInfo2;
|
|
rmem:TVkMemoryRequirements2;
|
|
rded:TVkMemoryDedicatedRequirements;
|
|
begin
|
|
Result:=false;
|
|
if Pointer(vkGetImageMemoryRequirements2)=nil then Exit;
|
|
info:=Default(TVkImageMemoryRequirementsInfo2);
|
|
info.sType:=VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
|
|
info.image:=FHandle;
|
|
rmem:=Default(TVkMemoryRequirements2);
|
|
rmem.sType:=VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
|
rded:=Default(TVkMemoryDedicatedRequirements);
|
|
rded.sType:=VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
|
rmem.pNext:=@rded;
|
|
vkGetImageMemoryRequirements2(Device.FHandle,@info,@rmem);
|
|
Result:=(rded.requiresDedicatedAllocation<>VK_FALSE) or
|
|
(rded.prefersDedicatedAllocation <>VK_FALSE);
|
|
end;
|
|
|
|
function TvCustomImage.Compile(ext:Pointer):Boolean;
|
|
var
|
|
cinfo:TVkImageCreateInfo;
|
|
clist:TVkImageFormatListCreateInfo;
|
|
MUTABLE:PVkFormat;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=False;
|
|
|
|
if (FHandle<>VK_NULL_HANDLE) then Exit(True);
|
|
|
|
cinfo:=GetImageInfo;
|
|
cinfo.format:=vkFixFormatSupport(cinfo.format,cinfo.tiling,cinfo.usage);
|
|
|
|
//save real format
|
|
FFormat:=cinfo.format;
|
|
|
|
cinfo.pNext:=@clist;
|
|
|
|
MUTABLE:=GET_VK_IMAGE_MUTABLE(cinfo.format);
|
|
|
|
clist:=Default(TVkImageFormatListCreateInfo);
|
|
clist.sType:=VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO;
|
|
|
|
clist.viewFormatCount:=GET_FORMATS_LEN(MUTABLE);
|
|
clist.pViewFormats :=MUTABLE;
|
|
|
|
clist.pNext:=ext;
|
|
|
|
r:=vkCreateImage(Device.FHandle,@cinfo,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateImage:',r);
|
|
Exit;
|
|
end;
|
|
|
|
FSize:=GetRequirements.size;
|
|
|
|
Result:=True;
|
|
end;
|
|
|
|
function TvCustomImage.BindMem(P:TvPointer):TVkResult;
|
|
var
|
|
B:TvPointer;
|
|
begin
|
|
B:=P.Acquire;
|
|
if (B.FMemory<>nil) then //try Acquire
|
|
begin
|
|
//
|
|
Result:=vkBindImageMemory(Device.FHandle,FHandle,B.FMemory.FHandle,B.FOffset);
|
|
//
|
|
if (Result=VK_SUCCESS) then
|
|
begin
|
|
B.FMemory.AddDependence(@Self.OnReleaseMem);
|
|
FBind:=B;
|
|
end;
|
|
//
|
|
B.Release; //release Acquire
|
|
end else
|
|
begin
|
|
Result:=VK_ERROR_UNKNOWN;
|
|
end;
|
|
|
|
if (Result<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(stderr,'Error BindMem:',Result,' To:0x',HexStr(FHandle,16));
|
|
vMemory.MemManager._print_devs;
|
|
vMemory.MemManager._print_host;
|
|
end;
|
|
end;
|
|
|
|
procedure TvCustomImage.UnBindMem(do_free:Boolean);
|
|
var
|
|
B:TvPointer;
|
|
H:Integer;
|
|
begin
|
|
B.FMemory:=TvDeviceMemory(System.InterlockedExchange(Pointer(FBind.FMemory),nil));
|
|
B.FOffset:=FBind.FOffset;
|
|
H:=System.InterlockedExchangeAdd(FHold,0);
|
|
if (B.FMemory<>nil) then
|
|
begin
|
|
if do_free then
|
|
begin
|
|
B.FMemory.DelDependence(@Self.OnReleaseMem);
|
|
while (H<>0) do
|
|
begin
|
|
B.Drop;
|
|
Dec(H);
|
|
end;
|
|
MemManager.FreeMemory(B);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TvCustomImage.Hold(Sender:TObject):Boolean;
|
|
begin
|
|
Result:=FBind.Hold;
|
|
if Result then
|
|
begin
|
|
Result:=inherited;
|
|
if not Result then
|
|
begin
|
|
FBind.Drop;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TvCustomImage.Drop(Sender:TObject):Boolean;
|
|
begin
|
|
Result:=FBind.Drop;
|
|
if Result then
|
|
begin
|
|
Result:=inherited;
|
|
end;
|
|
end;
|
|
|
|
function TvCustomImage.OnReleaseMem(Sender:TObject):Boolean;
|
|
begin
|
|
FreeHandle;
|
|
//
|
|
UnBindMem(False);
|
|
//
|
|
Result:=True;
|
|
end;
|
|
|
|
procedure TvCustomImage.SetObjectName(const name:RawByteString);
|
|
begin
|
|
FName:=name;
|
|
DebugReport.SetObjectName(VK_OBJECT_TYPE_IMAGE,FHandle,PChar(name));
|
|
end;
|
|
|
|
///
|
|
|
|
procedure _test_and_set_to(var new:TVkFlags;
|
|
test:TVkFlags;
|
|
val_test:TVkImageUsageFlagBits;
|
|
val_sets:TVkFormatFeatureFlagBits);
|
|
begin
|
|
if ((test and ord(val_test))<>0) then
|
|
begin
|
|
new:=new or ord(val_sets);
|
|
end;
|
|
end;
|
|
|
|
function vkGetFormatSupport(format:TVkFormat;tiling:TVkImageTiling;usage:TVkImageUsageFlags):Boolean;
|
|
var
|
|
prop:TVkFormatProperties;
|
|
test:TVkFormatFeatureFlags;
|
|
begin
|
|
Result:=False;
|
|
|
|
prop:=Default(TVkFormatProperties);
|
|
vkGetPhysicalDeviceFormatProperties(
|
|
VulkanApp.FPhysicalDevice,
|
|
format,
|
|
@prop);
|
|
|
|
test:=0;
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_TRANSFER_SRC_BIT ,VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_TRANSFER_DST_BIT ,VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_SAMPLED_BIT ,VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_STORAGE_BIT ,VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
|
_test_and_set_to(test,usage,VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT ,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
|
|
|
|
Case tiling of
|
|
VK_IMAGE_TILING_OPTIMAL:
|
|
begin
|
|
Result:=(prop.optimalTilingFeatures and test)=test;
|
|
end;
|
|
VK_IMAGE_TILING_LINEAR:
|
|
begin
|
|
Result:=(prop.linearTilingFeatures and test)=test;
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
end;
|
|
|
|
//D16_UNORM_S8_UINT -> D24_UNORM_S8_UINT -> D32_SFLOAT_S8_UINT
|
|
//D16_UNORM -> X8_D24_UNORM_PACK32 -> D32_SFLOAT
|
|
|
|
function vkFixFormatSupport(format:TVkFormat;tiling:TVkImageTiling;usage:TVkImageUsageFlags):TVkFormat;
|
|
begin
|
|
Result:=format;
|
|
|
|
repeat
|
|
|
|
Case Result of
|
|
|
|
VK_FORMAT_D16_UNORM_S8_UINT:
|
|
begin
|
|
if vkGetFormatSupport(Result,tiling,usage) then Break;
|
|
Result:=VK_FORMAT_D24_UNORM_S8_UINT;
|
|
end;
|
|
|
|
VK_FORMAT_D24_UNORM_S8_UINT:
|
|
begin
|
|
if vkGetFormatSupport(Result,tiling,usage) then Break;
|
|
Result:=VK_FORMAT_D32_SFLOAT_S8_UINT;
|
|
end;
|
|
|
|
VK_FORMAT_D16_UNORM:
|
|
begin
|
|
if vkGetFormatSupport(Result,tiling,usage) then Break;
|
|
Result:=VK_FORMAT_X8_D24_UNORM_PACK32;
|
|
end;
|
|
|
|
VK_FORMAT_X8_D24_UNORM_PACK32:
|
|
begin
|
|
if vkGetFormatSupport(Result,tiling,usage) then Break;
|
|
Result:=VK_FORMAT_D32_SFLOAT;
|
|
end;
|
|
|
|
else
|
|
Break;
|
|
end;
|
|
|
|
until false;
|
|
|
|
end;
|
|
|
|
Constructor TvImage.Create(format:TVkFormat;extent:TVkExtent3D;usage:TVkFlags;flags:TVkImageCreateFlags;ext:Pointer=nil);
|
|
begin
|
|
FFormat:=format;
|
|
FExtent:=extent;
|
|
FUsage:=usage;
|
|
Fflags:=flags;
|
|
Barrier.Init;
|
|
Compile(ext);
|
|
end;
|
|
|
|
function TvImage.GetImageInfo:TVkImageCreateInfo;
|
|
begin
|
|
Result:=Default(TVkImageCreateInfo);
|
|
Result.format:=FFormat;
|
|
Result.extent:=FExtent;
|
|
Result.usage :=FUsage;
|
|
Result.flags :=Fflags;
|
|
end;
|
|
|
|
function TvImage.NewView:TvImageView;
|
|
begin
|
|
Result:=NewViewF(FFormat);
|
|
end;
|
|
|
|
function TvImage.NewViewF(Format:TVkFormat):TvImageView;
|
|
var
|
|
cinfo:TVkImageViewCreateInfo;
|
|
FImg:TVkImageView;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=nil;
|
|
cinfo:=GetViewInfo;
|
|
cinfo.image :=FHandle;
|
|
cinfo.format:=Format;
|
|
FImg:=VK_NULL_HANDLE;
|
|
r:=vkCreateImageView(Device.FHandle,@cinfo,nil,@FImg);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateImageView:',r);
|
|
Exit;
|
|
end;
|
|
Result:=TvImageView.Create;
|
|
Result.FHandle:=FImg;
|
|
end;
|
|
|
|
procedure TvSwapChainImage.PushBarrier(cmd:TVkCommandBuffer;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags);
|
|
begin
|
|
if (cmd=VK_NULL_HANDLE) then Exit;
|
|
|
|
Barrier.Push(cmd,
|
|
nil,
|
|
FHandle,
|
|
range,
|
|
dstAccessMask,
|
|
newImageLayout,
|
|
dstStageMask);
|
|
end;
|
|
|
|
procedure TvImage.PushBarrier(cmd:TVkCommandBuffer;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags);
|
|
begin
|
|
if (cmd=VK_NULL_HANDLE) then Exit;
|
|
|
|
Barrier.Push(cmd,
|
|
nil,
|
|
FHandle,
|
|
range,
|
|
dstAccessMask,
|
|
newImageLayout,
|
|
dstStageMask);
|
|
end;
|
|
|
|
procedure TvImageView.SetObjectName(const name:RawByteString);
|
|
begin
|
|
FName:=name;
|
|
DebugReport.SetObjectName(VK_OBJECT_TYPE_IMAGE_VIEW,FHandle,PChar(name));
|
|
end;
|
|
|
|
Destructor TvImageView.Destroy;
|
|
begin
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyImageView(Device.FHandle,FHandle,nil);
|
|
end;
|
|
end;
|
|
|
|
function TvHostImage1D.GetImageInfo:TVkImageCreateInfo;
|
|
begin
|
|
Result:=inherited;
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
Result.imageType :=VK_IMAGE_TYPE_1D;
|
|
Result.arrayLayers :=1;
|
|
Result.mipLevels :=1;
|
|
Result.initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
Result.samples :=VK_SAMPLE_COUNT_1_BIT;
|
|
Result.tiling :=VK_IMAGE_TILING_LINEAR;
|
|
end;
|
|
|
|
function TvHostImage2D.GetImageInfo:TVkImageCreateInfo;
|
|
begin
|
|
Result:=inherited;
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
Result.imageType :=VK_IMAGE_TYPE_2D;
|
|
Result.arrayLayers :=1;
|
|
Result.mipLevels :=1;
|
|
Result.initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
Result.samples :=VK_SAMPLE_COUNT_1_BIT;
|
|
Result.tiling :=VK_IMAGE_TILING_LINEAR;
|
|
end;
|
|
|
|
//
|
|
|
|
function TvDeviceImage1D.GetImageInfo:TVkImageCreateInfo;
|
|
begin
|
|
Result:=inherited;
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
Result.imageType :=VK_IMAGE_TYPE_1D;
|
|
Result.arrayLayers :=1;
|
|
Result.mipLevels :=1;
|
|
Result.initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
Result.samples :=VK_SAMPLE_COUNT_1_BIT;
|
|
Result.tiling :=VK_IMAGE_TILING_OPTIMAL;
|
|
end;
|
|
|
|
function TvDeviceImage1D.GetViewInfo:TVkImageViewCreateInfo;
|
|
begin
|
|
Result:=Default(TVkImageViewCreateInfo);
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
Result.viewType :=VK_IMAGE_VIEW_TYPE_1D;
|
|
Result.format :=FFormat;
|
|
Result.components.r:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.g:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.b:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.a:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
|
|
Case FFormat of
|
|
VK_FORMAT_S8_UINT:
|
|
Result.subresourceRange.aspectMask :=ord(VK_IMAGE_ASPECT_STENCIL_BIT);
|
|
|
|
VK_FORMAT_D16_UNORM,
|
|
VK_FORMAT_X8_D24_UNORM_PACK32,
|
|
VK_FORMAT_D32_SFLOAT:
|
|
Result.subresourceRange.aspectMask :=ord(VK_IMAGE_ASPECT_DEPTH_BIT);
|
|
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result.subresourceRange.aspectMask :=ord(VK_IMAGE_ASPECT_DEPTH_BIT) or ord(VK_IMAGE_ASPECT_STENCIL_BIT);
|
|
|
|
else
|
|
Result.subresourceRange.aspectMask :=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
end;
|
|
|
|
Result.subresourceRange.baseMipLevel :=0;
|
|
Result.subresourceRange.levelCount :=1;
|
|
Result.subresourceRange.baseArrayLayer:=0;
|
|
Result.subresourceRange.layerCount :=1;
|
|
end;
|
|
|
|
//
|
|
|
|
function TvDeviceImage2D.GetImageInfo:TVkImageCreateInfo;
|
|
begin
|
|
Result:=inherited;
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
|
Result.imageType :=VK_IMAGE_TYPE_2D;
|
|
Result.arrayLayers :=1;
|
|
Result.mipLevels :=1;
|
|
Result.initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
Result.samples :=VK_SAMPLE_COUNT_1_BIT;
|
|
Result.tiling :=VK_IMAGE_TILING_OPTIMAL;
|
|
end;
|
|
|
|
function TvDeviceImage2D.GetViewInfo:TVkImageViewCreateInfo;
|
|
begin
|
|
Result:=Default(TVkImageViewCreateInfo);
|
|
Result.sType :=VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
Result.viewType :=VK_IMAGE_VIEW_TYPE_2D;
|
|
Result.format :=FFormat;
|
|
Result.components.r:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.g:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.b:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
Result.components.a:=VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
|
|
Result.subresourceRange.aspectMask :=GetAspectMaskByFormat(FFormat);
|
|
Result.subresourceRange.baseMipLevel :=0;
|
|
Result.subresourceRange.levelCount :=1;
|
|
Result.subresourceRange.baseArrayLayer:=0;
|
|
Result.subresourceRange.layerCount :=1;
|
|
end;
|
|
|
|
Function GetAspectMaskByFormat(cformat:TVkFormat):DWORD;
|
|
begin
|
|
Case cformat of
|
|
VK_FORMAT_S8_UINT:
|
|
Result :=ord(VK_IMAGE_ASPECT_STENCIL_BIT);
|
|
|
|
VK_FORMAT_D16_UNORM,
|
|
VK_FORMAT_X8_D24_UNORM_PACK32,
|
|
VK_FORMAT_D32_SFLOAT:
|
|
Result :=ord(VK_IMAGE_ASPECT_DEPTH_BIT);
|
|
|
|
VK_FORMAT_D16_UNORM_S8_UINT,
|
|
VK_FORMAT_D24_UNORM_S8_UINT,
|
|
VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
Result :=ord(VK_IMAGE_ASPECT_DEPTH_BIT) or ord(VK_IMAGE_ASPECT_STENCIL_BIT);
|
|
|
|
else
|
|
Result :=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
end;
|
|
end;
|
|
|
|
{
|
|
WW VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
|
RR VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
|
|
|
RW VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
|
|
WR VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
|
|
|
|
W_ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL
|
|
R_ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL
|
|
|
|
_W VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
|
|
_R VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL
|
|
}
|
|
|
|
Function GetDepthStencilInitLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
var
|
|
IMAGE_USAGE:Byte;
|
|
begin
|
|
IMAGE_USAGE:=(DEPTH_USAGE or STENCIL_USAGE);
|
|
//
|
|
if ((IMAGE_USAGE and TM_READ)=0) then
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
end else
|
|
if ((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) then
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
end else
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
end;
|
|
end;
|
|
|
|
Function GetDepthStencilSendLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
var
|
|
IMAGE_USAGE:Byte;
|
|
begin
|
|
IMAGE_USAGE:=(DEPTH_USAGE or STENCIL_USAGE);
|
|
//
|
|
if ((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) then
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
end else
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
end;
|
|
end;
|
|
|
|
Function GetDepthStencilAccessAttachMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags;
|
|
var
|
|
IMAGE_USAGE:Byte;
|
|
begin
|
|
IMAGE_USAGE:=(DEPTH_USAGE or STENCIL_USAGE);
|
|
//
|
|
Result:=(ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) *ord((IMAGE_USAGE and TM_READ )<>0) ) or
|
|
(ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)*ord((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) );
|
|
end;
|
|
|
|
function GetColorSendLayout(IMAGE_USAGE:Byte):TVkImageLayout;
|
|
begin
|
|
if ((IMAGE_USAGE and TM_MIXED)<>0) then
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_GENERAL;
|
|
end else
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
end;
|
|
end;
|
|
|
|
Function GetColorAccessAttachMask(IMAGE_USAGE:Byte):TVkAccessFlags;
|
|
begin
|
|
Result:=(ord(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) *ord((IMAGE_USAGE and TM_READ )<>0) ) or
|
|
(ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)*ord((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) );
|
|
end;
|
|
|
|
Procedure TvImageBarrier.Init({_image:TVkImage;_sub:TVkImageSubresourceRange});
|
|
begin
|
|
//image :=_image;
|
|
//range :=_sub;
|
|
AccessMask:=ord(VK_ACCESS_NONE_KHR);
|
|
ImgLayout :=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
StageMask :=ord(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
|
end;
|
|
|
|
function IsRead(dstAccessMask:TVkAccessFlags):Boolean; inline;
|
|
begin
|
|
Result:=dstAccessMask and
|
|
(
|
|
ord(VK_ACCESS_INDIRECT_COMMAND_READ_BIT) or
|
|
ord(VK_ACCESS_INDEX_READ_BIT) or
|
|
ord(VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT) or
|
|
ord(VK_ACCESS_UNIFORM_READ_BIT) or
|
|
ord(VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) or
|
|
ord(VK_ACCESS_SHADER_READ_BIT) or
|
|
ord(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) or
|
|
ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) or
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT) or
|
|
ord(VK_ACCESS_HOST_READ_BIT) or
|
|
ord(VK_ACCESS_MEMORY_READ_BIT)
|
|
)<>0;
|
|
end;
|
|
|
|
function IsWrite(dstAccessMask:TVkAccessFlags):Boolean; inline;
|
|
begin
|
|
Result:=dstAccessMask and
|
|
(
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT) or
|
|
ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) or
|
|
ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) or
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT) or
|
|
ord(VK_ACCESS_HOST_WRITE_BIT) or
|
|
ord(VK_ACCESS_MEMORY_WRITE_BIT)
|
|
)<>0;
|
|
end;
|
|
|
|
const
|
|
ALL_GRAPHICS_STAGE:TVkPipelineStageFlags=(
|
|
ord(VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT) or
|
|
ord(VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT) or
|
|
ord(VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT) or
|
|
ord(VK_PIPELINE_STAGE_VERTEX_INPUT_BIT) or
|
|
ord(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) or
|
|
ord(VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT) or
|
|
ord(VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT) or
|
|
ord(VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) or
|
|
ord(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) or
|
|
ord(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT) or
|
|
ord(VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT) or
|
|
ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) or
|
|
ord(VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT) or
|
|
ord(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT) or
|
|
ord(VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) or
|
|
ord(VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT)
|
|
);
|
|
|
|
function ChangeStage(curr,next:TVkPipelineStageFlags):Boolean;
|
|
begin
|
|
if ((curr and ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))<>0) then
|
|
begin
|
|
curr:=(curr and (not ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))) or ALL_GRAPHICS_STAGE;
|
|
end;
|
|
|
|
if ((next and ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))<>0) then
|
|
begin
|
|
next:=(next and (not ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))) or ALL_GRAPHICS_STAGE;
|
|
end;
|
|
|
|
Result:=((curr and next)<>next);
|
|
end;
|
|
|
|
procedure _test_and_set_to(var str :RawByteString;
|
|
test :TVkAccessFlags;
|
|
bit_test:TVkAccessFlagBits;
|
|
bit_str :RawByteString);
|
|
begin
|
|
if ((test and ord(bit_test))<>0) then
|
|
begin
|
|
if (str='') then
|
|
begin
|
|
str:=bit_str;
|
|
end else
|
|
begin
|
|
str:=str + '|' + bit_str;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function GetAccessMaskStr(AccessMask:TVkAccessFlags):RawByteString;
|
|
begin
|
|
if (AccessMask=0) then Exit('NONE');
|
|
|
|
Result:='';
|
|
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_INDIRECT_COMMAND_READ_BIT ,'ICR');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_INDEX_READ_BIT ,'IR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT ,'VAR');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_UNIFORM_READ_BIT ,'UR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_INPUT_ATTACHMENT_READ_BIT ,'IAR');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_SHADER_READ_BIT ,'SR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_SHADER_WRITE_BIT ,'SW' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_COLOR_ATTACHMENT_READ_BIT ,'CAR');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ,'CAW');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT ,'DAR');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,'DAW');
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_TRANSFER_READ_BIT ,'TR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_TRANSFER_WRITE_BIT ,'TW' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_HOST_READ_BIT ,'HR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_HOST_WRITE_BIT ,'HW' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_MEMORY_READ_BIT ,'MR' );
|
|
_test_and_set_to(Result,AccessMask,VK_ACCESS_MEMORY_WRITE_BIT ,'MW' );
|
|
end;
|
|
|
|
function TvImageBarrier.Push(cmd:TVkCommandBuffer;
|
|
cb:t_push_cb;
|
|
image:TVkImage;
|
|
range:TVkImageSubresourceRange;
|
|
dstAccessMask:TVkAccessFlags;
|
|
newImageLayout:TVkImageLayout;
|
|
dstStageMask:TVkPipelineStageFlags):Boolean;
|
|
var
|
|
info:TVkImageMemoryBarrier;
|
|
begin
|
|
Result:=False;
|
|
|
|
//Writeln('Push:0x',HexStr(image,16),' ',HexStr(dstAccessMask,8),' ',(newImageLayout),' ',HexStr(dstStageMask,8));
|
|
|
|
//RAW
|
|
//WAR
|
|
//WAW
|
|
|
|
if (AccessMask<>dstAccessMask ) or
|
|
(ImgLayout <>newImageLayout) or
|
|
(ImgLayout =VK_IMAGE_LAYOUT_GENERAL) or
|
|
(newImageLayout=VK_IMAGE_LAYOUT_GENERAL) or
|
|
ChangeStage(StageMask,dstStageMask) or
|
|
|
|
(IsRead (AccessMask) and IsWrite(dstAccessMask)) or
|
|
(IsWrite(AccessMask) and IsRead (dstAccessMask)) or
|
|
(IsWrite(AccessMask) and IsWrite(dstAccessMask))
|
|
|
|
then
|
|
begin
|
|
Result:=True;
|
|
|
|
if (cb<>nil) then
|
|
begin
|
|
cmd:=cb();
|
|
end;
|
|
|
|
if (cmd=0) then Exit;
|
|
|
|
if (image=VK_NULL_HANDLE) then
|
|
begin
|
|
print_backtrace(StdErr,Get_pc_addr,get_frame,0);
|
|
end;
|
|
|
|
Writeln('Barrier:'#13#10,
|
|
' image =0x',HexStr(image,16),#13#10,
|
|
' srcAccessMask=',GetAccessMaskStr(AccessMask),#13#10,
|
|
' dstAccessMask=',GetAccessMaskStr(dstAccessMask),#13#10,
|
|
' oldLayout =' ,ImgLayout,#13#10,
|
|
' newLayout =' ,newImageLayout
|
|
);
|
|
|
|
info:=Default(TVkImageMemoryBarrier);
|
|
info.sType :=VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
info.srcAccessMask :=AccessMask;
|
|
info.dstAccessMask :=dstAccessMask;
|
|
info.oldLayout :=ImgLayout;
|
|
info.newLayout :=newImageLayout;
|
|
info.image :=image;
|
|
info.subresourceRange:=range;
|
|
|
|
vkCmdPipelineBarrier(cmd,
|
|
StageMask,
|
|
dstStageMask,
|
|
ord(VK_DEPENDENCY_BY_REGION_BIT),
|
|
0, nil,
|
|
0, nil,
|
|
1, @info);
|
|
|
|
AccessMask:=dstAccessMask;
|
|
ImgLayout :=newImageLayout;
|
|
StageMask :=dstStageMask;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|