Instantly share code, notes, and snippets.

Embed
What would you like to do?
PasVulkan Frame graph API code example
unit UnitScreenMainMenu;
{$ifdef fpc}
{$mode delphi}
{$ifdef cpu386}
{$asmmode intel}
{$endif}
{$ifdef cpuamd64}
{$asmmode intel}
{$endif}
{$else}
{$ifdef conditionalexpressions}
{$if CompilerVersion>=24.0}
{$legacyifend on}
{$ifend}
{$endif}
{$endif}
{$if defined(Win32) or defined(Win64)}
{$define Windows}
{$ifend}
interface
uses SysUtils,
Classes,
Math,
PasMP,
Vulkan,
PasVulkan.Types,
PasVulkan.Math,
PasVulkan.Framework,
PasVulkan.FrameGraph,
PasVulkan.Application,
PasVulkan.Audio;
type PScreenMainMenuBackgroundUniformBuffer=^TScreenMainMenuBackgroundUniformBuffer;
TScreenMainMenuBackgroundUniformBuffer=packed record
InverseViewProjectionMatrix:TpvMatrix4x4;
Resolution:TpvVector2;
MusicTick:TpvFloat;
PressStartOffset:TpvFloat;
end;
PScreenMainMenuTerrainUniformBuffer=^TScreenMainMenuTerrainUniformBuffer;
TScreenMainMenuTerrainUniformBuffer=packed record
ModelViewMatrix:TpvMatrix4x4;
ModelViewProjectionMatrix:TpvMatrix4x4;
Offset:TpvFloat;
end;
PScreenMainMenuForegroundUniformBuffer=^TScreenMainMenuForegroundUniformBuffer;
TScreenMainMenuForegroundUniformBuffer=packed record
ViewProjectionMatrix:TpvMatrix4x4;
InverseViewProjectionMatrix:TpvMatrix4x4;
Resolution:TpvVector2;
MusicTick:TpvFloat;
PressStartOffset:TpvFloat;
end;
TScreenMainMenu=class;
TScreenMainMenuSceneContentRenderPass=class(TpvFrameGraph.TRenderPass)
public
const TerrainTextureSize=32;
TerrainTextureBorderSize=2;
TerrainParts=4;
HeightMapWidth=64;
HeightMapHeight=128;
GridSize=4;
type TTerrainTexturePixel=packed record
r,g,b,a:TpvUInt8;
end;
PTerrainTexturePixel=^TTerrainTexturePixel;
TTerrainTexture=array[0..TerrainTextureSize-1,0..TerrainTextureSize-1] of TTerrainTexturePixel;
PTerrainTexture=^TTerrainTexture;
TTerrainVertex=packed record // 16 bytes per vertex
Position:TpvVector3;
TexCoord:TpvHalfFloatVector2;
end;
PTerrainVertex=^TTerrainVertex;
TTerrainHeightMap=array[0..(HeightMapWidth*HeightMapHeight)-1] of TpvFloat;
PTerrainHeightMap=^TTerrainHeightMap;
TTerrainVertices=array[0..((HeightMapWidth*HeightMapHeight)*TerrainParts)-1] of TTerrainVertex;
PTerrainVertices=^TTerrainVertices;
TTerrainIndices=array[0..(((HeightMapWidth-1)*(HeightMapHeight-1))*6*TerrainParts)-1] of TVkUInt32;
PTerrainIndices=^TTerrainIndices;
private
fVulkanRenderPass:TpvVulkanRenderPass;
fParent:TScreenMainMenu;
fResourceColor:TpvFrameGraph.TPass.TUsedImageResource;
fResourceDepth:TpvFrameGraph.TPass.TUsedImageResource;
fVulkanGraphicsCommandBuffer:TpvVulkanCommandBuffer;
fVulkanGraphicsCommandBufferFence:TpvVulkanFence;
fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer;
fVulkanTransferCommandBufferFence:TpvVulkanFence;
fBackgroundVertexShaderModule:TpvVulkanShaderModule;
fBackgroundFragmentShaderModule:TpvVulkanShaderModule;
fBackgroundVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage;
fBackgroundVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage;
fBackgroundVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline;
fBackgroundVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer;
fBackgroundVulkanDescriptorPool:TpvVulkanDescriptorPool;
fBackgroundVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout;
fBackgroundVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet;
fBackgroundVulkanPipelineLayout:TpvVulkanPipelineLayout;
fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer;
fTerrainTextureData:TTerrainTexture;
fTerrainTexture:TpvVulkanTexture;
fTerrainHeightMap:TTerrainHeightMap;
fTerrainVertices:TTerrainVertices;
fTerrainIndices:TTerrainIndices;
fTerrainVertexShaderModule:TpvVulkanShaderModule;
fTerrainFragmentShaderModule:TpvVulkanShaderModule;
fTerrainVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage;
fTerrainVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage;
fTerrainVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline;
fTerrainVulkanVertexBuffer:TpvVulkanBuffer;
fTerrainVulkanIndexBuffer:TpvVulkanBuffer;
fTerrainVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer;
fTerrainVulkanDescriptorPool:TpvVulkanDescriptorPool;
fTerrainVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout;
fTerrainVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet;
fTerrainVulkanPipelineLayout:TpvVulkanPipelineLayout;
fTerrainUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuTerrainUniformBuffer;
fForegroundVertexShaderModule:TpvVulkanShaderModule;
fForegroundFragmentShaderModule:TpvVulkanShaderModule;
fForegroundVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage;
fForegroundVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage;
fForegroundVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline;
fForegroundVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer;
fForegroundVulkanDescriptorPool:TpvVulkanDescriptorPool;
fForegroundVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout;
fForegroundVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet;
fForegroundVulkanPipelineLayout:TpvVulkanPipelineLayout;
fForegroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuForegroundUniformBuffer;
procedure TerrainHeightMapGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
procedure TerrainVerticesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
procedure TerrainIndicesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
public
constructor Create(const aFrameGraph:TpvFrameGraph;const aParent:TScreenMainMenu); reintroduce;
destructor Destroy; override;
procedure Show; override;
procedure Hide; override;
procedure AfterCreateSwapChain; override;
procedure BeforeDestroySwapChain; override;
procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override;
procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override;
end;
TScreenMainMenuTonemappingRenderPass=class(TpvFrameGraph.TRenderPass)
private
fVulkanRenderPass:TpvVulkanRenderPass;
fResourceColor:TpvFrameGraph.TPass.TUsedImageResource;
fResourceSurface:TpvFrameGraph.TPass.TUsedImageResource;
fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer;
fVulkanTransferCommandBufferFence:TpvVulkanFence;
fVulkanVertexShaderModule:TpvVulkanShaderModule;
fVulkanFragmentShaderModule:TpvVulkanShaderModule;
fVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage;
fVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage;
fVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline;
fVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer;
fVulkanDescriptorPool:TpvVulkanDescriptorPool;
fVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout;
fVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet;
fVulkanPipelineLayout:TpvVulkanPipelineLayout;
fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer;
public
constructor Create(const aFrameGraph:TpvFrameGraph); override;
destructor Destroy; override;
procedure Show; override;
procedure Hide; override;
procedure AfterCreateSwapChain; override;
procedure BeforeDestroySwapChain; override;
procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override;
procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override;
end;
TScreenMainMenuAntialiasingRenderPass=class(TpvFrameGraph.TRenderPass)
private
fVulkanRenderPass:TpvVulkanRenderPass;
fResourceColor:TpvFrameGraph.TPass.TUsedImageResource;
fResourceSurface:TpvFrameGraph.TPass.TUsedImageResource;
fVulkanTransferCommandBuffer:TpvVulkanCommandBuffer;
fVulkanTransferCommandBufferFence:TpvVulkanFence;
fVulkanVertexShaderModule:TpvVulkanShaderModule;
fVulkanFragmentShaderModule:TpvVulkanShaderModule;
fVulkanPipelineShaderStageVertex:TpvVulkanPipelineShaderStage;
fVulkanPipelineShaderStageFragment:TpvVulkanPipelineShaderStage;
fVulkanGraphicsPipeline:TpvVulkanGraphicsPipeline;
fVulkanSampler:TpvVulkanSampler;
fVulkanUniformBuffers:array[0..MaxSwapChainImages-1] of TpvVulkanBuffer;
fVulkanDescriptorPool:TpvVulkanDescriptorPool;
fVulkanDescriptorSetLayout:TpvVulkanDescriptorSetLayout;
fVulkanDescriptorSets:array[0..MaxSwapChainImages-1] of TpvVulkanDescriptorSet;
fVulkanPipelineLayout:TpvVulkanPipelineLayout;
fBackgroundUniformBuffers:array[0..MaxSwapChainImages-1] of TScreenMainMenuBackgroundUniformBuffer;
public
constructor Create(const aFrameGraph:TpvFrameGraph); override;
destructor Destroy; override;
procedure Show; override;
procedure Hide; override;
procedure AfterCreateSwapChain; override;
procedure BeforeDestroySwapChain; override;
procedure Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt); override;
procedure Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt); override;
end;
TScreenMainMenu=class(TpvApplicationScreen)
private
fFrameGraph:TpvFrameGraph;
fSceneContentRenderPass:TScreenMainMenuSceneContentRenderPass;
fTonemappingRenderPass:TScreenMainMenuTonemappingRenderPass;
fAntialiasingRenderPass:TScreenMainMenuAntialiasingRenderPass;
fVulkanSampleCountFlagBits:TVkSampleCountFlagBits;
fVulkanRenderSemaphores:array[0..MaxSwapChainImages-1] of TpvVulkanSemaphore;
fReady:boolean;
fSelectedIndex:TpvInt32;
fStartY:TpvFloat;
fTime:TpvDouble;
fTimeToMusicTickFactor:TpvDouble;
fAudioSoundOGGSoundTrack1:TpvAudioSoundOGG;
public
constructor Create; override;
destructor Destroy; override;
procedure Show; override;
procedure Hide; override;
procedure Resume; override;
procedure Pause; override;
procedure Resize(const aWidth,aHeight:TpvInt32); override;
procedure AfterCreateSwapChain; override;
procedure BeforeDestroySwapChain; override;
function KeyEvent(const aKeyEvent:TpvApplicationInputKeyEvent):boolean; override;
function PointerEvent(const aPointerEvent:TpvApplicationInputPointerEvent):boolean; override;
function Scrolled(const aRelativeAmount:TpvVector2):boolean; override;
function CanBeParallelProcessed:boolean; override;
procedure Update(const aDeltaTime:TpvDouble); override;
procedure Draw(const aSwapChainImageIndex:TpvInt32;var aWaitSemaphore:TpvVulkanSemaphore;const aWaitFence:TpvVulkanFence=nil); override;
end;
implementation
uses UnitApplication;
const MainMenuFullscreenTriangleVertices:array[0..2,0..1,0..1] of TpvFloat=
(((-1.0,-1.0),(0.0,0.0)),
((-1.0,3.0),(0.0,2.0)),
((3.0,-1.0),(2.0,0.0)));
FullscreenTriangleIndices:array[0..2] of TpvInt32=(0,1,2);
Offsets:array[0..0] of TVkDeviceSize=(0);
FontSize=3.0;
{ TScreenMainMenuSceneContentRenderPass }
constructor TScreenMainMenuSceneContentRenderPass.Create(const aFrameGraph:TpvFrameGraph;const aParent:TScreenMainMenu);
begin
inherited Create(aFrameGraph);
fParent:=aParent;
Name:='SceneContent';
Queue:=aFrameGraph.UniversalQueue;
pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil,
0,
(HeightMapWidth*HeightMapHeight)-1,
TerrainHeightMapGenerationParallelForJobMethod,
HeightMapWidth,
16,
nil));
pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil,
0,
(HeightMapWidth*HeightMapHeight)-1,
TerrainVerticesGenerationParallelForJobMethod,
HeightMapWidth,
16,
nil));
pvApplication.PasMPInstance.Invoke(pvApplication.PasMPInstance.ParallelFor(nil,
0,
((HeightMapWidth-1)*(HeightMapHeight-1))-1,
TerrainIndicesGenerationParallelForJobMethod,
HeightMapWidth-1,
16,
nil));
Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,
1.0,
1.0);
if fParent.fVulkanSampleCountFlagBits=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT) then begin
fResourceColor:=AddImageOutput('resourcetype_color',
'scene_color',
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
fResourceDepth:=AddImageDepthOutput('resourcetype_depth',
'scene_depth',
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(1.0,1.0,1.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
end else begin
fResourceColor:=AddImageOutput('resourcetype_msaa_color',
'scene_msaa_color',
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
fResourceColor:=AddImageResolveOutput('resourcetype_color',
'scene_color',
'scene_msaa_color',
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.DontCare,
TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
fResourceDepth:=AddImageDepthOutput('resourcetype_msaa_depth',
'scene_msaa_depth',
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(1.0,1.0,1.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
end;
end;
destructor TScreenMainMenuSceneContentRenderPass.Destroy;
begin
inherited Destroy;
end;
procedure TScreenMainMenuSceneContentRenderPass.TerrainHeightMapGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
function FBM(st:TpvVector2):TpvFloat;
function Noise(const st:TpvVector2):TpvFloat;
function NoiseRandom(const st:TpvVector2):TpvFloat;
begin
result:=frac(sin(st.Dot(TpvVector2.InlineableCreate(12.9898,78.233)))*43758.5453123);
end;
var i,f,u:TpvVector2;
a,b,c,d:TpvFloat;
begin
i.x:=floor(st.x);
i.y:=floor(st.y);
f.x:=frac(frac(st.x)+1.0);
f.y:=frac(frac(st.y)+1.0);
a:=NoiseRandom(i+TpvVector2.InlineableCreate(0.0,0.0));
b:=NoiseRandom(i+TpvVector2.InlineableCreate(1.0,0.0));
c:=NoiseRandom(i+TpvVector2.InlineableCreate(0.0,1.0));
d:=NoiseRandom(i+TpvVector2.InlineableCreate(1.0,1.0));
u:=f*f*(TpvVector2.InlineableCreate(3.0,3.0)-(f*2.0));
result:=((a*(1.0-u.x))+(b*u.x))+
((c-a)*u.y*(1.0-u.x))+
((d-b)*u.x*u.y);
end;
var Iteration:TpvSizeInt;
Amplitude:TpvFloat;
begin
result:=0;
Amplitude:=0.5;
for Iteration:=0 to 4 do begin
result:=result+(Noise(st)*Amplitude);
st:=st*2.0;
Amplitude:=Amplitude*0.5;
end;
end;
var Index,x,y:TpvSizeInt;
p:TpvVector2;
begin
for Index:=aFromIndex to aToIndex do begin
x:=Index mod HeightMapWidth;
y:=Index div HeightMapWidth;
p:=TpvVector2.InlineableCreate(x-(HeightMapWidth*0.5),y);
//p:=TpvVector2.InlineableCreate(abs(x-(HeightMapWidth*0.5)),y);
fTerrainHeightMap[Index]:=-Mix(8.0,
((Mix(FBM(p*0.1),
FBM(TpvVector2.InlineableCreate(p.x,(HeightMapHeight-1.0)-p.y)*0.1),
LinearStep(HeightMapHeight*0.875,HeightMapHeight-1.0,y+0.0))-1.0)*24.0)+0.0,
sqr(LinearStep(16.0,64.0,abs(x-(HeightMapWidth*0.5))*GridSize)));
end;
end;
procedure TScreenMainMenuSceneContentRenderPass.TerrainVerticesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
var Index,PartIndex,OffsetedIndex,x,y:TpvSizeInt;
begin
for Index:=aFromIndex to aToIndex do begin
x:=Index mod HeightMapWidth;
y:=Index div HeightMapWidth;
for PartIndex:=0 to TerrainParts-1 do begin
OffsetedIndex:=Index+(PartIndex*(HeightMapWidth*HeightMapHeight));
fTerrainVertices[OffsetedIndex].Position:=TpvVector3.InlineableCreate((x-(HeightMapWidth*0.5))*GridSize,
fTerrainHeightMap[(y*HeightMapWidth)+x],
((y-((HeightMapHeight-1)*(TerrainParts-1)))+((HeightMapHeight-1)*PartIndex))*GridSize);
fTerrainVertices[OffsetedIndex].TexCoord.x:=x;
fTerrainVertices[OffsetedIndex].TexCoord.y:=y+(PartIndex*HeightMapHeight);
//fTerrainVertices[OffsetedIndex].TexCoord:=TpvVector4.InlineableCreate(x,y+(PartIndex*HeightMapHeight),0.0,0.0);
end;
end;
end;
procedure TScreenMainMenuSceneContentRenderPass.TerrainIndicesGenerationParallelForJobMethod(const aJob:PPasMPJob;const aThreadIndex:TPasMPInt32;const aData:pointer;const aFromIndex,aToIndex:TPasMPNativeInt);
var Index,PartIndex,OffsetedIndex,x,y,a,b,c,d:TpvSizeInt;
begin
for Index:=aFromIndex to aToIndex do begin
x:=Index mod (HeightMapWidth-1);
y:=Index div (HeightMapWidth-1);
for PartIndex:=0 to TerrainParts-1 do begin
OffsetedIndex:=(PartIndex*(HeightMapWidth*HeightMapHeight));
a:=(((y+0)*HeightMapWidth)+(x+0))+OffsetedIndex;
b:=(((y+0)*HeightMapWidth)+(x+1))+OffsetedIndex;
c:=(((y+1)*HeightMapWidth)+(x+1))+OffsetedIndex;
d:=(((y+1)*HeightMapWidth)+(x+0))+OffsetedIndex;
OffsetedIndex:=Index+(PartIndex*((HeightMapWidth-1)*(HeightMapHeight-1)));
fTerrainIndices[(OffsetedIndex*6)+0]:=a;
fTerrainIndices[(OffsetedIndex*6)+1]:=b;
fTerrainIndices[(OffsetedIndex*6)+2]:=d;
fTerrainIndices[(OffsetedIndex*6)+3]:=b;
fTerrainIndices[(OffsetedIndex*6)+4]:=c;
fTerrainIndices[(OffsetedIndex*6)+5]:=d;
end;
end;
end;
procedure TScreenMainMenuSceneContentRenderPass.Show;
var x,y:TpvSizeInt;
Stream:TStream;
p:PTerrainTexturePixel;
begin
inherited Show;
fVulkanGraphicsCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.GraphicsQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
fVulkanGraphicsCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice);
fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice);
begin
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_background_vert.spv');
try
fBackgroundVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_background_frag.spv');
try
fBackgroundFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
fBackgroundVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fBackgroundVertexShaderModule,'main');
fBackgroundVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fBackgroundFragmentShaderModule,'main');
fBackgroundVulkanGraphicsPipeline:=nil;
end;
begin
for y:=0 to TerrainTextureSize-1 do begin
for x:=0 to TerrainTextureSize-1 do begin
p:=@fTerrainTextureData[y,x];
if (x<((TerrainTextureBorderSize+1) shr 1)) or
(x>((TerrainTextureSize-1)-((TerrainTextureBorderSize+1) shr 1))) or
(y<((TerrainTextureBorderSize+1) shr 1)) or
(y>((TerrainTextureSize-1)-((TerrainTextureBorderSize+1) shr 1))) then begin
p^.r:=52;
p^.g:=28;
p^.b:=245;
p^.a:=255;
end else begin
p^.r:=0;
p^.g:=13;
p^.b:=51;
p^.a:=255;
end;
end;
end;
fTerrainTexture:=TpvVulkanTexture.CreateFromMemory(pvApplication.VulkanDevice,
pvApplication.VulkanDevice.GraphicsQueue,
fVulkanGraphicsCommandBuffer,
fVulkanGraphicsCommandBufferFence,
pvApplication.VulkanDevice.TransferQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
VK_FORMAT_R8G8B8A8_SRGB,
VK_SAMPLE_COUNT_1_BIT,
TerrainTextureSize,
TerrainTextureSize,
0,
0,
1,
-1,
[TpvVulkanTextureUsageFlag.TransferDst,TpvVulkanTextureUsageFlag.Sampled],
@fTerrainTextureData,
SizeOf(fTerrainTextureData),
false,
false,
1,
true);{}
fTerrainTexture.WrapModeU:=TpvVulkanTextureWrapMode.WrappedRepeat;
fTerrainTexture.WrapModeV:=TpvVulkanTextureWrapMode.WrappedRepeat;
fTerrainTexture.WrapModeW:=TpvVulkanTextureWrapMode.ClampToEdge;
fTerrainTexture.BorderColor:=VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
if pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.maxSamplerAnisotropy>1.0 then begin
fTerrainTexture.MaxAnisotropy:=pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.maxSamplerAnisotropy;
end else begin
fTerrainTexture.MaxAnisotropy:=0.0;
end;
fTerrainTexture.UpdateSampler;
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_terrain_vert.spv');
try
fTerrainVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_terrain_frag.spv');
try
fTerrainFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
fTerrainVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fTerrainVertexShaderModule,'main');
fTerrainVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fTerrainFragmentShaderModule,'main');
fTerrainVulkanGraphicsPipeline:=nil;
fTerrainVulkanVertexBuffer:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(fTerrainVertices),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
fTerrainVulkanVertexBuffer.UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fTerrainVertices,
0,
SizeOf(fTerrainVertices),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
fTerrainVulkanIndexBuffer:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(fTerrainIndices),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_INDEX_BUFFER_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
fTerrainVulkanIndexBuffer.UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fTerrainIndices,
0,
SizeOf(fTerrainIndices),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
begin
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_foreground_vert.spv');
try
fForegroundVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
Stream:=pvApplication.Assets.GetAssetStream('shaders/mainmenu_foreground_frag.spv');
try
fForegroundFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
fForegroundVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fForegroundVertexShaderModule,'main');
fForegroundVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fForegroundFragmentShaderModule,'main');
fForegroundVulkanGraphicsPipeline:=nil;
end;
end;
procedure TScreenMainMenuSceneContentRenderPass.Hide;
begin
FreeAndNil(fForegroundVulkanPipelineShaderStageVertex);
FreeAndNil(fForegroundVulkanPipelineShaderStageFragment);
FreeAndNil(fForegroundFragmentShaderModule);
FreeAndNil(fForegroundVertexShaderModule);
FreeAndNil(fTerrainVulkanIndexBuffer);
FreeAndNil(fTerrainVulkanVertexBuffer);
FreeAndNil(fTerrainVulkanPipelineShaderStageVertex);
FreeAndNil(fTerrainVulkanPipelineShaderStageFragment);
FreeAndNil(fTerrainFragmentShaderModule);
FreeAndNil(fTerrainVertexShaderModule);
FreeAndNil(fTerrainTexture);
FreeAndNil(fBackgroundVulkanPipelineShaderStageVertex);
FreeAndNil(fBackgroundVulkanPipelineShaderStageFragment);
FreeAndNil(fBackgroundFragmentShaderModule);
FreeAndNil(fBackgroundVertexShaderModule);
FreeAndNil(fVulkanTransferCommandBufferFence);
FreeAndNil(fVulkanTransferCommandBuffer);
FreeAndNil(fVulkanGraphicsCommandBufferFence);
FreeAndNil(fVulkanGraphicsCommandBuffer);
inherited Hide;
end;
procedure TScreenMainMenuSceneContentRenderPass.AfterCreateSwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
inherited AfterCreateSwapChain;
fVulkanRenderPass:=VulkanRenderPass;
begin
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fBackgroundVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
0,
0,
0,
0,
0,
[TpvVulkanBufferFlag.PersistentMapped]
);
fBackgroundVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fBackgroundUniformBuffers[SwapChainImageIndex],
0,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
fBackgroundVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice,
TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT),
MaxSwapChainImages);
fBackgroundVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages);
fBackgroundVulkanDescriptorPool.Initialize;
fBackgroundVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice);
fBackgroundVulkanDescriptorSetLayout.AddBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fBackgroundVulkanDescriptorSetLayout.Initialize;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fBackgroundVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fBackgroundVulkanDescriptorPool,
fBackgroundVulkanDescriptorSetLayout);
fBackgroundVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
[],
[fBackgroundVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fBackgroundVulkanDescriptorSets[SwapChainImageIndex].Flush;
end;
fBackgroundVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice);
fBackgroundVulkanPipelineLayout.AddDescriptorSetLayout(fBackgroundVulkanDescriptorSetLayout);
fBackgroundVulkanPipelineLayout.Initialize;
fBackgroundVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice,
pvApplication.VulkanPipelineCache,
0,
[],
fBackgroundVulkanPipelineLayout,
fVulkanRenderPass,
VulkanRenderPassSubpassIndex,
nil,
0);
fBackgroundVulkanGraphicsPipeline.AddStage(fBackgroundVulkanPipelineShaderStageVertex);
fBackgroundVulkanGraphicsPipeline.AddStage(fBackgroundVulkanPipelineShaderStageFragment);
fBackgroundVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
fBackgroundVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false;
fBackgroundVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0);
fBackgroundVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false;
fBackgroundVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false;
fBackgroundVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL;
fBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE);
//fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT);
fBackgroundVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE;
fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false;
fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0;
fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0;
fBackgroundVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0;
fBackgroundVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0;
fBackgroundVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits;
fBackgroundVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false;
fBackgroundVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0;
fBackgroundVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0;
fBackgroundVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false;
fBackgroundVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0;
fBackgroundVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT));
fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=false;
fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=false;
fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS;
fBackgroundVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false;
fBackgroundVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false;
fBackgroundVulkanGraphicsPipeline.Initialize;
fBackgroundVulkanGraphicsPipeline.FreeMemory;
end;
begin
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fTerrainVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(TScreenMainMenuTerrainUniformBuffer),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
0,
0,
0,
0,
0,
[TpvVulkanBufferFlag.PersistentMapped]
);
fTerrainVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fTerrainUniformBuffers[SwapChainImageIndex],
0,
SizeOf(TScreenMainMenuTerrainUniformBuffer),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
fTerrainVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice,
TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT),
MaxSwapChainImages);
fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages);
fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,MaxSwapChainImages);
fTerrainVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,MaxSwapChainImages*2);
fTerrainVulkanDescriptorPool.Initialize;
fTerrainVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice);
fTerrainVulkanDescriptorSetLayout.AddBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fTerrainVulkanDescriptorSetLayout.AddBinding(1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fTerrainVulkanDescriptorSetLayout.AddBinding(2,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT),
[]);
fTerrainVulkanDescriptorSetLayout.AddBinding(3,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT),
[]);
fTerrainVulkanDescriptorSetLayout.Initialize;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fTerrainVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fTerrainVulkanDescriptorPool,
fTerrainVulkanDescriptorSetLayout);
fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
[],
[fTerrainVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER),
[fTerrainTexture.DescriptorImageInfo],
[],
[],
false
);
fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(2,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER),
[],
[fTerrainVulkanVertexBuffer.DescriptorBufferInfo],
[],
false
);
fTerrainVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(3,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER),
[],
[fTerrainVulkanIndexBuffer.DescriptorBufferInfo],
[],
false
);
fTerrainVulkanDescriptorSets[SwapChainImageIndex].Flush;
end;
fTerrainVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice);
fTerrainVulkanPipelineLayout.AddDescriptorSetLayout(fTerrainVulkanDescriptorSetLayout);
fTerrainVulkanPipelineLayout.Initialize;
fTerrainVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice,
pvApplication.VulkanPipelineCache,
0,
[],
fTerrainVulkanPipelineLayout,
fVulkanRenderPass,
VulkanRenderPassSubpassIndex,
nil,
0);
fTerrainVulkanGraphicsPipeline.AddStage(fTerrainVulkanPipelineShaderStageVertex);
fTerrainVulkanGraphicsPipeline.AddStage(fTerrainVulkanPipelineShaderStageFragment);
fTerrainVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
fTerrainVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false;
fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputBindingDescription(0,SizeOf(TTerrainVertex),VK_VERTEX_INPUT_RATE_VERTEX);
fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputAttributeDescription(0,0,VK_FORMAT_R32G32B32_SFLOAT,TpvPtrUInt(pointer(@PTerrainVertex(nil)^.Position)));
fTerrainVulkanGraphicsPipeline.VertexInputState.AddVertexInputAttributeDescription(1,0,VK_FORMAT_R16G16_SFLOAT,TpvPtrUInt(pointer(@PTerrainVertex(nil)^.TexCoord)));
fTerrainVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0);
fTerrainVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
fTerrainVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false;
fTerrainVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false;
fTerrainVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL;
fTerrainVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT);
fTerrainVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE;
fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false;
fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0;
fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0;
fTerrainVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0;
fTerrainVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0;
fTerrainVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits;
fTerrainVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false;
fTerrainVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0;
fTerrainVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0;
fTerrainVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false;
fTerrainVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false;
fTerrainVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false;
fTerrainVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY;
fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0;
fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0;
fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0;
fTerrainVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0;
fTerrainVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT));
fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true;
fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true;
fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_LESS;
fTerrainVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false;
fTerrainVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false;
fTerrainVulkanGraphicsPipeline.Initialize;
fTerrainVulkanGraphicsPipeline.FreeMemory;
end;
begin
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fForegroundVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(TScreenMainMenuForegroundUniformBuffer),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
0,
0,
0,
0,
0,
[TpvVulkanBufferFlag.PersistentMapped]
);
fForegroundVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fForegroundUniformBuffers[SwapChainImageIndex],
0,
SizeOf(TScreenMainMenuForegroundUniformBuffer),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
fForegroundVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice,
TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT),
MaxSwapChainImages);
fForegroundVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages);
fForegroundVulkanDescriptorPool.Initialize;
fForegroundVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice);
fForegroundVulkanDescriptorSetLayout.AddBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fForegroundVulkanDescriptorSetLayout.Initialize;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fForegroundVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fForegroundVulkanDescriptorPool,
fForegroundVulkanDescriptorSetLayout);
fForegroundVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
[],
[fForegroundVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fForegroundVulkanDescriptorSets[SwapChainImageIndex].Flush;
end;
fForegroundVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice);
fForegroundVulkanPipelineLayout.AddDescriptorSetLayout(fForegroundVulkanDescriptorSetLayout);
fForegroundVulkanPipelineLayout.Initialize;
fForegroundVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice,
pvApplication.VulkanPipelineCache,
0,
[],
fForegroundVulkanPipelineLayout,
fVulkanRenderPass,
VulkanRenderPassSubpassIndex,
nil,
0);
fForegroundVulkanGraphicsPipeline.AddStage(fForegroundVulkanPipelineShaderStageVertex);
fForegroundVulkanGraphicsPipeline.AddStage(fForegroundVulkanPipelineShaderStageFragment);
fForegroundVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
fForegroundVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false;
fForegroundVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0);
fForegroundVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
fForegroundVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false;
fForegroundVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false;
fForegroundVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL;
fForegroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE);
//fMainMenuForegroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT);
fForegroundVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE;
fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false;
fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0;
fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0;
fForegroundVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0;
fForegroundVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0;
fForegroundVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=fParent.fVulkanSampleCountFlagBits;
fForegroundVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false;
fForegroundVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0;
fForegroundVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0;
fForegroundVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false;
fForegroundVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false;
fForegroundVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false;
fForegroundVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY;
fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0;
fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0;
fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0;
fForegroundVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0;
fForegroundVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(true,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT));
fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true;
fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true;
fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_LESS;
fForegroundVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false;
fForegroundVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false;
fForegroundVulkanGraphicsPipeline.Initialize;
fForegroundVulkanGraphicsPipeline.FreeMemory;
end;
end;
procedure TScreenMainMenuSceneContentRenderPass.BeforeDestroySwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
begin
FreeAndNil(fForegroundVulkanGraphicsPipeline);
FreeAndNil(fForegroundVulkanPipelineLayout);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fForegroundVulkanDescriptorSets[SwapChainImageIndex]);
end;
FreeAndNil(fForegroundVulkanDescriptorSetLayout);
FreeAndNil(fForegroundVulkanDescriptorPool);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fForegroundVulkanUniformBuffers[SwapChainImageIndex]);
end;
end;
begin
FreeAndNil(fTerrainVulkanGraphicsPipeline);
FreeAndNil(fTerrainVulkanPipelineLayout);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fTerrainVulkanDescriptorSets[SwapChainImageIndex]);
end;
FreeAndNil(fTerrainVulkanDescriptorSetLayout);
FreeAndNil(fTerrainVulkanDescriptorPool);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fTerrainVulkanUniformBuffers[SwapChainImageIndex]);
end;
end;
begin
FreeAndNil(fBackgroundVulkanGraphicsPipeline);
FreeAndNil(fBackgroundVulkanPipelineLayout);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fBackgroundVulkanDescriptorSets[SwapChainImageIndex]);
end;
FreeAndNil(fBackgroundVulkanDescriptorSetLayout);
FreeAndNil(fBackgroundVulkanDescriptorPool);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fBackgroundVulkanUniformBuffers[SwapChainImageIndex]);
end;
end;
fVulkanRenderPass:=nil;
inherited BeforeDestroySwapChain;
end;
procedure TScreenMainMenuSceneContentRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt);
var ModelMatrix,
ViewMatrix,
ViewProjectionMatrix,
InverseViewProjectionMatrix:TpvMatrix4x4;
BackgroundUniformBuffer:PScreenMainMenuBackgroundUniformBuffer;
TerrainUniformBuffer:PScreenMainMenuTerrainUniformBuffer;
ForegroundUniformBuffer:PScreenMainMenuForegroundUniformBuffer;
begin
inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex);
ViewMatrix:=TpvMatrix4x4.CreateFromQuaternion(TpvQuaternion.Create(0.11986792,0.0,0.0,-0.99278980).Normalize);
{
ViewMatrix:=TpvMatrix4x4.CreateTranslation(0.0,0.0,5.0)*
// TpvMatrix4x4.CreateRotateX(fParent.fTime*PI*0.0625)*
TpvMatrix4x4.CreateRotateY(fParent.fTime*PI*0.125)*
TpvMatrix4x4.CreateTranslation(0.0,0.0,-5.0)*
ViewMatrix;{}
ViewProjectionMatrix:=ViewMatrix*
TpvMatrix4x4.CreatePerspectiveRightHandedZeroToOne(53.13010235415598,
pvApplication.VulkanSwapChain.Width/pvApplication.VulkanSwapChain.Height,
1.0,
1024.0)*
TpvMatrix4x4.FlipYClipSpace;
InverseViewProjectionMatrix:=ViewProjectionMatrix.Inverse;
BackgroundUniformBuffer:=@fBackgroundUniformBuffers[aUpdateSwapChainImageIndex];
BackgroundUniformBuffer^.InverseViewProjectionMatrix:=InverseViewProjectionMatrix;
BackgroundUniformBuffer^.Resolution:=TpvVector2.InlineableCreate(pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
BackgroundUniformBuffer^.MusicTick:=fParent.fTime*fParent.fTimeToMusicTickFactor;
BackgroundUniformBuffer^.PressStartOffset:=0.0;
TerrainUniformBuffer:=@fTerrainUniformBuffers[aUpdateSwapChainImageIndex];
TerrainUniformBuffer^.Offset:=Modulo(BackgroundUniformBuffer^.MusicTick*(100.0/(3.0*64.0)),(HeightMapHeight-1)*GridSize);
ModelMatrix:=TpvMatrix4x4.CreateTranslation(0.0,0.0,TerrainUniformBuffer^.Offset);
TerrainUniformBuffer^.ModelViewMatrix:=ModelMatrix*ViewMatrix;
TerrainUniformBuffer^.ModelViewProjectionMatrix:=ModelMatrix*ViewProjectionMatrix;
ForegroundUniformBuffer:=@fForegroundUniformBuffers[aUpdateSwapChainImageIndex];
ForegroundUniformBuffer^.ViewProjectionMatrix:=ViewProjectionMatrix;
ForegroundUniformBuffer^.InverseViewProjectionMatrix:=InverseViewProjectionMatrix;
ForegroundUniformBuffer^.Resolution:=TpvVector2.InlineableCreate(pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
ForegroundUniformBuffer^.MusicTick:=fParent.fTime*fParent.fTimeToMusicTickFactor;
ForegroundUniformBuffer^.PressStartOffset:=0.0;
end;
procedure TScreenMainMenuSceneContentRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt);
var p:pointer;
begin
inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex);
begin
p:=fBackgroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuBackgroundUniformBuffer));
if assigned(p) then begin
try
PScreenMainMenuBackgroundUniformBuffer(p)^:=fBackgroundUniformBuffers[aSwapChainImageIndex];
finally
fBackgroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory;
end;
end;
aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fBackgroundVulkanPipelineLayout.Handle,0,1,@fBackgroundVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil);
aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fBackgroundVulkanGraphicsPipeline.Handle);
aCommandBuffer.CmdDraw(3,1,0,0);
end;{}
begin
p:=fTerrainVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuTerrainUniformBuffer));
if assigned(p) then begin
try
PScreenMainMenuTerrainUniformBuffer(p)^:=fTerrainUniformBuffers[aSwapChainImageIndex];
finally
fTerrainVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory;
end;
end;
aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fTerrainVulkanPipelineLayout.Handle,0,1,@fTerrainVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil);
aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fTerrainVulkanGraphicsPipeline.Handle);
aCommandBuffer.CmdBindVertexBuffers(0,1,@fTerrainVulkanVertexBuffer.Handle,@Offsets);
aCommandBuffer.CmdBindIndexBuffer(fTerrainVulkanIndexBuffer.Handle,0,VK_INDEX_TYPE_UINT32);
aCommandBuffer.CmdDrawIndexed(length(fTerrainIndices),1,0,0,0);
end;{}
begin
p:=fForegroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.MapMemory(0,SizeOf(TScreenMainMenuForegroundUniformBuffer));
if assigned(p) then begin
try
PScreenMainMenuForegroundUniformBuffer(p)^:=fForegroundUniformBuffers[aSwapChainImageIndex];
finally
fForegroundVulkanUniformBuffers[aSwapChainImageIndex].Memory.UnmapMemory;
end;
end;
aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fForegroundVulkanPipelineLayout.Handle,0,1,@fForegroundVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil);
aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fForegroundVulkanGraphicsPipeline.Handle);
aCommandBuffer.CmdDraw(3,1,0,0);
end;{}
end;
constructor TScreenMainMenuTonemappingRenderPass.Create(const aFrameGraph:TpvFrameGraph);
begin
inherited Create(aFrameGraph);
Name:='Tonemapping';
Queue:=aFrameGraph.UniversalQueue;
//SeparatePhysicalPass:=true;
//SeparateCommandBuffer:=true;
Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,
1.0,
1.0);
fResourceColor:=AddImageInput('resourcetype_color',
'scene_color',
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
fResourceSurface:=AddImageOutput('resourcetype_color',
'tonemapping_color',
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
end;
destructor TScreenMainMenuTonemappingRenderPass.Destroy;
begin
inherited Destroy;
end;
procedure TScreenMainMenuTonemappingRenderPass.Show;
var Stream:TStream;
begin
inherited Show;
fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice);
Stream:=pvApplication.Assets.GetAssetStream('shaders/tonemapping_vert.spv');
try
fVulkanVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
Stream:=pvApplication.Assets.GetAssetStream('shaders/tonemapping_frag.spv');
try
fVulkanFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
fVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fVulkanVertexShaderModule,'main');
fVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fVulkanFragmentShaderModule,'main');
fVulkanGraphicsPipeline:=nil;
end;
procedure TScreenMainMenuTonemappingRenderPass.Hide;
begin
FreeAndNil(fVulkanPipelineShaderStageVertex);
FreeAndNil(fVulkanPipelineShaderStageFragment);
FreeAndNil(fVulkanFragmentShaderModule);
FreeAndNil(fVulkanVertexShaderModule);
FreeAndNil(fVulkanTransferCommandBufferFence);
FreeAndNil(fVulkanTransferCommandBuffer);
inherited Hide;
end;
procedure TScreenMainMenuTonemappingRenderPass.AfterCreateSwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
inherited AfterCreateSwapChain;
fVulkanRenderPass:=VulkanRenderPass;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
0,
0,
0,
0,
0,
[TpvVulkanBufferFlag.PersistentMapped]
);
fVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fBackgroundUniformBuffers[SwapChainImageIndex],
0,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
fVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice,
TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT),
MaxSwapChainImages);
fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages);
fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,MaxSwapChainImages);
fVulkanDescriptorPool.Initialize;
fVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice);
fVulkanDescriptorSetLayout.AddBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fVulkanDescriptorSetLayout.AddBinding(1,
VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fVulkanDescriptorSetLayout.Initialize;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fVulkanDescriptorPool,
fVulkanDescriptorSetLayout);
fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
[],
[fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT),
[TVkDescriptorImageInfo.Create(VK_NULL_HANDLE,
fResourceColor.VulkanImageViews[SwapChainImageIndex].Handle,
fResourceColor.ResourceTransition.Layout)],// TVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))],
[fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fVulkanDescriptorSets[SwapChainImageIndex].Flush;
end;
fVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice);
fVulkanPipelineLayout.AddDescriptorSetLayout(fVulkanDescriptorSetLayout);
fVulkanPipelineLayout.Initialize;
fVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice,
pvApplication.VulkanPipelineCache,
0,
[],
fVulkanPipelineLayout,
fVulkanRenderPass,
VulkanRenderPassSubpassIndex,
nil,
0);
fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageVertex);
fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageFragment);
fVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
fVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false;
fVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0);
fVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
fVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL;
fVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE);
//fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT);
fVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0;
fVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0;
fVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=VK_SAMPLE_COUNT_1_BIT;
fVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false;
fVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0;
fVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0;
fVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false;
fVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false;
fVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false;
fVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT));
fVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true;
fVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true;
fVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS;
fVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false;
fVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false;
fVulkanGraphicsPipeline.Initialize;
fVulkanGraphicsPipeline.FreeMemory;
end;
procedure TScreenMainMenuTonemappingRenderPass.BeforeDestroySwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
FreeAndNil(fVulkanGraphicsPipeline);
FreeAndNil(fVulkanPipelineLayout);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fVulkanDescriptorSets[SwapChainImageIndex]);
end;
FreeAndNil(fVulkanDescriptorSetLayout);
FreeAndNil(fVulkanDescriptorPool);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fVulkanUniformBuffers[SwapChainImageIndex]);
end;
fVulkanRenderPass:=nil;
inherited BeforeDestroySwapChain;
end;
procedure TScreenMainMenuTonemappingRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt);
begin
inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex);
end;
procedure TScreenMainMenuTonemappingRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt);
begin
inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex);
aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanPipelineLayout.Handle,0,1,@fVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil);
aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanGraphicsPipeline.Handle);
aCommandBuffer.CmdDraw(3,1,0,0);
end;
constructor TScreenMainMenuAntialiasingRenderPass.Create(const aFrameGraph:TpvFrameGraph);
begin
inherited Create(aFrameGraph);
Name:='Antialiasing';
Queue:=aFrameGraph.UniversalQueue;
//SeparatePhysicalPass:=true;
//SeparateCommandBuffer:=true;
Size:=TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,
1.0,
1.0);
fResourceColor:=AddImageInput('resourcetype_color',
'tonemapping_color',
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
[]
);
fResourceSurface:=AddImageOutput('resourcetype_surface',
'resource_surface',
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TpvFrameGraph.TLoadOp.Create(TpvFrameGraph.TLoadOp.TKind.Clear,
TpvVector4.InlineableCreate(0.0,0.0,0.0,1.0)),
[TpvFrameGraph.TResourceTransition.TFlag.Attachment]
);
end;
destructor TScreenMainMenuAntialiasingRenderPass.Destroy;
begin
inherited Destroy;
end;
procedure TScreenMainMenuAntialiasingRenderPass.Show;
var Stream:TStream;
begin
inherited Show;
fVulkanTransferCommandBuffer:=TpvVulkanCommandBuffer.Create(FrameGraph.TransferQueue.CommandPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY);
fVulkanTransferCommandBufferFence:=TpvVulkanFence.Create(pvApplication.VulkanDevice);
Stream:=pvApplication.Assets.GetAssetStream('shaders/antialiasing_fxaa_vert.spv');
try
fVulkanVertexShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
Stream:=pvApplication.Assets.GetAssetStream('shaders/antialiasing_fxaa_frag.spv');
try
fVulkanFragmentShaderModule:=TpvVulkanShaderModule.Create(pvApplication.VulkanDevice,Stream);
finally
Stream.Free;
end;
fVulkanPipelineShaderStageVertex:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_VERTEX_BIT,fVulkanVertexShaderModule,'main');
fVulkanPipelineShaderStageFragment:=TpvVulkanPipelineShaderStage.Create(VK_SHADER_STAGE_FRAGMENT_BIT,fVulkanFragmentShaderModule,'main');
fVulkanGraphicsPipeline:=nil;
fVulkanSampler:=TpvVulkanSampler.Create(pvApplication.VulkanDevice,
TVkFilter.VK_FILTER_LINEAR,
TVkFilter.VK_FILTER_LINEAR,
TVkSamplerMipmapMode.VK_SAMPLER_MIPMAP_MODE_LINEAR,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
0.0,
false,
0.0,
false,
VK_COMPARE_OP_ALWAYS,
0.0,
0.0,
VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
false);
end;
procedure TScreenMainMenuAntialiasingRenderPass.Hide;
begin
FreeAndNil(fVulkanSampler);
FreeAndNil(fVulkanPipelineShaderStageVertex);
FreeAndNil(fVulkanPipelineShaderStageFragment);
FreeAndNil(fVulkanFragmentShaderModule);
FreeAndNil(fVulkanVertexShaderModule);
FreeAndNil(fVulkanTransferCommandBufferFence);
FreeAndNil(fVulkanTransferCommandBuffer);
inherited Hide;
end;
procedure TScreenMainMenuAntialiasingRenderPass.AfterCreateSwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
inherited AfterCreateSwapChain;
fVulkanRenderPass:=VulkanRenderPass;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fVulkanUniformBuffers[SwapChainImageIndex]:=TpvVulkanBuffer.Create(pvApplication.VulkanDevice,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TVkBufferUsageFlags(VK_BUFFER_USAGE_TRANSFER_DST_BIT) or TVkBufferUsageFlags(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
TVkSharingMode(VK_SHARING_MODE_EXCLUSIVE),
FrameGraph.QueueFamilyIndices.Items,
TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or TVkMemoryPropertyFlags(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
0,
0,
0,
0,
0,
[TpvVulkanBufferFlag.PersistentMapped]
);
fVulkanUniformBuffers[SwapChainImageIndex].UploadData(FrameGraph.TransferQueue.PhysicalQueue,
fVulkanTransferCommandBuffer,
fVulkanTransferCommandBufferFence,
fBackgroundUniformBuffers[SwapChainImageIndex],
0,
SizeOf(TScreenMainMenuBackgroundUniformBuffer),
TpvVulkanBufferUseTemporaryStagingBufferMode.Yes);
end;
fVulkanDescriptorPool:=TpvVulkanDescriptorPool.Create(pvApplication.VulkanDevice,
TVkDescriptorPoolCreateFlags(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT),
MaxSwapChainImages);
fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,MaxSwapChainImages);
fVulkanDescriptorPool.AddDescriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,MaxSwapChainImages);
fVulkanDescriptorPool.Initialize;
fVulkanDescriptorSetLayout:=TpvVulkanDescriptorSetLayout.Create(pvApplication.VulkanDevice);
fVulkanDescriptorSetLayout.AddBinding(0,
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_VERTEX_BIT) or TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fVulkanDescriptorSetLayout.AddBinding(1,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,
TVkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT),
[]);
fVulkanDescriptorSetLayout.Initialize;
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
fVulkanDescriptorSets[SwapChainImageIndex]:=TpvVulkanDescriptorSet.Create(fVulkanDescriptorPool,
fVulkanDescriptorSetLayout);
fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(0,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
[],
[fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fVulkanDescriptorSets[SwapChainImageIndex].WriteToDescriptorSet(1,
0,
1,
TVkDescriptorType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER),
[TVkDescriptorImageInfo.Create(fVulkanSampler.Handle,
fResourceColor.VulkanImageViews[SwapChainImageIndex].Handle,
fResourceColor.ResourceTransition.Layout)],// TVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))],
[fVulkanUniformBuffers[SwapChainImageIndex].DescriptorBufferInfo],
[],
false
);
fVulkanDescriptorSets[SwapChainImageIndex].Flush;
end;
fVulkanPipelineLayout:=TpvVulkanPipelineLayout.Create(pvApplication.VulkanDevice);
fVulkanPipelineLayout.AddDescriptorSetLayout(fVulkanDescriptorSetLayout);
fVulkanPipelineLayout.Initialize;
fVulkanGraphicsPipeline:=TpvVulkanGraphicsPipeline.Create(pvApplication.VulkanDevice,
pvApplication.VulkanPipelineCache,
0,
[],
fVulkanPipelineLayout,
fVulkanRenderPass,
VulkanRenderPassSubpassIndex,
nil,
0);
fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageVertex);
fVulkanGraphicsPipeline.AddStage(fVulkanPipelineShaderStageFragment);
fVulkanGraphicsPipeline.InputAssemblyState.Topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
fVulkanGraphicsPipeline.InputAssemblyState.PrimitiveRestartEnable:=false;
fVulkanGraphicsPipeline.ViewPortState.AddViewPort(0.0,0.0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height,0.0,1.0);
fVulkanGraphicsPipeline.ViewPortState.AddScissor(0,0,pvApplication.VulkanSwapChain.Width,pvApplication.VulkanSwapChain.Height);
fVulkanGraphicsPipeline.RasterizationState.DepthClampEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.RasterizerDiscardEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.PolygonMode:=VK_POLYGON_MODE_FILL;
fVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_NONE);
//fMainMenuBackgroundVulkanGraphicsPipeline.RasterizationState.CullMode:=TVkCullModeFlags(VK_CULL_MODE_BACK_BIT);
fVulkanGraphicsPipeline.RasterizationState.FrontFace:=VK_FRONT_FACE_CLOCKWISE;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasEnable:=false;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasConstantFactor:=0.0;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasClamp:=0.0;
fVulkanGraphicsPipeline.RasterizationState.DepthBiasSlopeFactor:=0.0;
fVulkanGraphicsPipeline.RasterizationState.LineWidth:=1.0;
fVulkanGraphicsPipeline.MultisampleState.RasterizationSamples:=VK_SAMPLE_COUNT_1_BIT;
fVulkanGraphicsPipeline.MultisampleState.SampleShadingEnable:=false;
fVulkanGraphicsPipeline.MultisampleState.MinSampleShading:=0.0;
fVulkanGraphicsPipeline.MultisampleState.CountSampleMasks:=0;
fVulkanGraphicsPipeline.MultisampleState.AlphaToCoverageEnable:=false;
fVulkanGraphicsPipeline.MultisampleState.AlphaToOneEnable:=false;
fVulkanGraphicsPipeline.ColorBlendState.LogicOpEnable:=false;
fVulkanGraphicsPipeline.ColorBlendState.LogicOp:=VK_LOGIC_OP_COPY;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[0]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[1]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[2]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.BlendConstants[3]:=0.0;
fVulkanGraphicsPipeline.ColorBlendState.AddColorBlendAttachmentState(false,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_OP_ADD,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_ZERO,
VK_BLEND_OP_ADD,
TVkColorComponentFlags(VK_COLOR_COMPONENT_R_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_G_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_B_BIT) or
TVkColorComponentFlags(VK_COLOR_COMPONENT_A_BIT));
fVulkanGraphicsPipeline.DepthStencilState.DepthTestEnable:=true;
fVulkanGraphicsPipeline.DepthStencilState.DepthWriteEnable:=true;
fVulkanGraphicsPipeline.DepthStencilState.DepthCompareOp:=VK_COMPARE_OP_ALWAYS;
fVulkanGraphicsPipeline.DepthStencilState.DepthBoundsTestEnable:=false;
fVulkanGraphicsPipeline.DepthStencilState.StencilTestEnable:=false;
fVulkanGraphicsPipeline.Initialize;
fVulkanGraphicsPipeline.FreeMemory;
end;
procedure TScreenMainMenuAntialiasingRenderPass.BeforeDestroySwapChain;
var SwapChainImageIndex:TpvSizeInt;
begin
FreeAndNil(fVulkanGraphicsPipeline);
FreeAndNil(fVulkanPipelineLayout);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fVulkanDescriptorSets[SwapChainImageIndex]);
end;
FreeAndNil(fVulkanDescriptorSetLayout);
FreeAndNil(fVulkanDescriptorPool);
for SwapChainImageIndex:=0 to FrameGraph.CountSwapChainImages-1 do begin
FreeAndNil(fVulkanUniformBuffers[SwapChainImageIndex]);
end;
fVulkanRenderPass:=nil;
inherited BeforeDestroySwapChain;
end;
procedure TScreenMainMenuAntialiasingRenderPass.Update(const aUpdateSwapChainImageIndex,aUpdateFrameIndex:TpvSizeInt);
begin
inherited Update(aUpdateSwapChainImageIndex,aUpdateFrameIndex);
end;
procedure TScreenMainMenuAntialiasingRenderPass.Execute(const aCommandBuffer:TpvVulkanCommandBuffer;const aSwapChainImageIndex,aFrameIndex:TpvSizeInt);
begin
inherited Execute(aCommandBuffer,aSwapChainImageIndex,aFrameIndex);
aCommandBuffer.CmdBindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanPipelineLayout.Handle,0,1,@fVulkanDescriptorSets[aSwapChainImageIndex].Handle,0,nil);
aCommandBuffer.CmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS,fVulkanGraphicsPipeline.Handle);
aCommandBuffer.CmdDraw(3,1,0,0);
end;
{ TScreenMainMenu }
constructor TScreenMainMenu.Create;
const ProjectSampleRate=44100;
BPM=90*100;
TicksPerRow=3;
RowsPerBeat=8;
InaccurateBPM=true;
var WaitSamples:TpvInt64;
WaitSamplesFloat:TpvDouble;
SampleCounts:TVkSampleCountFlags;
begin
inherited Create;
if (RowsPerBeat=0) or (TicksPerRow=0) then begin
WaitSamples:=(TpvInt64(ProjectSampleRate)*6000*TpvInt64($100000000)) div (BPM*6*4);
end else begin
WaitSamples:=(TpvInt64(ProjectSampleRate)*6000*TpvInt64($100000000)) div (BPM*TicksPerRow*RowsPerBeat);
end;
if InaccurateBPM then begin
WaitSamples:=WaitSamples and $ffffffff00000000;
end;
WaitSamplesFloat:=WaitSamples/TpvInt64($100000000);
fTimeToMusicTickFactor:=ProjectSampleRate/WaitSamplesFloat;
fAudioSoundOGGSoundTrack1:=pvApplication.Audio.OGGs.Load('soundtrack1',pvApplication.Assets.GetAssetStream('music/soundtrack1.ogg'),true);
fFrameGraph:=TpvFrameGraph.Create(pvApplication.VulkanDevice);
fFrameGraph.SurfaceIsSwapchain:=true;
SampleCounts:=pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferColorSampleCounts and
pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferDepthSampleCounts and
pvApplication.VulkanDevice.PhysicalDevice.Properties.limits.framebufferStencilSampleCounts;
if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_8_BIT))<>0 then begin
fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_8_BIT);
end else if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_4_BIT))<>0 then begin
fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_4_BIT);
end else if (SampleCounts and TVkSampleCountFlags(VK_SAMPLE_COUNT_2_BIT))<>0 then begin
fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_2_BIT);
end else begin
fVulkanSampleCountFlagBits:=TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT);
end;
fFrameGraph.AddImageResourceType('resourcetype_surface',
true,
VK_FORMAT_B8G8R8A8_SRGB,
TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT),
TpvFrameGraph.TImageType.Surface,
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT),
1
);
fFrameGraph.AddImageResourceType('resourcetype_msaa_color',
true,
VK_FORMAT_R16G16B16A16_SFLOAT,
fVulkanSampleCountFlagBits,
TpvFrameGraph.TImageType.Color,
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT),
1
);
fFrameGraph.AddImageResourceType('resourcetype_msaa_depth',
true,
pvApplication.VulkanDepthImageFormat,
fVulkanSampleCountFlagBits,
TpvFrameGraph.TImageType.From(pvApplication.VulkanDepthImageFormat),
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT),
1
);
fFrameGraph.AddImageResourceType('resourcetype_color',
true,
VK_FORMAT_R16G16B16A16_SFLOAT,
TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT),
TpvFrameGraph.TImageType.Color,
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT),
1
);
fFrameGraph.AddImageResourceType('resourcetype_srgb_color',
true,
VK_FORMAT_R8G8B8A8_SRGB,
TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT),
TpvFrameGraph.TImageType.Color,
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_SAMPLED_BIT),
1
);
fFrameGraph.AddImageResourceType('resourcetype_depth',
true,
pvApplication.VulkanDepthImageFormat,
TVkSampleCountFlagBits(VK_SAMPLE_COUNT_1_BIT),
TpvFrameGraph.TImageType.From(pvApplication.VulkanDepthImageFormat),
TpvFrameGraph.TImageSize.Create(TpvFrameGraph.TImageSize.TKind.SurfaceDependent,1.0,1.0),
TVkImageUsageFlags(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) or TVkImageUsageFlags(VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT),
1
);
fSceneContentRenderPass:=TScreenMainMenuSceneContentRenderPass.Create(fFrameGraph,self);
fTonemappingRenderPass:=TScreenMainMenuTonemappingRenderPass.Create(fFrameGraph);
fAntialiasingRenderPass:=TScreenMainMenuAntialiasingRenderPass.Create(fFrameGraph);
fFrameGraph.RootPass:=fAntialiasingRenderPass;
fFrameGraph.DoWaitOnSemaphore:=true;
fFrameGraph.DoSignalSemaphore:=true;
fFrameGraph.Compile;
fSelectedIndex:=-1;
fReady:=false;
end;
destructor TScreenMainMenu.Destroy;
begin
FreeAndNil(fFrameGraph);
FreeAndNil(fAudioSoundOGGSoundTrack1);
inherited Destroy;
end;
procedure TScreenMainMenu.Show;
var Index:TpvInt32;
begin
inherited Show;
for Index:=0 to MaxSwapChainImages-1 do begin
fVulkanRenderSemaphores[Index]:=TpvVulkanSemaphore.Create(pvApplication.VulkanDevice);
end;
fFrameGraph.Show;
fTime:=0.0;
fAudioSoundOGGSoundTrack1.Play(0.0,0.0,1.0,true);
end;
procedure TScreenMainMenu.Hide;
var Index:TpvInt32;
begin
fFrameGraph.Hide;
fAudioSoundOGGSoundTrack1.Stop;
for Index:=0 to MaxSwapChainImages-1 do begin
FreeAndNil(fVulkanRenderSemaphores[Index]);
end;
inherited Hide;
end;
procedure TScreenMainMenu.Resume;
begin
inherited Resume;
end;
procedure TScreenMainMenu.Pause;
begin
inherited Pause;
end;
procedure TScreenMainMenu.Resize(const aWidth,aHeight:TpvInt32);
begin
inherited Resize(aWidth,aHeight);
end;
procedure TScreenMainMenu.AfterCreateSwapChain;
begin
inherited AfterCreateSwapChain;
fFrameGraph.SetSwapChain(pvApplication.VulkanSwapChain,
pvApplication.VulkanDepthImageFormat);
fFrameGraph.AfterCreateSwapChain;
end;
procedure TScreenMainMenu.BeforeDestroySwapChain;
begin
fFrameGraph.BeforeDestroySwapChain;
inherited BeforeDestroySwapChain;
end;
function TScreenMainMenu.KeyEvent(const aKeyEvent:TpvApplicationInputKeyEvent):boolean;
begin
result:=false;
if fReady and (aKeyEvent.KeyEventType=TpvApplicationInputKeyEventType.Down) then begin
case aKeyEvent.KeyCode of
KEYCODE_AC_BACK,KEYCODE_ESCAPE:begin
// pvApplication.NextScreen:=TScreenMainMenu.Create;
pvApplication.Terminate;
end;
KEYCODE_UP:begin
if fSelectedIndex<=0 then begin
fSelectedIndex:=0;
end else begin
dec(fSelectedIndex);
end;
end;
KEYCODE_DOWN:begin
if fSelectedIndex>=0 then begin
fSelectedIndex:=0;
end else begin
inc(fSelectedIndex);
end;
end;
KEYCODE_PAGEUP:begin
if fSelectedIndex<0 then begin
fSelectedIndex:=0;
end;
end;
KEYCODE_PAGEDOWN:begin
if fSelectedIndex<0 then begin
fSelectedIndex:=0;
end;
end;
KEYCODE_HOME:begin
fSelectedIndex:=0;
end;
KEYCODE_END:begin
fSelectedIndex:=0
end;
KEYCODE_RETURN,KEYCODE_SPACE:begin
if fSelectedIndex=0 then begin
// pvApplication.NextScreen:=TScreenMainMenu.Create;
end;
end;
end;
end;
end;
function TScreenMainMenu.PointerEvent(const aPointerEvent:TpvApplicationInputPointerEvent):boolean;
var Index:TpvInt32;
cy:TpvFloat;
begin
result:=false;
{if fReady then begin
case aPointerEvent.PointerEventType of
TpvApplicationInputPointerEventType.Down:begin
fSelectedIndex:=-1;
cy:=fStartY;
for Index:=0 to 0 do begin
if (aPointerEvent.Position.y>=cy) and (aPointerEvent.Position.y<(cy+(Application.TextOverlay.FontCharHeight*FontSize))) then begin
fSelectedIndex:=Index;
if fSelectedIndex=0 then begin
pvApplication.NextScreen:=TScreenMainMenu.Create;
end;
end;
cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize);
end;
end;
TpvApplicationInputPointerEventType.Up:begin
end;
TpvApplicationInputPointerEventType.Motion:begin
fSelectedIndex:=-1;
cy:=fStartY;
for Index:=0 to 0 do begin
if (aPointerEvent.Position.y>=cy) and (aPointerEvent.Position.y<(cy+(Application.TextOverlay.FontCharHeight*FontSize))) then begin
fSelectedIndex:=Index;
end;
cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize);
end;
end;
TpvApplicationInputPointerEventType.Drag:begin
end;
end;
end;}
end;
function TScreenMainMenu.Scrolled(const aRelativeAmount:TpvVector2):boolean;
begin
result:=false;
end;
function TScreenMainMenu.CanBeParallelProcessed:boolean;
begin
result:=true;
end;
procedure TScreenMainMenu.Update(const aDeltaTime:TpvDouble);
begin
inherited Update(aDeltaTime);
fFrameGraph.Update(pvApplication.UpdateSwapChainImageIndex,pvApplication.UpdateFrameCounter);
{Application.TextOverlay.AddText(pvApplication.Width*0.5,Application.TextOverlay.FontCharHeight*1.0,2.0,toaCenter,'MainMenu');
fStartY:=pvApplication.Height-((((Application.TextOverlay.FontCharHeight+4)*FontSize)*1.25)-(4*FontSize));
cy:=fStartY;
for Index:=0 to 0 do begin
IsSelected:=fSelectedIndex=Index;
s:=' '+Options[Index]+' ';
if IsSelected then begin
s:='>'+s+'<';
end;
Application.TextOverlay.AddText(pvApplication.Width*0.5,cy,FontSize,toaCenter,TpvRawByteString(s),MenuColors[IsSelected,0,0],MenuColors[IsSelected,0,1],MenuColors[IsSelected,0,2],MenuColors[IsSelected,0,3],MenuColors[IsSelected,1,0],MenuColors[IsSelected,1,1],MenuColors[IsSelected,1,2],MenuColors[IsSelected,1,3]);
cy:=cy+((Application.TextOverlay.FontCharHeight+4)*FontSize);
end;}
fReady:=true;
fTime:=fTime+aDeltaTime;
end;
procedure TScreenMainMenu.Draw(const aSwapChainImageIndex:TpvInt32;var aWaitSemaphore:TpvVulkanSemaphore;const aWaitFence:TpvVulkanFence=nil);
begin
inherited Draw(aSwapChainImageIndex,aWaitSemaphore,nil);
fFrameGraph.Draw(aSwapChainImageIndex,
pvApplication.DrawFrameCounter,
aWaitSemaphore,
fVulkanRenderSemaphores[aSwapChainImageIndex],
aWaitFence);
aWaitSemaphore:=fVulkanRenderSemaphores[aSwapChainImageIndex];
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment