mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-23 14:29:53 +00:00
1270 lines
34 KiB
ObjectPascal
1270 lines
34 KiB
ObjectPascal
unit vFlip;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes,
|
|
SysUtils,
|
|
ps4_libSceVideoOut,
|
|
vulkan,
|
|
vDevice,
|
|
vMemory,
|
|
vShader,
|
|
vPipeline,
|
|
vBuffer,
|
|
vImage,
|
|
vImageManager,
|
|
vCmdBuffer,
|
|
vRender;
|
|
|
|
type
|
|
TFlipCfg=packed object
|
|
gamma:array[0..3] of Single;
|
|
Width:array[0..1] of Integer;
|
|
end;
|
|
|
|
Tgamma=array[0..2] of Single;
|
|
|
|
TvFlip=class;
|
|
|
|
PvFlipBufferCursor=^TvFlipBufferCursor;
|
|
TvFlipBufferCursor=object
|
|
FSet:TvDescriptorSet;
|
|
PtrBuf :TvPointer;
|
|
HostBuf :TvBuffer;
|
|
pending:PDWORD;
|
|
procedure SetBuffer(hbuf:TvPointer);
|
|
Procedure Init(Flip:TvFlip);
|
|
Procedure Free;
|
|
function IsPrepare:Boolean;
|
|
Procedure SetPending(f:PDWORD);
|
|
end;
|
|
|
|
PvFlipBuffer=^TvFlipBuffer;
|
|
TvFlipBuffer=object
|
|
|
|
FSet:TvDescriptorSet;
|
|
|
|
//cmdfence:TvFence; //
|
|
//cmdbuf:TVkCommandBuffer; //
|
|
|
|
cmdbuf:TvCustomCmdBuffer;
|
|
|
|
Extent:TVkExtent3D;
|
|
|
|
PITCH,SIZE:DWORD;
|
|
|
|
DstImgNORM:TvImage; //
|
|
DstImgSRGB:TvImage; //
|
|
|
|
DevcMem:TvPointer; //
|
|
ImgViewDst:TvImageView; //
|
|
|
|
Addr:Pointer;
|
|
PtrBuf:TvPointer; //
|
|
HostBuf:TvBuffer; //
|
|
|
|
Cursors:array[0..SCE_VIDEO_OUT_CURSOR_NUM_MAX-1] of TvFlipBufferCursor;
|
|
|
|
//ur:TURDevcImage2D;
|
|
//ur:TvImage2;
|
|
|
|
Procedure Init(Flip:TvFlip);
|
|
Procedure Free(Flip:TvFlip);
|
|
function IsPrepare:Boolean;
|
|
end;
|
|
|
|
TVCursorPos=packed record
|
|
X,Y:DWORD;
|
|
end;
|
|
|
|
TvFlipCursor=object
|
|
enable:boolean;
|
|
pos:TVCursorPos;
|
|
PtrBuf:TvPointer;
|
|
pending:PDWORD;
|
|
Procedure Free;
|
|
end;
|
|
|
|
TvFlip=class
|
|
FSurface:TVSurface;
|
|
FSwapChain:TSwapChain;
|
|
FSetLayout:TvSetLayout;
|
|
FLayout:TvPipelineLayout;
|
|
FPipelineFlip:TvComputePipeline;
|
|
FPipelineCursor:TvComputePipeline;
|
|
|
|
FSetsPool:TvSetsPool;
|
|
|
|
FCmdPool:TvCmdPool;
|
|
Fcfg:TFlipCfg;
|
|
|
|
Fformat,Ftmode:DWORD;
|
|
|
|
cformat:TVkFormat;
|
|
sformat:TVkFormat;
|
|
|
|
Ffilp_shader:TvShaderCompute;
|
|
|
|
Fcursor_shader:TvShaderCompute;
|
|
|
|
FimageAvailableSemaphore:array[0..2] of TvSemaphore; //
|
|
FrenderFinishedSemaphore:array[0..2] of TvSemaphore; //
|
|
|
|
FNeoMode:Boolean;
|
|
|
|
FcurrentFrame:Byte;
|
|
FcurrentBuffer:Byte;
|
|
FBuffers:array[0..15] of TvFlipBuffer;
|
|
|
|
FCursors:array[0..SCE_VIDEO_OUT_CURSOR_NUM_MAX-1] of TvFlipCursor;
|
|
|
|
Constructor Create(Handle:THandle);
|
|
Destructor Destroy; override;
|
|
|
|
Procedure SetCurrentBuffer(Buffer:Byte);
|
|
|
|
Procedure SetImageFormat(format,tmode:DWORD);
|
|
Procedure SetImageSize(width,height:DWORD);
|
|
Procedure SetHostBuffer(Addr:Pointer);
|
|
Procedure SetGamma(gamma:Tgamma);
|
|
|
|
Procedure SetCursor(index:Integer;enable:Boolean;addr:Pointer;pending:PDWORD;pos:TVCursorPos);
|
|
|
|
procedure recreateSwapChain;
|
|
Procedure FixCurrentFrame;
|
|
function IsComplite(currentBuffer:Byte):Boolean;
|
|
Procedure Flip;
|
|
end;
|
|
|
|
implementation
|
|
|
|
Procedure TvFlipCursor.Free;
|
|
begin
|
|
enable:=False;
|
|
pos:=Default(TVCursorPos);
|
|
pending:=nil;
|
|
PtrBuf:=Default(TvPointer);
|
|
end;
|
|
|
|
Constructor TvFlip.Create(Handle:THandle);
|
|
var
|
|
i:Byte;
|
|
//P1,P2,P3:TvPointer;
|
|
begin
|
|
InitVulkan;
|
|
|
|
Fcfg.gamma[0]:=1;
|
|
Fcfg.gamma[1]:=1;
|
|
Fcfg.gamma[2]:=1;
|
|
Fcfg.gamma[3]:=1;
|
|
Fcfg.Width[0]:=1;
|
|
Fcfg.Width[1]:=1;
|
|
|
|
FSurface:=TVSurface.Create(Handle);
|
|
|
|
FSetLayout:=TvSetLayout.Create;
|
|
FSetLayout.Add(0,VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,ord(VK_SHADER_STAGE_COMPUTE_BIT));
|
|
FSetLayout.Add(1,VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ,ord(VK_SHADER_STAGE_COMPUTE_BIT));
|
|
|
|
FLayout:=TvPipelineLayout.Create;
|
|
FLayout.AddLayout(FSetLayout);
|
|
FLayout.AddPushConst(0,SizeOf(TFlipCfg),ord(VK_SHADER_STAGE_COMPUTE_BIT));
|
|
|
|
FPipelineFlip:=TvComputePipeline.Create;
|
|
FPipelineFlip.SetLayout(FLayout);
|
|
|
|
FSetsPool:=TvSetsPool.Create;
|
|
FSetsPool.AddLayout(FSetLayout,16+16*2);
|
|
|
|
FCmdPool:=TvCmdPool.Create(VulkanApp.FGFamily);
|
|
|
|
For i:=0 to 2 do
|
|
begin
|
|
FimageAvailableSemaphore[i]:=TvSemaphore.Create;
|
|
FrenderFinishedSemaphore[i]:=TvSemaphore.Create;
|
|
end;
|
|
|
|
end;
|
|
|
|
Destructor TvFlip.Destroy;
|
|
var
|
|
i:Byte;
|
|
begin
|
|
FlipQueue.QueueWaitIdle;
|
|
FreeAndNil(Ffilp_shader);
|
|
|
|
For i:=0 to 15 do
|
|
begin
|
|
FBuffers[i].Free(Self);
|
|
end;
|
|
|
|
For i:=0 to 2 do
|
|
begin
|
|
FreeAndNil(FimageAvailableSemaphore[i]);
|
|
FreeAndNil(FrenderFinishedSemaphore[i]);
|
|
end;
|
|
|
|
FreeAndNil(FCmdPool);
|
|
FreeAndNil(FSetsPool);
|
|
FreeAndNil(FPipelineFlip);
|
|
FreeAndNil(FLayout);
|
|
FreeAndNil(FSetLayout);
|
|
FreeAndNil(FSwapChain);
|
|
FreeAndNil(FSurface);
|
|
inherited;
|
|
end;
|
|
|
|
Procedure TvFlipBuffer.Init(Flip:TvFlip);
|
|
begin
|
|
if (FSet=nil) then
|
|
begin
|
|
FSet:=Flip.FSetsPool.Alloc(Flip.FSetLayout);
|
|
end;
|
|
|
|
if (cmdbuf=nil) then
|
|
begin
|
|
cmdbuf:=TvCustomCmdBuffer.Create(Flip.FCmdPool,FlipQueue);
|
|
end;
|
|
|
|
{if (cmdbuf=VK_NULL_HANDLE) then
|
|
begin
|
|
cmdbuf:=Flip.FCmdPool.Alloc;
|
|
end;
|
|
if (cmdfence=nil) then
|
|
begin
|
|
cmdfence:=TvFence.Create(true);
|
|
end;}
|
|
end;
|
|
|
|
Procedure TvFlipBuffer.Free(Flip:TvFlip);
|
|
begin
|
|
FreeAndNil(ImgViewDst);
|
|
FreeAndNil(DstImgNORM);
|
|
FreeAndNil(DstImgSRGB);
|
|
FreeAndNil(HostBuf);
|
|
|
|
FreeAndNil(cmdbuf);
|
|
{
|
|
FreeAndNil(cmdfence);
|
|
if (cmdbuf<>VK_NULL_HANDLE) then
|
|
begin
|
|
Flip.FCmdPool.Free(cmdbuf);
|
|
cmdbuf:=VK_NULL_HANDLE;
|
|
end;
|
|
}
|
|
MemManager.Free(DevcMem);
|
|
DevcMem:=Default(TvPointer);
|
|
Cursors[0].Free;
|
|
Cursors[1].Free;
|
|
end;
|
|
|
|
function TvFlipBuffer.IsPrepare:Boolean;
|
|
begin
|
|
Result:=False;
|
|
if (FSet=nil) then Exit;
|
|
//if (cmdfence=nil) then Exit;
|
|
//if (cmdbuf=VK_NULL_HANDLE) then Exit;
|
|
if (cmdbuf=nil) then Exit;
|
|
if (DstImgNORM=nil) then Exit;
|
|
if (ImgViewDst=nil) then Exit;
|
|
if (DevcMem.FHandle=VK_NULL_HANDLE) then Exit;
|
|
if (Extent.width=0) or (Extent.height=0) then Exit;
|
|
if (HostBuf=nil) then Exit;
|
|
Result:=True;
|
|
end;
|
|
|
|
procedure TvFlipBufferCursor.SetBuffer(hbuf:TvPointer);
|
|
const
|
|
buf_ext:TVkExternalMemoryBufferCreateInfo=(
|
|
sType:VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
|
|
pNext:nil;
|
|
handleTypes:ord(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
|
|
);
|
|
begin
|
|
if (PtrBuf.FHandle=hbuf.FHandle) and (PtrBuf.FOffset=hbuf.FOffset) and (HostBuf<>nil) then Exit;
|
|
|
|
PtrBuf:=hbuf;
|
|
FreeAndNil(HostBuf);
|
|
|
|
HostBuf:=TvBuffer.Create(16384,
|
|
ord(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
|
|
@buf_ext);
|
|
|
|
HostBuf.BindMem(hbuf);
|
|
end;
|
|
|
|
Procedure TvFlipBufferCursor.Init(Flip:TvFlip);
|
|
begin
|
|
if (FSet=nil) then
|
|
begin
|
|
FSet:=Flip.FSetsPool.Alloc(Flip.FSetLayout);
|
|
end;
|
|
end;
|
|
|
|
Procedure TvFlipBufferCursor.Free;
|
|
begin
|
|
FreeAndNil(FSet);
|
|
FreeAndNil(HostBuf);
|
|
PtrBuf:=Default(TvPointer);
|
|
pending:=nil;
|
|
end;
|
|
|
|
function TvFlipBufferCursor.IsPrepare:Boolean;
|
|
begin
|
|
Result:=False;
|
|
if (FSet=nil) then Exit;
|
|
if (HostBuf=nil) then Exit;
|
|
Result:=True;
|
|
end;
|
|
|
|
Procedure TvFlipBufferCursor.SetPending(f:PDWORD);
|
|
begin
|
|
if (pending<>f) then
|
|
begin
|
|
if (pending<>nil) then System.InterlockedDecrement(pending^);
|
|
pending:=f;
|
|
if (pending<>nil) then System.InterlockedIncrement(pending^);
|
|
end;
|
|
end;
|
|
|
|
Procedure TvFlip.SetCurrentBuffer(Buffer:Byte);
|
|
var
|
|
buf:PvFlipBuffer;
|
|
begin
|
|
if (Buffer>15) then Buffer:=15;
|
|
FcurrentBuffer:=Buffer;
|
|
buf:=@FBuffers[FcurrentBuffer];
|
|
buf^.Init(Self);
|
|
end;
|
|
|
|
Const
|
|
SRGB_HACK=True;
|
|
|
|
Procedure TvFlip.SetImageFormat(format,tmode:DWORD);
|
|
begin
|
|
if (Fformat=format) and (Ftmode=tmode) and (Ffilp_shader<>nil) then Exit;
|
|
|
|
Case format of
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB,
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB:
|
|
begin
|
|
cformat:=VK_FORMAT_R8G8B8A8_UNORM;
|
|
if SRGB_HACK then
|
|
sformat:=VK_FORMAT_R8G8B8A8_SRGB;
|
|
end;
|
|
end;
|
|
|
|
Case tmode of
|
|
SCE_VIDEO_OUT_TILING_MODE_LINEAR:
|
|
Case format of
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB:
|
|
begin
|
|
Fformat:=format;
|
|
Ftmode:=tmode;
|
|
FlipQueue.QueueWaitIdle;
|
|
FreeAndNil(Ffilp_shader);
|
|
Ffilp_shader:=TvShaderCompute.Create;
|
|
|
|
//Ffilp_shader.FLocalSize.Create(64,64,1);
|
|
//Ffilp_shader.FLocalSize:=limits.maxComputeWorkGroupSize;
|
|
|
|
Ffilp_shader.LoadFromFile('shaders\FLIP_LINE_A8R8G8B8_SRGB.spv');
|
|
FPipelineFlip.SetShader(Ffilp_shader);
|
|
end;
|
|
else
|
|
Assert(false);
|
|
end;
|
|
SCE_VIDEO_OUT_TILING_MODE_TILE:
|
|
Case format of
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB:
|
|
begin
|
|
Fformat:=format;
|
|
Ftmode:=tmode;
|
|
FlipQueue.QueueWaitIdle;
|
|
FreeAndNil(Ffilp_shader);
|
|
Ffilp_shader:=TvShaderCompute.Create;
|
|
|
|
//Ffilp_shader.FLocalSize.Create(64,64,1);
|
|
|
|
{Ffilp_shader.FLocalSize:=limits.maxComputeWorkGroupSize;
|
|
Ffilp_shader.FLocalSize.z:=1;
|
|
|
|
While (Ffilp_shader.FLocalSize.x*Ffilp_shader.FLocalSize.y>limits.maxComputeWorkGroupInvocations) do
|
|
begin
|
|
if (Ffilp_shader.FLocalSize.x>Ffilp_shader.FLocalSize.y) then
|
|
Ffilp_shader.FLocalSize.x:=Ffilp_shader.FLocalSize.x div 2
|
|
else
|
|
Ffilp_shader.FLocalSize.y:=Ffilp_shader.FLocalSize.y div 2;
|
|
end;}
|
|
|
|
if FNeoMode then
|
|
begin
|
|
Ffilp_shader.LoadFromFile('shaders\FLIP_TILE_A8R8G8B8_SRGB_NEO.spv');
|
|
end else
|
|
begin
|
|
Ffilp_shader.LoadFromFile('shaders\FLIP_TILE_A8R8G8B8_SRGB.spv');
|
|
end;
|
|
|
|
//Ffilp_shader.FLocalSize.Create(16,16,1);
|
|
|
|
FPipelineFlip.SetShader(Ffilp_shader);
|
|
end;
|
|
else
|
|
Assert(false);
|
|
end;
|
|
else
|
|
Assert(false);
|
|
end;
|
|
|
|
end;
|
|
|
|
Procedure TvFlip.SetImageSize(width,height:DWORD);
|
|
var
|
|
buf:PvFlipBuffer;
|
|
//mt:TVkUInt32;
|
|
memr:TVkMemoryRequirements;
|
|
begin
|
|
buf:=@FBuffers[FcurrentBuffer];
|
|
|
|
if (buf^.Extent.width=width) and (buf^.Extent.height=height) and (buf^.DstImgNORM<>nil) then Exit;
|
|
buf^.Extent.width :=width;
|
|
buf^.Extent.height:=height;
|
|
buf^.Extent.depth :=1;
|
|
|
|
Case Ftmode of
|
|
SCE_VIDEO_OUT_TILING_MODE_LINEAR:
|
|
Case Fformat of
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB,
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB:
|
|
begin
|
|
buf^.PITCH:=width;
|
|
buf^.SIZE :=width*height*4;
|
|
end;
|
|
end;
|
|
SCE_VIDEO_OUT_TILING_MODE_TILE:
|
|
Case Fformat of
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8R8G8B8_SRGB,
|
|
SCE_VIDEO_OUT_PIXEL_FORMAT_A8B8G8R8_SRGB:
|
|
begin
|
|
if FNeoMode then
|
|
begin
|
|
buf^.PITCH:=(width+127) div 128;
|
|
buf^.SIZE :=buf^.PITCH*128*((height+127) div 128)*128*4;
|
|
end else
|
|
begin
|
|
buf^.PITCH:=(width+127) div 128;
|
|
buf^.SIZE :=buf^.PITCH*128*((height+63) div 64)*64*4;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
FreeAndNil(buf^.ImgViewDst);
|
|
FreeAndNil(buf^.DstImgNORM);
|
|
FreeAndNil(buf^.DstImgSRGB);
|
|
|
|
MemManager.Free(buf^.DevcMem);
|
|
buf^.DevcMem:=Default(TvPointer);
|
|
|
|
//
|
|
|
|
buf^.DstImgNORM:=TvDeviceImage2D.Create(
|
|
cformat,
|
|
buf^.Extent,
|
|
ord(VK_IMAGE_USAGE_STORAGE_BIT) or
|
|
ord(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) or
|
|
ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
|
);
|
|
|
|
if (sformat<>VK_FORMAT_UNDEFINED) then
|
|
buf^.DstImgSRGB:=TvDeviceImage2D.Create(
|
|
sformat,
|
|
buf^.Extent,
|
|
ord(VK_IMAGE_USAGE_TRANSFER_SRC_BIT) or
|
|
ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT)
|
|
);
|
|
|
|
memr:=buf^.DstImgNORM.GetRequirements;
|
|
|
|
//Writeln(buf^.DstImg.GetDedicatedAllocation);
|
|
|
|
buf^.DevcMem:=MemManager.Alloc(memr,ord(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
|
|
|
|
buf^.DstImgNORM.BindMem(buf^.DevcMem);
|
|
|
|
if (sformat<>VK_FORMAT_UNDEFINED) then
|
|
buf^.DstImgSRGB.BindMem(buf^.DevcMem);
|
|
|
|
buf^.ImgViewDst:=buf^.DstImgNORM.NewView;
|
|
end;
|
|
|
|
Procedure TvFlip.SetHostBuffer(Addr:Pointer);
|
|
const
|
|
buf_ext:TVkExternalMemoryBufferCreateInfo=(
|
|
sType:VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
|
|
pNext:nil;
|
|
handleTypes:ord(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
|
|
);
|
|
var
|
|
//r:TURDevcImage2D;
|
|
//r:TvImage2;
|
|
hbuf:TvPointer;
|
|
buf:PvFlipBuffer;
|
|
begin
|
|
buf:=@FBuffers[FcurrentBuffer];
|
|
|
|
{
|
|
r:=FindImage(nil,Addr,cformat);
|
|
//r:=FindUnionImage2D(Addr);
|
|
if (r<>nil) then
|
|
begin
|
|
FreeAndNil(buf^.HostBuf);
|
|
buf^.ur:=r;
|
|
end else
|
|
begin
|
|
buf^.ur:=nil;
|
|
end;
|
|
}
|
|
|
|
hbuf:=Default(TvPointer);
|
|
if not TryGetHostPointerByAddr(addr,hbuf) then Exit;
|
|
|
|
if (buf^.PtrBuf.FHandle=hbuf.FHandle) and (buf^.PtrBuf.FOffset=hbuf.FOffset) and (buf^.HostBuf<>nil) then Exit;
|
|
buf^.PtrBuf:=hbuf;
|
|
FreeAndNil(buf^.HostBuf);
|
|
|
|
buf^.HostBuf:=TvBuffer.Create(buf^.SIZE,
|
|
ord(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
|
|
@buf_ext);
|
|
buf^.HostBuf.BindMem(hbuf);
|
|
|
|
buf^.Addr:=Addr;
|
|
end;
|
|
|
|
Procedure TvFlip.SetGamma(gamma:Tgamma);
|
|
begin
|
|
Fcfg.gamma[0]:=gamma[0];
|
|
Fcfg.gamma[1]:=gamma[1];
|
|
Fcfg.gamma[2]:=gamma[2];
|
|
end;
|
|
|
|
Procedure TvFlip.SetCursor(index:Integer;enable:Boolean;addr:Pointer;pending:PDWORD;pos:TVCursorPos);
|
|
var
|
|
hbuf:TvPointer;
|
|
begin
|
|
If (index<0) or (index>=Length(FCursors)) then Exit;
|
|
Case enable of
|
|
True:
|
|
if TryGetHostPointerByAddr(addr,hbuf) then
|
|
begin
|
|
if (FPipelineCursor=nil) then
|
|
begin
|
|
FPipelineCursor:=TvComputePipeline.Create;
|
|
FPipelineCursor.SetLayout(FLayout);
|
|
end;
|
|
|
|
if (Fcursor_shader=nil) then
|
|
begin
|
|
Fcursor_shader:=TvShaderCompute.Create;
|
|
Fcursor_shader.LoadFromFile('shaders\FLIP_CURSOR.spv');
|
|
FPipelineCursor.SetShader(Fcursor_shader);
|
|
end;
|
|
|
|
FCursors[index].enable :=true;
|
|
FCursors[index].pos :=pos;
|
|
FCursors[index].pending:=pending;
|
|
FCursors[index].PtrBuf :=hbuf;
|
|
end else
|
|
begin
|
|
FCursors[index].Free;
|
|
end;
|
|
False:FCursors[index].Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TvFlip.recreateSwapChain;
|
|
begin
|
|
vkDeviceWaitIdle(Device.FHandle);
|
|
FreeAndNil(FSwapChain);
|
|
FSwapChain:=TSwapChain.Create(FSurface,0{1},ord(VK_IMAGE_USAGE_TRANSFER_DST_BIT));
|
|
end;
|
|
|
|
Procedure TvFlip.FixCurrentFrame;
|
|
begin
|
|
if (FSwapChain=nil) then Exit;
|
|
if (Length(FSwapChain.FImage)=0) then Exit;
|
|
FcurrentFrame:=FcurrentFrame mod Length(FSwapChain.FImage);
|
|
end;
|
|
|
|
function TvFlip.IsComplite(currentBuffer:Byte):Boolean;
|
|
var
|
|
buf:PvFlipBuffer;
|
|
r:TVkResult;
|
|
begin
|
|
Result:=True;
|
|
if (Device=nil) then Exit;
|
|
|
|
buf:=@FBuffers[FcurrentBuffer];
|
|
|
|
if (buf^.cmdbuf=nil) then Exit;
|
|
if (buf^.cmdbuf.Fence=nil) then Exit;
|
|
|
|
r:=buf^.cmdbuf.Fence.Status;
|
|
Case r of
|
|
VK_SUCCESS :;
|
|
VK_NOT_READY:Exit(False);
|
|
else
|
|
begin
|
|
Writeln('vkGetEventStatus:',r);
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
buf^.cmdbuf.ReleaseResource;
|
|
|
|
buf^.Cursors[0].SetPending(nil);
|
|
buf^.Cursors[1].SetPending(nil);
|
|
end;
|
|
|
|
Procedure TvFlip.Flip;
|
|
var
|
|
r:TVkResult;
|
|
imageIndex:TVkUInt32;
|
|
SwapImage:TVkImage;
|
|
|
|
imageAvailableSemaphore:TvSemaphore;
|
|
renderFinishedSemaphore:TvSemaphore;
|
|
|
|
buf:PvFlipBuffer;
|
|
|
|
bufcur:PvFlipBufferCursor;
|
|
|
|
FCurSet:TvDescriptorSet;
|
|
|
|
//beginInfo:TVkCommandBufferBeginInfo;
|
|
imgBlitRegion:TVkImageBlit;
|
|
FLocalSize:TVkOffset3D;
|
|
|
|
//submitInfo:TVkSubmitInfo;
|
|
//wstage:TVkPipelineStageFlags;
|
|
prInfo:TVkPresentInfoKHR;
|
|
|
|
//tmp_reg:TVkBufferImageCopy;
|
|
//tmp_buf:TURDevcImage;
|
|
|
|
img_reg:TVkImageCopy;
|
|
|
|
ur:TvImage2;
|
|
begin
|
|
if (Device=nil) then Exit;
|
|
|
|
buf:=@FBuffers[FcurrentBuffer];
|
|
|
|
if (Ffilp_shader=nil) then Exit;
|
|
|
|
if not buf^.IsPrepare then Exit;
|
|
|
|
if (FSwapChain=nil) then recreateSwapChain;
|
|
if (FSwapChain.FHandle=VK_NULL_HANDLE) then
|
|
begin
|
|
recreateSwapChain;
|
|
if (FSwapChain.FHandle=VK_NULL_HANDLE) then Exit;
|
|
end;
|
|
|
|
if not FSetLayout.Compile then Exit;
|
|
if not FLayout.Compile then Exit;
|
|
if not FPipelineFlip.Compile then Exit;
|
|
if not FSetsPool.Compile then Exit;
|
|
|
|
repeat
|
|
FixCurrentFrame;
|
|
imageAvailableSemaphore:=FimageAvailableSemaphore[FcurrentFrame];
|
|
renderFinishedSemaphore:=FrenderFinishedSemaphore[FcurrentFrame];
|
|
|
|
R:=vkAcquireNextImageKHR(Device.FHandle,
|
|
FSwapChain.FHandle,
|
|
High(uInt64),
|
|
imageAvailableSemaphore.FHandle,
|
|
VK_NULL_HANDLE,
|
|
@imageIndex);
|
|
Case R of
|
|
VK_SUCCESS:Break;
|
|
VK_ERROR_OUT_OF_DATE_KHR,
|
|
VK_SUBOPTIMAL_KHR:recreateSwapChain;
|
|
else
|
|
begin
|
|
Writeln('vkAcquireNextImageKHR:',R);
|
|
Exit;
|
|
end;
|
|
end;
|
|
until false;
|
|
SwapImage:=FSwapChain.FImage[imageIndex];
|
|
|
|
//buf^.cmdfence.Wait(High(uint64));
|
|
//buf^.cmdfence.Reset;
|
|
|
|
buf^.cmdbuf.Fence.Wait(High(uint64));
|
|
buf^.cmdbuf.Fence.Reset;
|
|
buf^.cmdbuf.ReleaseResource;
|
|
|
|
buf^.Cursors[0].SetPending(nil);
|
|
buf^.Cursors[1].SetPending(nil);
|
|
|
|
{
|
|
beginInfo:=Default(TVkCommandBufferBeginInfo);
|
|
beginInfo.sType:=VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
beginInfo.flags:=ord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
|
beginInfo.pInheritanceInfo:=nil;
|
|
r:=vkBeginCommandBuffer(buf^.cmdbuf,@beginInfo);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln('vkBeginCommandBuffer:',r);
|
|
Exit;
|
|
end;
|
|
}
|
|
if not buf^.cmdbuf.BeginCmdBuffer then Exit;
|
|
|
|
ur:=FindImage(buf^.cmdbuf,buf^.Addr,cformat);
|
|
|
|
if (ur=nil) then
|
|
begin
|
|
FCurSet:=buf^.FSet;
|
|
|
|
FCurSet.BindBuf(0,0,
|
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
buf^.HostBuf.FHandle,
|
|
0,
|
|
buf^.SIZE);
|
|
|
|
FCurSet.BindSTI(1,0,buf^.ImgViewDst.FHandle,VK_IMAGE_LAYOUT_GENERAL);
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgNORM.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgNORM.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgSRGB.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
end;
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgSRGB.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
//vkCmdBindPipeline(buf^.cmdbuf,VK_PIPELINE_BIND_POINT_COMPUTE,FPipelineFlip.FHandle);
|
|
buf^.cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE,FPipelineFlip.FHandle);
|
|
buf^.cmdbuf.BindLayout(VK_PIPELINE_BIND_POINT_COMPUTE,FLayout);
|
|
|
|
Fcfg.Width[0]:=1;
|
|
Fcfg.Width[1]:=buf^.PITCH;
|
|
|
|
//vkCmdPushConstants(buf^.cmdbuf.cmdbuf,
|
|
// FLayout.FHandle,
|
|
// ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
// 0,
|
|
// SizeOf(TFlipCfg),
|
|
// @Fcfg);
|
|
|
|
buf^.cmdbuf.PushConstant(VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
0,SizeOf(TFlipCfg),@Fcfg);
|
|
|
|
buf^.cmdbuf.BindSet(VK_PIPELINE_BIND_POINT_COMPUTE,0,FCurSet.FHandle);
|
|
|
|
//vkCmdBindDescriptorSets(buf^.cmdbuf.cmdbuf,
|
|
// VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
// FLayout.FHandle,0,1,
|
|
// @FCurSet.FHandle,0,nil);
|
|
|
|
FLocalSize:=TvShaderCompute(FPipelineFlip.FComputeShader).FLocalSize;
|
|
|
|
FLocalSize.x:=(buf^.DstImgNORM.FExtent.width +(FLocalSize.x-1)) div FLocalSize.x;
|
|
FLocalSize.y:=(buf^.DstImgNORM.FExtent.height+(FLocalSize.y-1)) div FLocalSize.y;
|
|
|
|
//vkCmdDispatch(buf^.cmdbuf.cmdbuf,FLocalSize.x,FLocalSize.y,1);
|
|
buf^.cmdbuf.DispatchDirect(FLocalSize.x,FLocalSize.y,1);
|
|
end else
|
|
begin
|
|
|
|
buf^.cmdbuf.SetImageBarrier(ur.FHandle,SubresColor,
|
|
ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT));
|
|
|
|
buf^.cmdbuf.PushImageBarrier(ur.FHandle,SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// {buf^.}ur{.FImage}.FHandle,
|
|
// ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),
|
|
// ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
// VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
// VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
// ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT),
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// SubresColor);
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgNORM.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
// ord(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT),
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// SubresColor);
|
|
|
|
if (buf^.DstImgSRGB<>nil) and (ur.key.cformat=VK_FORMAT_R8G8B8A8_SRGB) then
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgSRGB.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
end else
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgNORM.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
end;
|
|
|
|
imgBlitRegion:=Default(TVkImageBlit);
|
|
imgBlitRegion.srcSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
imgBlitRegion.srcSubresource.layerCount:=1;
|
|
imgBlitRegion.dstSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
imgBlitRegion.dstSubresource.layerCount:=1;
|
|
imgBlitRegion.srcOffsets[1].x:=ur.key.params.extend.width;
|
|
imgBlitRegion.srcOffsets[1].y:=ur.key.params.extend.height;
|
|
imgBlitRegion.srcOffsets[1].z:=1;
|
|
imgBlitRegion.dstOffsets[1].x:=buf^.DstImgNORM.FExtent.width;
|
|
imgBlitRegion.dstOffsets[1].y:=buf^.DstImgNORM.FExtent.height;
|
|
imgBlitRegion.dstOffsets[1].z:=1;
|
|
|
|
if (buf^.DstImgSRGB<>nil) and (ur.key.cformat=VK_FORMAT_R8G8B8A8_SRGB) then
|
|
begin
|
|
vkCmdBlitImage(
|
|
buf^.cmdbuf.cmdbuf,
|
|
ur.FHandle ,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf^.DstImgSRGB.FHandle,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@imgBlitRegion,VK_FILTER_LINEAR);
|
|
end else
|
|
begin
|
|
vkCmdBlitImage(
|
|
buf^.cmdbuf.cmdbuf,
|
|
ur.FHandle ,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf^.DstImgNORM.FHandle,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@imgBlitRegion,VK_FILTER_LINEAR);
|
|
end;
|
|
|
|
{
|
|
img_reg:=Default(TVkImageCopy);
|
|
img_reg.srcSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
img_reg.srcSubresource.layerCount:=1;
|
|
img_reg.dstSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
img_reg.dstSubresource.layerCount:=1;
|
|
|
|
img_reg.extent.Create(
|
|
ur.key.params.extend.width,
|
|
ur.key.params.extend.height,
|
|
1);
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
|
|
vkCmdCopyImage(buf^.cmdbuf.cmdbuf,
|
|
ur.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf^.DstImgSRGB.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@img_reg);
|
|
|
|
end else
|
|
begin
|
|
|
|
vkCmdCopyImage(buf^.cmdbuf.cmdbuf,
|
|
ur.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
buf^.DstImgNORM.FHandle,
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@img_reg);
|
|
|
|
end;
|
|
}
|
|
|
|
end;
|
|
|
|
if (FCursors[0].enable or FCursors[1].enable) then
|
|
begin
|
|
//vkCmdBindPipeline(buf^.cmdbuf,VK_PIPELINE_BIND_POINT_COMPUTE,FPipelineCursor.FHandle);
|
|
buf^.cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE,FPipelineCursor.FHandle);
|
|
|
|
FLocalSize:=TvShaderCompute(FPipelineCursor.FComputeShader).FLocalSize;
|
|
|
|
bufcur:=@buf^.Cursors[0];
|
|
|
|
if FCursors[0].enable then
|
|
begin
|
|
bufcur^.Init(Self);
|
|
bufcur^.SetBuffer(FCursors[0].PtrBuf);
|
|
|
|
if bufcur^.IsPrepare then
|
|
begin
|
|
FCurSet:=bufcur^.FSet;
|
|
|
|
Fcfg.Width[0]:=FCursors[0].pos.x;
|
|
Fcfg.Width[1]:=FCursors[0].pos.y;
|
|
|
|
bufcur^.SetPending(FCursors[0].pending);
|
|
|
|
FCurSet.BindBuf(0,0,
|
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
bufcur^.HostBuf.FHandle,
|
|
0,
|
|
16384);
|
|
|
|
FCurSet.BindSTI(1,0,buf^.ImgViewDst.FHandle,VK_IMAGE_LAYOUT_GENERAL);
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgNORM.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgSRGB.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
end else
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgNORM.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
end;
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgSRGB.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
buf^.cmdbuf.PushConstant(VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
0,SizeOf(TFlipCfg),@Fcfg);
|
|
|
|
//vkCmdPushConstants(buf^.cmdbuf.cmdbuf,
|
|
// FLayout.FHandle,
|
|
// ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
// 0,
|
|
// SizeOf(TFlipCfg),
|
|
// @Fcfg);
|
|
|
|
buf^.cmdbuf.BindSet(VK_PIPELINE_BIND_POINT_COMPUTE,0,FCurSet.FHandle);
|
|
|
|
//vkCmdBindDescriptorSets(buf^.cmdbuf.cmdbuf,
|
|
// VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
// FLayout.FHandle,0,1,
|
|
// @FCurSet.FHandle,0,nil);
|
|
|
|
//vkCmdDispatch(buf^.cmdbuf.cmdbuf,64 div FLocalSize.x,64 div FLocalSize.y,1);
|
|
buf^.cmdbuf.DispatchDirect(64 div FLocalSize.x,64 div FLocalSize.y,1);
|
|
end else
|
|
begin
|
|
bufcur^.Free;
|
|
end;
|
|
end else
|
|
begin
|
|
bufcur^.Free;
|
|
end;
|
|
|
|
bufcur:=@buf^.Cursors[1];
|
|
|
|
if FCursors[1].enable then
|
|
begin
|
|
bufcur^.Init(Self);
|
|
bufcur^.SetBuffer(FCursors[1].PtrBuf);
|
|
|
|
if bufcur^.IsPrepare then
|
|
begin
|
|
FCurSet:=bufcur^.FSet;
|
|
|
|
Fcfg.Width[0]:=FCursors[1].pos.x;
|
|
Fcfg.Width[1]:=FCursors[1].pos.y;
|
|
|
|
bufcur^.SetPending(FCursors[1].pending);
|
|
|
|
FCurSet.BindBuf(0,0,
|
|
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
bufcur^.HostBuf.FHandle,
|
|
0,
|
|
16384);
|
|
|
|
FCurSet.BindSTI(1,0,buf^.ImgViewDst.FHandle,VK_IMAGE_LAYOUT_GENERAL);
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgNORM.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgSRGB.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
end else
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgNORM.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_GENERAL,
|
|
ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
|
|
end;
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgSRGB.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_SHADER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_GENERAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// SubresColor);
|
|
|
|
//vkCmdPushConstants(buf^.cmdbuf.cmdbuf,
|
|
// FLayout.FHandle,
|
|
// ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
// 0,
|
|
// SizeOf(TFlipCfg),
|
|
// @Fcfg);
|
|
|
|
buf^.cmdbuf.PushConstant(VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
ord(VK_SHADER_STAGE_COMPUTE_BIT),
|
|
0,SizeOf(TFlipCfg),@Fcfg);
|
|
|
|
buf^.cmdbuf.BindSet(VK_PIPELINE_BIND_POINT_COMPUTE,0,FCurSet.FHandle);
|
|
|
|
//vkCmdBindDescriptorSets(buf^.cmdbuf.cmdbuf,
|
|
// VK_PIPELINE_BIND_POINT_COMPUTE,
|
|
// FLayout.FHandle,0,1,
|
|
// @FCurSet.FHandle,0,nil);
|
|
|
|
//vkCmdDispatch(buf^.cmdbuf.cmdbuf,64 div FLocalSize.x,64 div FLocalSize.y,1);
|
|
buf^.cmdbuf.DispatchDirect(64 div FLocalSize.x,64 div FLocalSize.y,1);
|
|
end else
|
|
begin
|
|
bufcur^.Free;
|
|
end;
|
|
end else
|
|
begin
|
|
bufcur^.Free;
|
|
end;
|
|
|
|
end else
|
|
begin
|
|
buf^.Cursors[0].Free;
|
|
buf^.Cursors[1].Free;
|
|
end;
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgNORM.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// SubresColor);
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgSRGB.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
end else
|
|
begin
|
|
buf^.cmdbuf.PushImageBarrier(buf^.DstImgNORM.FHandle,
|
|
SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
end;
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// buf^.DstImgSRGB.FHandle,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_TRANSFER_READ_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
// ord(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// SubresColor);
|
|
|
|
buf^.cmdbuf.PushImageBarrier(SwapImage,
|
|
SubresColor,
|
|
ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// SwapImage,
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
// VK_IMAGE_LAYOUT_UNDEFINED,
|
|
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
// ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT),
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// SubresColor);
|
|
|
|
imgBlitRegion:=Default(TVkImageBlit);
|
|
imgBlitRegion.srcSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
imgBlitRegion.srcSubresource.layerCount:=1;
|
|
imgBlitRegion.dstSubresource.aspectMask:=ord(VK_IMAGE_ASPECT_COLOR_BIT);
|
|
imgBlitRegion.dstSubresource.layerCount:=1;
|
|
imgBlitRegion.srcOffsets[1].x:=buf^.DstImgNORM.FExtent.width;
|
|
imgBlitRegion.srcOffsets[1].y:=buf^.DstImgNORM.FExtent.height;
|
|
imgBlitRegion.srcOffsets[1].z:=1;
|
|
imgBlitRegion.dstOffsets[1].x:=FSwapChain.FSize.width;
|
|
imgBlitRegion.dstOffsets[1].y:=FSwapChain.FSize.height;
|
|
imgBlitRegion.dstOffsets[1].z:=1;
|
|
|
|
if (buf^.DstImgSRGB<>nil) then
|
|
begin
|
|
vkCmdBlitImage(
|
|
buf^.cmdbuf.cmdbuf,
|
|
buf^.DstImgSRGB.FHandle,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
SwapImage ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@imgBlitRegion,VK_FILTER_LINEAR);
|
|
end else
|
|
begin
|
|
vkCmdBlitImage(
|
|
buf^.cmdbuf.cmdbuf,
|
|
buf^.DstImgNORM.FHandle,VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
|
SwapImage ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
1,@imgBlitRegion,VK_FILTER_LINEAR);
|
|
end;
|
|
|
|
|
|
buf^.cmdbuf.PushImageBarrier(SwapImage,
|
|
SubresColor,
|
|
ord(VK_ACCESS_NONE_KHR),
|
|
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT));
|
|
|
|
//vkImageMemoryBarrier(
|
|
// buf^.cmdbuf.cmdbuf,
|
|
// SwapImage,
|
|
// ord(VK_ACCESS_TRANSFER_WRITE_BIT),
|
|
// ord(VK_ACCESS_NONE_KHR),
|
|
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
|
// VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
// ord(VK_PIPELINE_STAGE_TRANSFER_BIT),
|
|
// ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT),
|
|
// SubresColor);
|
|
|
|
//vkEndCommandBuffer(buf^.cmdbuf);
|
|
buf^.cmdbuf.EndCmdBuffer;
|
|
|
|
buf^.cmdbuf.AddWaitSemaphore(imageAvailableSemaphore,ord(VK_PIPELINE_STAGE_TRANSFER_BIT));
|
|
buf^.cmdbuf.SignalSemaphore:=renderFinishedSemaphore;
|
|
buf^.cmdbuf.QueueSubmit;
|
|
|
|
{r:=vkQueueSubmit(FlipQueue,1,@submitInfo,buf^.cmdbuf.Fence.FHandle);
|
|
//r:=vkQueueSubmit(FlipQueue,1,@submitInfo,buf^.cmdfence.FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln('vkQueueSubmit:',r);
|
|
exit;
|
|
end;}
|
|
|
|
prInfo:=Default(TVkPresentInfoKHR);
|
|
prInfo.sType :=VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
prInfo.waitSemaphoreCount:=1;
|
|
prInfo.pWaitSemaphores :=@renderFinishedSemaphore.FHandle;
|
|
prInfo.swapchainCount :=1;
|
|
prInfo.pSwapchains :=@FSwapChain.FHandle;
|
|
prInfo.pImageIndices :=@imageIndex;
|
|
prInfo.pResults:=nil;
|
|
|
|
R:=FlipQueue.QueuePresentKHR(@prInfo);
|
|
Case R of
|
|
VK_SUCCESS:;
|
|
VK_ERROR_OUT_OF_DATE_KHR,
|
|
VK_SUBOPTIMAL_KHR:recreateSwapChain;
|
|
else
|
|
begin
|
|
Writeln('vkQueuePresentKHR:',R);
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
FcurrentFrame:=FcurrentFrame+1;
|
|
FixCurrentFrame;
|
|
//vkQueueWaitIdle(FlipQueue);
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|