mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-23 06:19:57 +00:00
2e04d5d3fa
* Unit names should match with file names to avoid case sensitive issue on Unix system * Explicit state the build is for win64 target
645 lines
19 KiB
ObjectPascal
645 lines
19 KiB
ObjectPascal
unit vRender;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes,
|
|
SysUtils,
|
|
RWLock,
|
|
sys_types,
|
|
g23tree,
|
|
ps4_libSceVideoOut,
|
|
si_ci_vi_merged_enum,
|
|
Vulkan,
|
|
vDevice,
|
|
vMemory,
|
|
vShader,
|
|
vShaderExt,
|
|
vPipeline,
|
|
//vSetsPools,
|
|
vImage;
|
|
|
|
type
|
|
TvComputePipeline2=class(TvComputePipeline)
|
|
FRefs:ptruint;
|
|
Procedure Acquire(Sender:TObject);
|
|
Procedure Release(Sender:TOBject);
|
|
end;
|
|
|
|
TvRenderPass=class(vPipeline.TvRenderPass)
|
|
|
|
AtCount:TVkUInt32;
|
|
ColorAt:array[0..8] of TVkAttachmentDescription;
|
|
|
|
ColorRef:array[0..7] of TVkAttachmentReference; //subpass.colorAttachmentCount
|
|
|
|
pDepthStencilRef:TVkAttachmentReference;
|
|
|
|
subpass:TVkSubpassDescription;
|
|
dependency:TVkSubpassDependency;
|
|
|
|
Procedure Clear;
|
|
Procedure SetZorderStage(s:TVkPipelineStageFlags);
|
|
Procedure AddColorRef(id:TVkUInt32;IMAGE_USAGE:Byte);
|
|
Procedure SetDepthStencilRef(id:TVkUInt32;DEPTH_USAGE,STENCIL_USAGE:Byte);
|
|
Procedure AddColorAt(format:TVkFormat;IMAGE_USAGE:Byte;samples:TVkSampleCountFlagBits);
|
|
Procedure AddDepthAt(format:TVkFormat;DEPTH_USAGE,STENCIL_USAGE:Byte);
|
|
Function Compile:Boolean;
|
|
end;
|
|
|
|
TvGraphicsPipeline=class(TvPipeline)
|
|
FRenderPass:TvRenderPass;
|
|
|
|
Viewports:array[0..15] of TVkViewport; //viewportState.viewportCount
|
|
Scissors :array[0..15] of TVkRect2D; //viewportState.scissorCount
|
|
|
|
ColorBlends:array[0..7] of TVkPipelineColorBlendAttachmentState; //colorBlending.attachmentCount
|
|
|
|
FShaderGroup:TvShaderGroup;
|
|
|
|
dynamicStates:array[0..1] of TVkDynamicState; //dynamicState.dynamicStateCount
|
|
|
|
vertexInputInfo:TVkPipelineVertexInputStateCreateInfo;
|
|
inputAssembly:TVkPipelineInputAssemblyStateCreateInfo;
|
|
viewportState:TVkPipelineViewportStateCreateInfo;
|
|
rasterizer:TVkPipelineRasterizationStateCreateInfo;
|
|
multisampling:TVkPipelineMultisampleStateCreateInfo;
|
|
colorBlending:TVkPipelineColorBlendStateCreateInfo;
|
|
DepthStencil:TVkPipelineDepthStencilStateCreateInfo;
|
|
dynamicState:TVkPipelineDynamicStateCreateInfo;
|
|
|
|
emulate_primtype:Integer;
|
|
|
|
Procedure SetPrimType(t:TVkPrimitiveTopology);
|
|
Procedure SetPrimReset(enable:TVkBool32);
|
|
Procedure AddVPort(const V:TVkViewport;const S:TVkRect2D);
|
|
Procedure AddBlend(const b:TVkPipelineColorBlendAttachmentState);
|
|
Procedure Clear;
|
|
procedure SetBlendColors(P:PSingle);
|
|
procedure SetRenderPass(RenderPass:TvRenderPass);
|
|
function Compile:Boolean;
|
|
end;
|
|
|
|
TvRenderTargets=class
|
|
FRenderPass:TvRenderPass;
|
|
FPipeline:TvGraphicsPipeline;
|
|
FFramebuffer:TvFramebuffer;
|
|
FRenderArea:TVkRect2D;
|
|
FClearValuesCount:TVkUInt32;
|
|
FClearValues:array[0..8] of TVkClearValue;
|
|
//
|
|
FRefs:ptruint;
|
|
//
|
|
Procedure AddClearColor(clr:TVkClearValue);
|
|
Function GetInfo:TVkRenderPassBeginInfo;
|
|
class function c(const a,b:TvRenderTargets):Integer;
|
|
Destructor Destroy; override;
|
|
Procedure Acquire(Sender:TObject);
|
|
Procedure Release(Sender:TOBject);
|
|
end;
|
|
|
|
TvRenderTargetsSet=specialize T23treeSet<TvRenderTargets,TvRenderTargets>;
|
|
|
|
Function GetDepthStencilLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
Function GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags;
|
|
Function GetColorAccessMask(IMAGE_USAGE:Byte):TVkAccessFlags;
|
|
|
|
implementation
|
|
|
|
{
|
|
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);
|
|
);
|
|
|
|
img_ext:TVkExternalMemoryImageCreateInfo=(
|
|
sType:VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
|
|
pNext:nil;
|
|
handleTypes:ord(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
|
|
);
|
|
}
|
|
|
|
Procedure TvRenderPass.Clear;
|
|
begin
|
|
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyRenderPass(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
|
|
AtCount:=0;
|
|
|
|
FillChar(ColorAt,SizeOf(ColorAt),0);
|
|
FillChar(ColorRef,SizeOf(ColorRef),0);
|
|
|
|
subpass:=Default(TVkSubpassDescription);
|
|
subpass.pipelineBindPoint:=VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
|
|
subpass.inputAttachmentCount :=0;
|
|
subpass.pInputAttachments :=nil;
|
|
|
|
subpass.colorAttachmentCount:=0;
|
|
subpass.pColorAttachments :=@ColorRef;
|
|
|
|
subpass.pResolveAttachments :=nil; //colorAttachmentCount VK_ATTACHMENT_UNUSED
|
|
|
|
subpass.pDepthStencilAttachment:=nil; //1
|
|
|
|
subpass.preserveAttachmentCount:=0;
|
|
subpass.pPreserveAttachments :=nil;
|
|
|
|
dependency:=Default(TVkSubpassDependency);
|
|
|
|
dependency.srcSubpass :=VK_SUBPASS_EXTERNAL;
|
|
dependency.dstSubpass :=0;
|
|
|
|
dependency.srcStageMask :=0{ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)};
|
|
dependency.dstStageMask :=0{ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)};
|
|
|
|
dependency.srcAccessMask:=0;
|
|
dependency.dstAccessMask:=0{ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)};
|
|
end;
|
|
|
|
Procedure TvRenderPass.SetZorderStage(s:TVkPipelineStageFlags);
|
|
begin
|
|
dependency.srcStageMask:=dependency.srcStageMask or s;
|
|
dependency.dstStageMask:=dependency.dstStageMask or s;
|
|
end;
|
|
|
|
Procedure TvRenderPass.AddColorRef(id:TVkUInt32;IMAGE_USAGE:Byte);
|
|
var
|
|
am:TVkAccessFlags;
|
|
begin
|
|
if (subpass.colorAttachmentCount>7) then Exit;
|
|
ColorRef[subpass.colorAttachmentCount].attachment:=id;
|
|
ColorRef[subpass.colorAttachmentCount].layout :={VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}VK_IMAGE_LAYOUT_GENERAL;
|
|
Inc(subpass.colorAttachmentCount);
|
|
|
|
dependency.srcStageMask :=dependency.srcStageMask or ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
|
dependency.dstStageMask :=dependency.dstStageMask or ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
|
|
|
am:=GetColorAccessMask(IMAGE_USAGE);
|
|
|
|
dependency.srcAccessMask:=dependency.srcAccessMask or am;
|
|
dependency.dstAccessMask:=dependency.dstAccessMask or am;
|
|
end;
|
|
|
|
Procedure TvRenderPass.SetDepthStencilRef(id:TVkUInt32;DEPTH_USAGE,STENCIL_USAGE:Byte);
|
|
var
|
|
am:TVkAccessFlags;
|
|
begin
|
|
subpass.pDepthStencilAttachment:=@pDepthStencilRef;
|
|
|
|
pDepthStencilRef.attachment :=id;
|
|
pDepthStencilRef.layout :=GetDepthStencilLayout(DEPTH_USAGE,STENCIL_USAGE);
|
|
|
|
am:=GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE);
|
|
|
|
dependency.srcAccessMask:=dependency.srcAccessMask or am;
|
|
dependency.dstAccessMask:=dependency.dstAccessMask or am;
|
|
end;
|
|
|
|
Procedure TvRenderPass.AddColorAt(format:TVkFormat;IMAGE_USAGE:Byte;samples:TVkSampleCountFlagBits);
|
|
begin
|
|
if (AtCount>8) then Exit;
|
|
|
|
format:=vkFixFormatSupport(format,VK_IMAGE_TILING_OPTIMAL,ord(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
|
|
|
|
ColorAt[AtCount]:=Default(TVkAttachmentDescription);
|
|
ColorAt[AtCount].format :=format;
|
|
ColorAt[AtCount].samples :=samples{VK_SAMPLE_COUNT_1_BIT};
|
|
|
|
With ColorAt[AtCount] do
|
|
if (IMAGE_USAGE and TM_CLEAR<>0) then
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
end else
|
|
if (IMAGE_USAGE and TM_READ<>0) then
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
end else
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (IMAGE_USAGE and TM_WRITE<>0) then
|
|
begin
|
|
storeOp:=VK_ATTACHMENT_STORE_OP_STORE;
|
|
end else
|
|
begin
|
|
storeOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
end;
|
|
|
|
ColorAt[AtCount].stencilLoadOp :=VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
ColorAt[AtCount].stencilStoreOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (IMAGE_USAGE and TM_READ<>0) then
|
|
begin
|
|
initialLayout :={VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}VK_IMAGE_LAYOUT_GENERAL;
|
|
end else
|
|
begin
|
|
initialLayout :=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
finalLayout:={VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}VK_IMAGE_LAYOUT_GENERAL;
|
|
|
|
Inc(AtCount);
|
|
end;
|
|
|
|
Function GetDepthStencilLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout;
|
|
begin
|
|
if ((DEPTH_USAGE or STENCIL_USAGE) and (TM_WRITE or TM_CLEAR)<>0) then
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
end else
|
|
begin
|
|
Result:=VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
end;
|
|
end;
|
|
|
|
Function GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags;
|
|
begin
|
|
Result:=(ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) *ord((DEPTH_USAGE or STENCIL_USAGE) and TM_READ <>0) ) or
|
|
(ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)*ord((DEPTH_USAGE or STENCIL_USAGE) and (TM_WRITE or TM_CLEAR)<>0) );
|
|
end;
|
|
|
|
Function GetColorAccessMask(IMAGE_USAGE:Byte):TVkAccessFlags;
|
|
begin
|
|
Result:=(ord(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) *ord(IMAGE_USAGE and TM_READ<>0) ) or
|
|
(ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)*ord(IMAGE_USAGE and (TM_WRITE or TM_CLEAR)<>0) );
|
|
end;
|
|
|
|
Procedure TvRenderPass.AddDepthAt(format:TVkFormat;DEPTH_USAGE,STENCIL_USAGE:Byte);
|
|
begin
|
|
if (AtCount>8) then Exit;
|
|
|
|
format:=vkFixFormatSupport(format,VK_IMAGE_TILING_OPTIMAL,ord(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
|
|
|
|
ColorAt[AtCount]:=Default(TVkAttachmentDescription);
|
|
ColorAt[AtCount].format :=format;
|
|
ColorAt[AtCount].samples :=VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (DEPTH_USAGE and TM_CLEAR<>0) then
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
end else
|
|
if (DEPTH_USAGE and TM_READ<>0) then
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
end else
|
|
begin
|
|
loadOp:=VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (DEPTH_USAGE and TM_WRITE<>0) then
|
|
begin
|
|
storeOp:=VK_ATTACHMENT_STORE_OP_STORE;
|
|
end else
|
|
begin
|
|
storeOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (STENCIL_USAGE and TM_CLEAR<>0) then
|
|
begin
|
|
stencilLoadOp:=VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
end else
|
|
if (STENCIL_USAGE and TM_READ<>0) then
|
|
begin
|
|
stencilLoadOp:=VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
end else
|
|
begin
|
|
stencilLoadOp:=VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
if (STENCIL_USAGE and TM_WRITE<>0) then
|
|
begin
|
|
stencilStoreOp:=VK_ATTACHMENT_STORE_OP_STORE;
|
|
end else
|
|
begin
|
|
stencilStoreOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
if ((DEPTH_USAGE or STENCIL_USAGE) and TM_READ<>0) then
|
|
begin
|
|
initialLayout :=GetDepthStencilLayout(DEPTH_USAGE,STENCIL_USAGE);
|
|
end else
|
|
begin
|
|
initialLayout :=VK_IMAGE_LAYOUT_UNDEFINED;
|
|
end;
|
|
|
|
With ColorAt[AtCount] do
|
|
finalLayout:=GetDepthStencilLayout(DEPTH_USAGE,STENCIL_USAGE);
|
|
|
|
Inc(AtCount);
|
|
end;
|
|
|
|
Function TvRenderPass.Compile:Boolean;
|
|
var
|
|
r:TVkResult;
|
|
info:TVkRenderPassCreateInfo;
|
|
begin
|
|
Result:=False;
|
|
if (AtCount=0) then Exit;
|
|
|
|
if (FHandle<>VK_NULL_HANDLE) then Exit(True);
|
|
|
|
info:=Default(TVkRenderPassCreateInfo);
|
|
info.sType :=VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
info.attachmentCount:=AtCount;
|
|
info.pAttachments :=@ColorAt;
|
|
info.subpassCount :=1;
|
|
info.pSubpasses :=@subpass;
|
|
info.dependencyCount:=1;
|
|
info.pDependencies :=@dependency;
|
|
|
|
r:=vkCreateRenderPass(Device.FHandle,@info,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateRenderPass:',r);
|
|
Exit;
|
|
end;
|
|
|
|
Result:=True;
|
|
end;
|
|
|
|
//
|
|
|
|
Procedure TvGraphicsPipeline.SetPrimType(t:TVkPrimitiveTopology);
|
|
begin
|
|
Case ord(t) of
|
|
ord(VK_PRIMITIVE_TOPOLOGY_POINT_LIST)..ord(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY):
|
|
begin
|
|
inputAssembly.topology:=t;
|
|
emulate_primtype:=0;
|
|
end;
|
|
|
|
DI_PT_RECTLIST:
|
|
begin
|
|
inputAssembly.topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
|
emulate_primtype:=Integer(t);
|
|
end;
|
|
DI_PT_LINELOOP ,
|
|
DI_PT_QUADLIST ,
|
|
DI_PT_QUADSTRIP,
|
|
DI_PT_POLYGON :
|
|
begin
|
|
inputAssembly.topology:=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
|
emulate_primtype:=Integer(t);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
Procedure TvGraphicsPipeline.SetPrimReset(enable:TVkBool32);
|
|
begin
|
|
inputAssembly.primitiveRestartEnable:=enable;
|
|
end;
|
|
|
|
Procedure TvGraphicsPipeline.AddVPort(const V:TVkViewport;const S:TVkRect2D);
|
|
begin
|
|
if (s.extent.width=0) or (s.extent.height=0) then Assert(false);
|
|
|
|
if (viewportState.viewportCount>15) then Exit;
|
|
Viewports[viewportState.viewportCount]:=V;
|
|
Scissors [viewportState.viewportCount]:=S;
|
|
Inc(viewportState.viewportCount);
|
|
viewportState.scissorCount:=viewportState.viewportCount;
|
|
end;
|
|
|
|
Procedure TvGraphicsPipeline.AddBlend(const b:TVkPipelineColorBlendAttachmentState);
|
|
begin
|
|
if (colorBlending.attachmentCount>7) then Exit;
|
|
ColorBlends[colorBlending.attachmentCount]:=b;
|
|
Inc(colorBlending.attachmentCount);
|
|
end;
|
|
|
|
Procedure TvGraphicsPipeline.Clear;
|
|
begin
|
|
|
|
if (FHandle<>VK_NULL_HANDLE) then
|
|
begin
|
|
vkDestroyPipeline(Device.FHandle,FHandle,nil);
|
|
FHandle:=VK_NULL_HANDLE;
|
|
end;
|
|
|
|
vertexInputInfo:=Default(TVkPipelineVertexInputStateCreateInfo);
|
|
vertexInputInfo.sType :=VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
|
|
|
inputAssembly:=Default(TVkPipelineInputAssemblyStateCreateInfo);
|
|
inputAssembly.sType :=VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
|
inputAssembly.topology :=VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
|
inputAssembly.primitiveRestartEnable:=VK_FALSE; //VGT_MULTI_PRIM_IB_RESET_EN
|
|
|
|
FillChar(Viewports ,SizeOf(Viewports),0);
|
|
FillChar(Scissors ,SizeOf(Scissors) ,0);
|
|
FillChar(ColorBlends,SizeOf(ColorBlends),0);
|
|
|
|
FShaderGroup:=nil;
|
|
|
|
viewportState:=Default(TVkPipelineViewportStateCreateInfo);
|
|
viewportState.sType :=VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
|
viewportState.viewportCount:=0;
|
|
viewportState.pViewports :=@Viewports;
|
|
viewportState.scissorCount :=0;
|
|
viewportState.pScissors :=@Scissors;
|
|
|
|
rasterizer:=Default(TVkPipelineRasterizationStateCreateInfo);
|
|
rasterizer.sType :=VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
|
rasterizer.depthClampEnable:=VK_FALSE;
|
|
rasterizer.rasterizerDiscardEnable:=VK_FALSE; //DB_SHADER_CONTROL.KILL_ENABLE DB_RENDER_CONTROL.FORCE_COLOR_KILL
|
|
rasterizer.polygonMode :=VK_POLYGON_MODE_FILL; //PA_SU_SC_MODE_CNTL.POLY_MODE POLYMODE_FRONT_PTYPE POLYMODE_BACK_PTYPE
|
|
rasterizer.lineWidth :=1; //PA_SU_LINE_CNTL.WIDTH
|
|
rasterizer.cullMode :=ord(VK_CULL_MODE_NONE); //CULL_FRONT CULL_BACK
|
|
rasterizer.frontFace :=VK_FRONT_FACE_COUNTER_CLOCKWISE; //FACE
|
|
rasterizer.depthBiasEnable :=VK_FALSE;
|
|
rasterizer.depthBiasConstantFactor:=0;
|
|
rasterizer.depthBiasClamp :=0;
|
|
rasterizer.depthBiasSlopeFactor :=0;
|
|
|
|
multisampling:=Default(TVkPipelineMultisampleStateCreateInfo);
|
|
multisampling.sType :=VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
|
multisampling.sampleShadingEnable :=VK_FALSE;
|
|
multisampling.rasterizationSamples :=VK_SAMPLE_COUNT_1_BIT;
|
|
multisampling.minSampleShading :=1;
|
|
multisampling.pSampleMask :=nil;
|
|
multisampling.alphaToCoverageEnable:=VK_FALSE;
|
|
multisampling.alphaToOneEnable :=VK_FALSE;
|
|
|
|
colorBlending:=Default(TVkPipelineColorBlendStateCreateInfo);
|
|
colorBlending.sType :=VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
|
colorBlending.logicOpEnable :=VK_FALSE;
|
|
colorBlending.logicOp :=VK_LOGIC_OP_COPY;
|
|
colorBlending.attachmentCount :=0;
|
|
colorBlending.pAttachments :=@ColorBlends;
|
|
|
|
DepthStencil:=Default(TVkPipelineDepthStencilStateCreateInfo);
|
|
DepthStencil.sType :=VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
|
DepthStencil.depthTestEnable :=VK_FALSE;
|
|
DepthStencil.depthWriteEnable :=VK_FALSE;
|
|
DepthStencil.depthCompareOp :=VK_COMPARE_OP_LESS;
|
|
DepthStencil.depthBoundsTestEnable:=VK_FALSE;
|
|
DepthStencil.stencilTestEnable :=VK_FALSE;
|
|
//DepthStencil.front :TVkStencilOpState;
|
|
//DepthStencil.back :TVkStencilOpState;
|
|
DepthStencil.minDepthBounds :=0;
|
|
DepthStencil.maxDepthBounds :=0;
|
|
|
|
dynamicState:=Default(TVkPipelineDynamicStateCreateInfo);
|
|
dynamicState.sType :=VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
|
dynamicState.dynamicStateCount:=0{2};
|
|
dynamicState.pDynamicStates :=@dynamicStates;
|
|
|
|
dynamicStates[0]:=VK_DYNAMIC_STATE_VIEWPORT;
|
|
dynamicStates[1]:=VK_DYNAMIC_STATE_LINE_WIDTH;
|
|
|
|
end;
|
|
|
|
type
|
|
PVec4f=^TVec4f;
|
|
TVec4f=array[0..3] of Single;
|
|
|
|
procedure TvGraphicsPipeline.SetBlendColors(P:PSingle);
|
|
begin
|
|
if (P=nil) then Exit;
|
|
colorBlending.blendConstants:=PVec4f(P)^;
|
|
end;
|
|
|
|
procedure TvGraphicsPipeline.SetRenderPass(RenderPass:TvRenderPass);
|
|
begin
|
|
if (FRenderPass<>RenderPass) then
|
|
begin
|
|
FRenderPass:=RenderPass;
|
|
end;
|
|
end;
|
|
|
|
function TvGraphicsPipeline.Compile:Boolean;
|
|
type
|
|
AVkPipelineShaderStageCreateInfo=array[0..6] of TVkPipelineShaderStageCreateInfo;
|
|
var
|
|
r:TVkResult;
|
|
Stages:AVkPipelineShaderStageCreateInfo; // info.stageCount
|
|
info:TVkGraphicsPipelineCreateInfo;
|
|
begin
|
|
Result:=False;
|
|
|
|
if (FShaderGroup=nil) then Exit;
|
|
if (FRenderPass=nil) then Exit;
|
|
if (viewportState.viewportCount=0) then Exit;
|
|
if (viewportState.scissorCount=0) then Exit;
|
|
|
|
info:=Default(TVkGraphicsPipelineCreateInfo);
|
|
|
|
Stages:=Default(AVkPipelineShaderStageCreateInfo);
|
|
|
|
FShaderGroup.FKey.ExportStages(@Stages,@info.stageCount);
|
|
|
|
if (info.stageCount=0) then Exit;
|
|
|
|
if (not FShaderGroup.Compile) then Exit;
|
|
if (not FRenderPass.Compile) then Exit;
|
|
|
|
info.sType :=VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
|
info.pStages :=@Stages;
|
|
info.pVertexInputState :=@vertexInputInfo;
|
|
info.pInputAssemblyState:=@inputAssembly;
|
|
info.pViewportState :=@viewportState;
|
|
info.pRasterizationState:=@rasterizer;
|
|
info.pMultisampleState :=@multisampling;
|
|
info.pDepthStencilState :=@DepthStencil;
|
|
info.pColorBlendState :=@colorBlending;
|
|
info.pDynamicState :=@dynamicState;
|
|
info.layout :=FShaderGroup.FLayout.FHandle;
|
|
info.renderPass :=FRenderPass.FHandle;
|
|
info.subpass :=0;
|
|
info.basePipelineHandle :=VK_NULL_HANDLE;
|
|
info.basePipelineIndex :=-1;
|
|
|
|
r:=vkCreateGraphicsPipelines(Device.FHandle,VK_NULL_HANDLE,1,@info,nil,@FHandle);
|
|
if (r<>VK_SUCCESS) then
|
|
begin
|
|
Writeln(StdErr,'vkCreateGraphicsPipelines:',r);
|
|
exit;
|
|
end;
|
|
|
|
Result:=True;
|
|
end;
|
|
|
|
/////////
|
|
|
|
Procedure TvRenderTargets.AddClearColor(clr:TVkClearValue);
|
|
begin
|
|
if (FClearValuesCount>8) then Exit;
|
|
FClearValues[FClearValuesCount]:=clr;
|
|
Inc(FClearValuesCount);
|
|
end;
|
|
|
|
Function TvRenderTargets.GetInfo:TVkRenderPassBeginInfo;
|
|
begin
|
|
Result:=Default(TVkRenderPassBeginInfo);
|
|
Result.sType :=VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
|
Result.renderPass :=FRenderPass.FHandle;
|
|
Result.renderArea :=FRenderArea;
|
|
Result.clearValueCount:=FClearValuesCount;
|
|
Result.pClearValues :=FClearValues;
|
|
Result.framebuffer :=FFramebuffer.FHandle;
|
|
end;
|
|
|
|
class function TvRenderTargets.c(const a,b:TvRenderTargets):Integer;
|
|
begin
|
|
Result:=CompareByte(a,b,SizeOf(Pointer));
|
|
end;
|
|
|
|
Destructor TvRenderTargets.Destroy;
|
|
begin
|
|
FreeAndNil(FRenderPass);
|
|
FreeAndNil(FPipeline);
|
|
FreeAndNil(FFramebuffer);
|
|
inherited;
|
|
end;
|
|
|
|
Procedure TvRenderTargets.Acquire(Sender:TObject);
|
|
begin
|
|
System.InterlockedIncrement(Pointer(FRefs));
|
|
end;
|
|
|
|
Procedure TvRenderTargets.Release(Sender:TOBject);
|
|
begin
|
|
if System.InterlockedDecrement(Pointer(FRefs))=nil then
|
|
begin
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
Procedure TvComputePipeline2.Acquire(Sender:TObject);
|
|
begin
|
|
System.InterlockedIncrement(Pointer(FRefs));
|
|
end;
|
|
|
|
Procedure TvComputePipeline2.Release(Sender:TOBject);
|
|
begin
|
|
if System.InterlockedDecrement(Pointer(FRefs))=nil then
|
|
begin
|
|
Free;
|
|
end;
|
|
end;
|
|
|
|
//////////////
|
|
|
|
|
|
|
|
end.
|
|
|