diff --git a/chip/pm4_me.pas b/chip/pm4_me.pas index b0cfc38a..068940da 100644 --- a/chip/pm4_me.pas +++ b/chip/pm4_me.pas @@ -29,8 +29,7 @@ uses vShaderManager, vRegs2Vulkan, vCmdBuffer, - vPipeline, - vSetsPoolManager, + vDescriptorSet, vSampler, vSamplerManager, vMetaManager, @@ -133,6 +132,7 @@ type // function OnAlloc(size:Ptruint):Pointer; register; override; Procedure OnFree (P:Pointer ); register; override; + function IsLinearAlloc:Boolean; register; override; end; t_me_render_context=object @@ -471,6 +471,10 @@ begin // end; +function TvStreamCmdBuffer.IsLinearAlloc:Boolean; register; +begin + Result:=True; +end; // @@ -728,21 +732,15 @@ begin end; procedure Bind_Uniforms(var ctx:t_me_render_context; + BindPoint:TVkPipelineBindPoint; var UniformBuilder:TvUniformBuilder; - var DescriptorGroup:TvDescriptorGroup; ShaderGroup:TvShaderGroup); - procedure _init; inline; - begin - if (DescriptorGroup=nil) then - begin - DescriptorGroup:=FetchDescriptorGroup(ctx.Cmd,ShaderGroup.FLayout); - end; - end; - var i:Integer; + DescriptorGroup:TvDescriptorInterface; + ri:TvImage2; iv:TvImageView2; sm:TvSampler; @@ -755,6 +753,7 @@ var resource_instance:p_pm4_resource_instance; begin + DescriptorGroup:=ctx.Cmd.FetchDescriptorInterface(BindPoint); //images if (Length(UniformBuilder.FImages)<>0) then @@ -780,11 +779,9 @@ begin iv:=ri.FetchView(ctx.Cmd,FView,iu_sampled); - _init; - - DescriptorGroup.FSets[fset].BindImage(bind,0, - iv.FHandle, - VK_IMAGE_LAYOUT_GENERAL); + DescriptorGroup.BindImage(fset,bind, + iv.FHandle, + VK_IMAGE_LAYOUT_GENERAL); end; @@ -799,9 +796,7 @@ begin begin sm:=FetchSampler(ctx.Cmd,PS); - _init; - - DescriptorGroup.FSets[fset].BindSampler(bind,0,sm.FHandle); + DescriptorGroup.BindSampler(fset,bind,sm.FHandle); end; end; @@ -841,13 +836,10 @@ begin range:=size; - _init; - - DescriptorGroup.FSets[fset].BindBuffer(bind,0, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - buf.FHandle, - diff, - range {VK_WHOLE_SIZE}); + DescriptorGroup.BindBuffer(fset,bind, + buf.FHandle, + diff, + range {VK_WHOLE_SIZE}); if ((memuse and TM_WRITE)<>0) then begin @@ -1029,8 +1021,6 @@ var ri:TvImage2; iv:TvImageView2; - FDescriptorGroup:TvDescriptorGroup; - resource_instance:p_pm4_resource_instance; begin RP_KEY.Clear; @@ -1303,18 +1293,11 @@ begin ctx.Cmd.SetVertexInput (FAttrBuilder); ctx.Cmd.BindVertexBuffers(FAttrBuilder); - FDescriptorGroup:=nil; - Bind_Uniforms(ctx, + BP_GRAPHICS, FUniformBuilder, - FDescriptorGroup, ctx.rt_info^.ShaderGroup); - if (FDescriptorGroup<>nil) then - begin - ctx.Cmd.BindSets(BP_GRAPHICS,FDescriptorGroup); - end; - Bind_Pushs(ctx,ctx.rt_info^.ShaderGroup,@ctx.rt_info^.USERDATA); end; @@ -1639,7 +1622,6 @@ var FUniformBuilder:TvUniformBuilder; - FDescriptorGroup:TvDescriptorGroup; begin CP_KEY.FShaderGroup:=node^.ShaderGroup; CP:=FetchComputePipeline(ctx.Cmd,@CP_KEY); @@ -1672,18 +1654,11 @@ begin Assert(false ,'BindCompute(CP)'); end; - FDescriptorGroup:=nil; - Bind_Uniforms(ctx, + BP_COMPUTE, FUniformBuilder, - FDescriptorGroup, CP_KEY.FShaderGroup); - if (FDescriptorGroup<>nil) then - begin - ctx.Cmd.BindSets(BP_COMPUTE,FDescriptorGroup); - end; - Bind_Pushs(ctx,CP_KEY.FShaderGroup,dst); end; diff --git a/fpPS4.lpi b/fpPS4.lpi index 073fb789..0c8b64f0 100644 --- a/fpPS4.lpi +++ b/fpPS4.lpi @@ -1304,6 +1304,14 @@ + + + + + + + + diff --git a/vulkan/vCmdBuffer.pas b/vulkan/vCmdBuffer.pas index a65479b9..c45f3738 100644 --- a/vulkan/vCmdBuffer.pas +++ b/vulkan/vCmdBuffer.pas @@ -23,6 +23,8 @@ uses vImage, vPipeline, vPipelineManager, + vSetsPoolManager, + vDescriptorSet, vRender; type @@ -74,7 +76,11 @@ type submit_id:ptruint; FCurrPipeline:array[BP_GRAPHICS..BP_COMPUTE] of TVkPipeline; - FCurrLayout :array[BP_GRAPHICS..BP_COMPUTE] of TVkPipelineLayout; + FCurrLayout :array[BP_GRAPHICS..BP_COMPUTE] of TvPipelineLayout; + FCurrBinds :array[BP_GRAPHICS..BP_COMPUTE] of PvDescriptorCache; + FCurrGroup :array[BP_GRAPHICS..BP_COMPUTE] of TvDescriptorGroup; + + FDescriptorCacheSet:TvDescriptorCacheSet; FRenderPass:TVkRenderPass; @@ -112,6 +118,8 @@ type Procedure ReleaseAllPlannedTriggers; Procedure AddPlannedTrigger(start,__end:QWORD;exclude:Pointer); + Procedure FreeAllDescriptorCache; + Procedure BindLayout(BindPoint:TVkPipelineBindPoint;F:TvPipelineLayout); Procedure BindSet(BindPoint:TVkPipelineBindPoint;fset:TVkUInt32;FHandle:TVkDescriptorSet); Procedure PushConstant(BindPoint:TVkPipelineBindPoint;stageFlags:TVkShaderStageFlags;offset,size:TVkUInt32;const pValues:PVkVoid); @@ -167,6 +175,13 @@ type Procedure InsertLabel(pLabelName:PVkChar); Procedure BeginLabel(pLabelName:PVkChar); Procedure EndLabel(); + + function FetchDescriptorCache(layout:TvPipelineLayout):PvDescriptorCache; + function FetchDescriptorCache(BindPoint:TVkPipelineBindPoint):PvDescriptorCache; + function FetchDescriptorInterface(BindPoint:TVkPipelineBindPoint):TvDescriptorInterface; + Procedure ApplyDescriptorCache(BindPoint:TVkPipelineBindPoint); + + Procedure BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup); end; TvCmdBuffer=class(TvCustomCmdBuffer) @@ -181,8 +196,6 @@ type function BindCompute(CP:TvComputePipeline2):Boolean; - Procedure BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup); - Procedure dmaData1(src,dst:Pointer;byteCount:DWORD;isBlocking:Boolean); Procedure dmaData2(src:DWORD;dst:Pointer;byteCount:DWORD;isBlocking:Boolean); Procedure WriteEos(eventType:Byte;dst:Pointer;value:DWORD;isBlocking:Boolean); @@ -325,8 +338,14 @@ begin EndRenderPass; - FCurrLayout[BP_GRAPHICS]:=VK_NULL_HANDLE; - FCurrLayout[BP_COMPUTE ]:=VK_NULL_HANDLE; + FCurrLayout[BP_GRAPHICS]:=nil; + FCurrLayout[BP_COMPUTE ]:=nil; + + FCurrBinds[BP_GRAPHICS]:=nil; + FCurrBinds[BP_COMPUTE ]:=nil; + + FCurrGroup[BP_GRAPHICS]:=nil; + FCurrGroup[BP_COMPUTE ]:=nil; FCurrPipeline[BP_GRAPHICS]:=VK_NULL_HANDLE; FCurrPipeline[BP_COMPUTE ]:=VK_NULL_HANDLE; @@ -443,7 +462,9 @@ begin vkCmdEndRenderPass(FCmdbuf); FRenderPass:=VK_NULL_HANDLE; // - FCurrLayout[BP_GRAPHICS]:=VK_NULL_HANDLE; + FCurrLayout[BP_GRAPHICS]:=nil; + FCurrBinds [BP_GRAPHICS]:=nil; + FCurrGroup [BP_GRAPHICS]:=nil; // FCurrPipeline[BP_GRAPHICS]:=VK_NULL_HANDLE; end; @@ -637,6 +658,8 @@ begin ReleaseAllPlannedTriggers; + FreeAllDescriptorCache; + FreeAllSemaphores; cmd_count:=0; @@ -647,14 +670,20 @@ Procedure TvCustomCmdBuffer.FreeAllSemaphores; var node:PvSemaphoreWait; begin - node:=FWaitSemaphores.Min; - - while (node<>nil) do + if IsLinearAlloc then + begin + FWaitSemaphores:=Default(TvSemaphoreWaitSet); + end else begin - FWaitSemaphores.delete(node); - OnFree(node); - node:=FWaitSemaphores.Min; + + while (node<>nil) do + begin + FWaitSemaphores.delete(node); + OnFree(node); + + node:=FWaitSemaphores.Min; + end; end; FWaitSemaphoresCount:=0; @@ -698,12 +727,23 @@ begin //deffered trigger vm_map_track_trigger(p_proc.p_vmspace,node^.start,node^.__end,node^.exclude,M_GPU_APPLY); - FPlannedTriggers.delete(node); - OnFree(node); + if IsLinearAlloc then + begin + node:=FPlannedTriggers.Next(node); + end else + begin + FPlannedTriggers.delete(node); + OnFree(node); + // + node:=FPlannedTriggers.Min; + end; - node:=FPlannedTriggers.Min; end; + if IsLinearAlloc then + begin + FPlannedTriggers:=Default(t_cmd_track_deferred_set); + end; end; Procedure TvCustomCmdBuffer.AddPlannedTrigger(start,__end:QWORD;exclude:Pointer); @@ -731,6 +771,27 @@ begin end; +Procedure TvCustomCmdBuffer.FreeAllDescriptorCache; +var + node:PvDescriptorCache; +begin + if IsLinearAlloc then + begin + FDescriptorCacheSet:=Default(TvDescriptorCacheSet); + end else + begin + node:=FDescriptorCacheSet.Min; + + while (node<>nil) do + begin + FDescriptorCacheSet.delete(node); + OnFree(node); + + node:=FDescriptorCacheSet.Min; + end; + end; +end; + Procedure TvCustomCmdBuffer.BindLayout(BindPoint:TVkPipelineBindPoint;F:TvPipelineLayout); begin @@ -741,7 +802,13 @@ begin end; if (F=nil) then Exit; - FCurrLayout[BindPoint]:=F.FHandle; + + if (FCurrLayout[BindPoint]<>F) then + begin + FCurrLayout[BindPoint]:=F; + FCurrBinds [BindPoint]:=nil; + FCurrGroup [BindPoint]:=nil; + end; end; Procedure TvCustomCmdBuffer.BindSet(BindPoint:TVkPipelineBindPoint;fset:TVkUInt32;FHandle:TVkDescriptorSet); @@ -754,7 +821,7 @@ begin end; if (FHandle=VK_NULL_HANDLE) then Exit; - if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit; + if (FCurrLayout[BindPoint]=nil) then Exit; if (not BeginCmdBuffer) then Exit; @@ -762,7 +829,7 @@ begin vkCmdBindDescriptorSets(FCmdbuf, BindPoint, - FCurrLayout[BindPoint], + FCurrLayout[BindPoint].FHandle, fset,1, @FHandle, 0,nil); @@ -779,14 +846,14 @@ begin end; if (pValues=nil) or (size=0) then Exit; - if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit; + if (FCurrLayout[BindPoint]=nil) then Exit; if (not BeginCmdBuffer) then Exit; Inc(cmd_count); vkCmdPushConstants(FCmdbuf, - FCurrLayout[BindPoint], + FCurrLayout[BindPoint].FHandle, stageFlags, offset,size, pValues); @@ -806,6 +873,8 @@ begin if (not BeginCmdBuffer) then Exit; + ApplyDescriptorCache(BP_COMPUTE); + Inc(cmd_count); vkCmdDispatch(FCmdbuf,X,Y,Z); @@ -1074,72 +1143,6 @@ begin dstStageMask); end; -Procedure TvCmdBuffer.BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup); -var - A:array[0..6] of TVkDescriptorSet; - i,start,pos:Integer; - - procedure Flush; inline; - begin - Inc(cmd_count); - - vkCmdBindDescriptorSets(FCmdbuf, - BindPoint, - FCurrLayout[BindPoint], - start,pos, - @A[0], - 0,nil); - - pos:=0; - end; - -begin - - if (Self=nil) then - begin - Writeln(stderr,'Self=nil,',{$I %LINE%}); - Exit; - end; - - if (F=nil) then Exit; - if (FCurrLayout[BindPoint]=VK_NULL_HANDLE) then Exit; - if (Length(F.FSets)=0) then Exit; - - if (not BeginCmdBuffer) then Exit; - - pos:=0; - - For i:=0 to High(F.FSets) do - begin - if F.FSets[i].IsValid then - begin - - if (pos=0) then - begin - start:=i; - end; - - A[pos]:=F.FSets[i].FHandle; - Inc(pos); - - if (pos=7) then - begin - Flush; - end; - - end else - if (pos<>0) then - begin - Flush; - end; - end; - - if (pos<>0) then - begin - Flush; - end; -end; - Const VK_ACCESS_ANY= ord(VK_ACCESS_INDIRECT_COMMAND_READ_BIT ) or @@ -1486,6 +1489,8 @@ begin if (not BeginCmdBuffer) then Exit; + ApplyDescriptorCache(BP_GRAPHICS); + if (FinstanceCount=0) then FinstanceCount:=1; Size:=(indexOffset+indexCount)*GET_INDEX_TYPE_SIZE(FINDEX_TYPE); @@ -1560,6 +1565,8 @@ begin if (not BeginCmdBuffer) then Exit; + ApplyDescriptorCache(BP_GRAPHICS); + if (FinstanceCount=0) then FinstanceCount:=1; Case Femulate_primtype of @@ -1626,6 +1633,155 @@ begin end; +// + +function TvCustomCmdBuffer.FetchDescriptorCache(layout:TvPipelineLayout):PvDescriptorCache; +begin + Result:=FDescriptorCacheSet.Find(@layout); + + if (Result=nil) then + begin + Result:=AllocDescriptorCache(Self,layout); + FDescriptorCacheSet.Insert(Result); + end; +end; + +function TvCustomCmdBuffer.FetchDescriptorCache(BindPoint:TVkPipelineBindPoint):PvDescriptorCache; +begin + Result:=nil; + + if (FCurrLayout[BindPoint]=nil) then Exit; + + Result:=FCurrBinds[BindPoint]; + + if (Result=nil) then + begin + Result:=FetchDescriptorCache(FCurrLayout[BindPoint]); + // + FCurrBinds[BindPoint]:=Result; + // + Result^.SetAllChange; + end; +end; + +function TvCustomCmdBuffer.FetchDescriptorInterface(BindPoint:TVkPipelineBindPoint):TvDescriptorInterface; +begin + Result:=Default(TvDescriptorInterface); + + if (Self=nil) then + begin + Writeln(stderr,'Self=nil,',{$I %LINE%}); + Exit; + end; + + Result:=TvDescriptorInterface(FetchDescriptorCache(BindPoint)); +end; + +Procedure TvCustomCmdBuffer.ApplyDescriptorCache(BindPoint:TVkPipelineBindPoint); +var + Cache:PvDescriptorCache; + Group:TvDescriptorGroup; +begin + if (FCurrLayout[BindPoint]=nil) then Exit; + + Cache:=FCurrBinds[BindPoint]; + if (Cache=nil) then Exit; + + if (Cache^.p_count_all=0) then Exit; //no sets + + Group:=FCurrGroup[BindPoint]; + + if (Cache^.p_change_any) or + (Group=nil) then + begin + Group:=FetchDescriptorGroup(Self,FCurrLayout[BindPoint]); + // + FCurrGroup[BindPoint]:=Group; + // + Group.Bind(Cache); + // + BindSets(BindPoint,Group); + // + Cache^.ClearAllChange; + end; + + //VK_KHR_push_descriptor vkCmdPushDescriptorSetKHR TODO +end; + +Procedure TvCustomCmdBuffer.BindSets(BindPoint:TVkPipelineBindPoint;F:TvDescriptorGroup); +var + A:array[0..6] of TVkDescriptorSet; + i,start,pos:Integer; + + procedure Flush; inline; + begin + Inc(cmd_count); + + vkCmdBindDescriptorSets(FCmdbuf, + BindPoint, + FCurrLayout[BindPoint].FHandle, + start,pos, + @A[0], + 0,nil); + + pos:=0; + end; + +begin + + if (Self=nil) then + begin + Writeln(stderr,'Self=nil,',{$I %LINE%}); + Exit; + end; + + if (F=nil) then Exit; + if (FCurrLayout[BindPoint]=nil) then Exit; + if (Length(F.FSets)=0) then Exit; + + if (not BeginCmdBuffer) then Exit; + + pos:=0; + + For i:=0 to High(F.FSets) do + begin + if F.FSets[i].IsValid then + begin + + if (pos=0) then + begin + start:=i; + end; + + A[pos]:=F.FSets[i].FHandle; + Inc(pos); + + if (pos=7) then + begin + Flush; + end; + + end else + if (pos<>0) then + begin + Flush; + end; + end; + + if (pos<>0) then + begin + Flush; + end; +end; + +// + + + + end. + + + diff --git a/vulkan/vDependence.pas b/vulkan/vDependence.pas index 2b82498d..4bd1ddb1 100644 --- a/vulkan/vDependence.pas +++ b/vulkan/vDependence.pas @@ -44,6 +44,7 @@ type // function OnAlloc(size:Ptruint):Pointer; virtual; Procedure OnFree (P:Pointer ); virtual; + function IsLinearAlloc:Boolean; virtual; Procedure RefTo(obj:TvRefsObject); function AddDependence(cb:TvReleaseCb):Boolean; function DelDependence(cb:TvReleaseCb):Boolean; @@ -132,6 +133,11 @@ begin FreeMem(P); end; +function TvDependenciesObject.IsLinearAlloc:Boolean; +begin + Result:=False; +end; + Procedure TvDependenciesObject.RefTo(obj:TvRefsObject); begin if (Self=nil) or (obj=nil) then Exit; diff --git a/vulkan/vDescriptorSet.pas b/vulkan/vDescriptorSet.pas new file mode 100644 index 00000000..38e3ea48 --- /dev/null +++ b/vulkan/vDescriptorSet.pas @@ -0,0 +1,488 @@ +unit vDescriptorSet; + +{$mode ObjFPC}{$H+} + +interface + +uses + g_node_splay, + Vulkan, + vDevice, + vPipeline, + vDependence; + +type + PvDescriptorCache=^TvDescriptorCache; + TvDescriptorCache=packed object + // + layout:TvPipelineLayout; //Must be the first element in memory + // + p_write:PVkWriteDescriptorSet; + // + p_count_all:Byte; + // set bind + p_count:array[0..6] of Byte; + p_binds:array[0..6] of PVkWriteDescriptorSet; + // + p_change_any:Boolean; + p_change:array[0..6] of Boolean; + // + pLeft :PvDescriptorCache; + pRight:PvDescriptorCache; + // + function c(a,b:PvDescriptorCache):Integer; static; + procedure ClearAllChange; + procedure SetAllChange; + procedure BindBuffer (aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize); + procedure BindImage (aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;img:TVkImageView;aLayout:TVkImageLayout); + procedure BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler); + end; + + TvDescriptorCacheSet=specialize TNodeSplay; + + TvDescriptorInterface=object + FHandle:PvDescriptorCache; + Procedure BindBuffer (aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); + Procedure BindUniform(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); + Procedure BindStorage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); + Procedure BindImage (aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); + Procedure BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler); + end; + + TvDescriptorSet2=object + FHandle:TVkDescriptorSet; + Function IsValid:Boolean; + Procedure FillHandle (dwrite:PVkWriteDescriptorSet;count:Integer); + Procedure BindBuffer (aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); + Procedure BindUniform(aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); + Procedure BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); + Procedure BindImage (aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); + Procedure BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler); + end; + + AvDescriptorSet2=Array of TvDescriptorSet2; + + TvDescriptorGroup=class(TvRefsObject) + FLayout:TvPipelineLayout; + FSets :AvDescriptorSet2; + Procedure Bind(Cache:PvDescriptorCache); + end; + +function AllocDescriptorCache(obj:TvDependenciesObject;layout:TvPipelineLayout):PvDescriptorCache; + +implementation + +Procedure TvDescriptorGroup.Bind(Cache:PvDescriptorCache); +var + i:Integer; +begin + if (Cache=nil) then Exit; + + Assert(FLayout=Cache^.layout,'bind on wrong layout'); + + if (Length(FSets)<>0) then + For i:=0 to High(FSets) do + begin + FSets[i].FillHandle(Cache^.p_binds[i],Cache^.p_count[i]); + end; + + if (Cache^.p_count_all<>0) then + begin + vkUpdateDescriptorSets(Device.FHandle,Cache^.p_count_all,Cache^.p_write,0,nil); + end; +end; + +// + +Function TvDescriptorSet2.IsValid:Boolean; +begin + Result:=FHandle<>VK_NULL_HANDLE; +end; + +Procedure TvDescriptorSet2.FillHandle(dwrite:PVkWriteDescriptorSet;count:Integer); +var + i:Integer; +begin + if (dwrite=nil) or (count=0) then Exit; + + For i:=0 to count-1 do + begin + dwrite[i].dstSet:=FHandle; + end; +end; + +Procedure TvDescriptorSet2.BindBuffer(aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); +var + dwrite:TVkWriteDescriptorSet; + buf:TVkDescriptorBufferInfo; +begin + buf:=Default(TVkDescriptorBufferInfo); + buf.buffer:=buffer; + buf.offset:=offset; + buf.range :=range ; + + dwrite:=Default(TVkWriteDescriptorSet); + dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + dwrite.dstSet :=FHandle; + dwrite.dstBinding :=aBind; + dwrite.dstArrayElement:=aElem; + dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + dwrite.descriptorCount:=1; + dwrite.pBufferInfo :=@buf; + + vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); +end; + +Procedure TvDescriptorSet2.BindUniform(aBind,aElem:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); +var + dwrite:TVkWriteDescriptorSet; + buf:TVkDescriptorBufferInfo; +begin + buf:=Default(TVkDescriptorBufferInfo); + buf.buffer:=buffer; + buf.offset:=offset; + buf.range :=range ; + + dwrite:=Default(TVkWriteDescriptorSet); + dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + dwrite.dstSet :=FHandle; + dwrite.dstBinding :=aBind; + dwrite.dstArrayElement:=aElem; + dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + dwrite.descriptorCount:=1; + dwrite.pBufferInfo :=@buf; + + vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); +end; + +Procedure TvDescriptorSet2.BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); +var + dwrite:TVkWriteDescriptorSet; + dimg:TVkDescriptorImageInfo; +begin + dimg:=Default(TVkDescriptorImageInfo); + dimg.imageView :=img; + dimg.imageLayout:=Layout; + + dwrite:=Default(TVkWriteDescriptorSet); + dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + dwrite.dstSet :=FHandle; + dwrite.dstBinding :=aBind; + dwrite.dstArrayElement:=aElem; + dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + dwrite.descriptorCount:=1; + dwrite.pImageInfo :=@dimg; + vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); +end; + +Procedure TvDescriptorSet2.BindImage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); +var + dwrite:TVkWriteDescriptorSet; + dimg:TVkDescriptorImageInfo; +begin + dimg:=Default(TVkDescriptorImageInfo); + dimg.imageView :=img; + dimg.imageLayout:=Layout; + + dwrite:=Default(TVkWriteDescriptorSet); + dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + dwrite.dstSet :=FHandle; + dwrite.dstBinding :=aBind; + dwrite.dstArrayElement:=aElem; + dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + dwrite.descriptorCount:=1; + dwrite.pImageInfo :=@dimg; + vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); +end; + +Procedure TvDescriptorSet2.BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler); +var + dwrite:TVkWriteDescriptorSet; + dimg:TVkDescriptorImageInfo; +begin + dimg:=Default(TVkDescriptorImageInfo); + dimg.sampler:=smp; + + dwrite:=Default(TVkWriteDescriptorSet); + dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + dwrite.dstSet :=FHandle; + dwrite.dstBinding :=aBind; + dwrite.dstArrayElement:=aElem; + dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLER; + dwrite.descriptorCount:=1; + dwrite.pImageInfo :=@dimg; + vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); +end; + +// + +Procedure TvDescriptorInterface.BindBuffer(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); +begin + if (FHandle=nil) then Exit; + + FHandle^.BindBuffer(aSet,aBind,VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,buffer,offset,range); +end; + +Procedure TvDescriptorInterface.BindUniform(aSet,aBind:TVkUInt32;buffer:TVkBuffer;offset,range:TVkDeviceSize); +begin + if (FHandle=nil) then Exit; + + FHandle^.BindBuffer(aSet,aBind,VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,buffer,offset,range); +end; + + +Procedure TvDescriptorInterface.BindStorage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); +begin + if (FHandle=nil) then Exit; + + FHandle^.BindImage(aSet,aBind,VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,img,Layout); +end; + +Procedure TvDescriptorInterface.BindImage(aSet,aBind:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); +begin + if (FHandle=nil) then Exit; + + FHandle^.BindImage(aSet,aBind,VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,img,Layout); +end; + +Procedure TvDescriptorInterface.BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler); +begin + if (FHandle=nil) then Exit; + + FHandle^.BindSampler(aSet,aBind,smp); +end; + + +// + +function AllocDescriptorCache(obj:TvDependenciesObject;layout:TvPipelineLayout):PvDescriptorCache; +var + i,b :Integer; + dwrite_count:Integer; + dimg_count :Integer; + dbuf_count :Integer; + size :Integer; + base :Pointer; + ends :Pointer; + + p_write_base:PVkWriteDescriptorSet; + p_write_ends:PVkWriteDescriptorSet; + + function AllocBase(size:Integer):Pointer; inline; + begin + Assert((base+size)<=ends,'AllocBase'); + Result:=base; + base:=base+size; + end; + + function AllocWrite(count:Integer):PVkWriteDescriptorSet; inline; + begin + Assert((p_write_base+count)<=p_write_ends,'AllocWrite'); + Result:=p_write_base; + p_write_base:=p_write_base+count; + end; + +begin + Assert(layout<>nil,'layout not binded'); + + Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER )]=0,'TODO'); + Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER )]=0,'TODO'); + Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)]=0,'TODO'); + Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)]=0,'TODO'); + Assert(layout.FCounts[ord(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT )]=0,'TODO'); + + dwrite_count:=layout.FBinds; + Assert(dwrite_count<=255,'dwrite_count limit'); + + dimg_count:= + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_SAMPLER)]+ + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)]+ + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)]+ + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)]; + + dbuf_count:= + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)]+ + layout.FCounts[ord(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)]; + + size:=SizeOf(TvDescriptorCache)+ + dwrite_count*SizeOf(TVkWriteDescriptorSet)+ + dimg_count *SizeOf(TVkDescriptorImageInfo)+ + dbuf_count *SizeOf(TVkDescriptorBufferInfo); + + base:=obj.OnAlloc(size); + ends:=base+size; + + Result:=AllocBase(SizeOf(TvDescriptorCache)); + + Result^.layout:=layout; + + p_write_base:=AllocBase(dwrite_count*SizeOf(TVkWriteDescriptorSet)); + p_write_ends:=base; + + Result^.p_write:=p_write_base; + Result^.p_count_all:=dwrite_count; + + if Length(layout.key.FLayouts)<>0 then + begin + For i:=0 to High(layout.key.FLayouts) do + With layout.key.FLayouts[i] do + if (Length(key.FBinds)<>0) then + begin + + Result^.p_count[i]:=Length(key.FBinds); + Result^.p_binds[i]:=AllocWrite(Length(key.FBinds)); + + For b:=0 to High(key.FBinds) do + with key.FBinds[b] do + begin + + Result^.p_binds[i][b].sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + Result^.p_binds[i][b].dstBinding :=b; + Result^.p_binds[i][b].descriptorCount:=1; + Result^.p_binds[i][b].descriptorType :=descriptorType; + + case descriptorType of + VK_DESCRIPTOR_TYPE_SAMPLER, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + begin + Result^.p_binds[i][b].pImageInfo:=AllocBase(SizeOf(TVkDescriptorImageInfo)); + end; + + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + begin + Result^.p_binds[i][b].pBufferInfo:=AllocBase(SizeOf(TVkDescriptorBufferInfo)); + end; + + else; + end; + + end; + end; + end; + +end; + +/// + +function TvDescriptorCache.c(a,b:PvDescriptorCache):Integer; +begin + Result:=Integer(Pointer(a^.layout)>Pointer(b^.layout))-Integer(Pointer(a^.layout)nil); + + dwrite:=@p_binds[aSet][aBind]; + + Assert(dwrite^.descriptorType=dtype); + + dbuf:=dwrite^.pBufferInfo; + + Assert(dbuf<>nil); + + change:=False; + + change:=change or (dbuf^.buffer<>buffer); + change:=change or (dbuf^.offset<>offset); + change:=change or (dbuf^.range <>range ); + + dbuf^.buffer:=buffer; + dbuf^.offset:=offset; + dbuf^.range :=range ; + + if change then + begin + p_change_any:=True; + p_change[aSet]:=True; + end; +end; + +procedure TvDescriptorCache.BindImage(aSet,aBind:TVkUInt32;dtype:TVkDescriptorType;img:TVkImageView;aLayout:TVkImageLayout); +var + dwrite:PVkWriteDescriptorSet; + dimg :PVkDescriptorImageInfo; + change:Boolean; +begin + Assert(aSet<7); + Assert(aBindnil); + + dwrite:=@p_binds[aSet][aBind]; + + Assert(dwrite^.descriptorType=dtype); + + dimg:=dwrite^.pImageInfo; + + Assert(dimg<>nil); + + change:=False; + + change:=change or (dimg^.imageView <>img ); + change:=change or (dimg^.imageLayout<>aLayout); + + dimg^.imageView :=img; + dimg^.imageLayout:=aLayout; + + if change then + begin + p_change_any:=True; + p_change[aSet]:=True; + end; +end; + +procedure TvDescriptorCache.BindSampler(aSet,aBind:TVkUInt32;smp:TVkSampler); +var + dwrite:PVkWriteDescriptorSet; + dimg :PVkDescriptorImageInfo; + change:Boolean; +begin + Assert(aSet<7); + Assert(aBindnil); + + dwrite:=@p_binds[aSet][aBind]; + + Assert(dwrite^.descriptorType=VK_DESCRIPTOR_TYPE_SAMPLER); + + dimg:=dwrite^.pImageInfo; + + Assert(dimg<>nil); + + change:=False; + + change:=change or (dimg^.sampler<>smp); + + dimg^.sampler:=smp; + + if change then + begin + p_change_any:=True; + p_change[aSet]:=True; + end; +end; + + +end. + diff --git a/vulkan/vImage.pas b/vulkan/vImage.pas index b74c61da..4ea451be 100644 --- a/vulkan/vImage.pas +++ b/vulkan/vImage.pas @@ -64,6 +64,7 @@ type TvCustomImage=class(TvRefsObject) FHandle:TVkImage; + FFormat:TVkFormat; //real used format FBind :TvPointer; procedure FreeHandle; virtual; Destructor Destroy; override; @@ -148,7 +149,6 @@ type end; TvImage=class(TvCustomImage) - FFormat:TVkFormat; FExtent:TVkExtent3D; FUsage :TVkFlags; Fflags :TVkImageCreateFlags; @@ -281,82 +281,125 @@ Function getFormatSize(cformat:TVkFormat):Byte; //in bytes begin Result:=0; Case cformat of + VK_FORMAT_UNDEFINED :Result:=0; + //pixel size - VK_FORMAT_R8_UNORM :Result:=1; - VK_FORMAT_R8_SNORM :Result:=1; - VK_FORMAT_R8_UINT :Result:=1; - VK_FORMAT_R8_SINT :Result:=1; - VK_FORMAT_R8_SRGB :Result:=1; + VK_FORMAT_R8_UNORM , + VK_FORMAT_R8_SNORM , + VK_FORMAT_R8_USCALED , + VK_FORMAT_R8_SSCALED , + VK_FORMAT_R8_UINT , + VK_FORMAT_R8_SINT , + VK_FORMAT_R8_SRGB :Result:=1; - VK_FORMAT_R8G8_UNORM :Result:=2; - VK_FORMAT_R8G8_SNORM :Result:=2; - VK_FORMAT_R8G8_UINT :Result:=2; - VK_FORMAT_R8G8_SINT :Result:=2; + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT , + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT , + VK_FORMAT_R4G4B4A4_UNORM_PACK16 , + VK_FORMAT_B4G4R4A4_UNORM_PACK16 , + VK_FORMAT_R5G6B5_UNORM_PACK16 , + VK_FORMAT_B5G6R5_UNORM_PACK16 , - VK_FORMAT_R8G8B8A8_UNORM :Result:=4; - VK_FORMAT_R8G8B8A8_SRGB :Result:=4; - VK_FORMAT_R8G8B8A8_SNORM :Result:=4; - VK_FORMAT_R8G8B8A8_UINT :Result:=4; - VK_FORMAT_R8G8B8A8_SINT :Result:=4; + VK_FORMAT_R8G8_UNORM , + VK_FORMAT_R8G8_SNORM , + VK_FORMAT_R8G8_USCALED , + VK_FORMAT_R8G8_SSCALED , + VK_FORMAT_R8G8_UINT , + VK_FORMAT_R8G8_SINT , + VK_FORMAT_R8G8_SRGB , - VK_FORMAT_B8G8R8A8_UNORM :Result:=4; - VK_FORMAT_B8G8R8A8_SRGB :Result:=4; - VK_FORMAT_B8G8R8A8_SNORM :Result:=4; - VK_FORMAT_B8G8R8A8_UINT :Result:=4; - VK_FORMAT_B8G8R8A8_SINT :Result:=4; + VK_FORMAT_R16_UNORM , + VK_FORMAT_R16_SNORM , + VK_FORMAT_R16_USCALED , + VK_FORMAT_R16_SSCALED , + VK_FORMAT_R16_UINT , + VK_FORMAT_R16_SINT , + VK_FORMAT_R16_SFLOAT :Result:=2; - VK_FORMAT_R16_UNORM :Result:=2; - VK_FORMAT_R16_SNORM :Result:=2; - VK_FORMAT_R16_UINT :Result:=2; - VK_FORMAT_R16_SINT :Result:=2; - VK_FORMAT_R16_SFLOAT :Result:=2; + VK_FORMAT_R8G8B8A8_UNORM , + VK_FORMAT_R8G8B8A8_SNORM , + VK_FORMAT_R8G8B8A8_USCALED , + VK_FORMAT_R8G8B8A8_SSCALED , + VK_FORMAT_R8G8B8A8_UINT , + VK_FORMAT_R8G8B8A8_SINT , + VK_FORMAT_R8G8B8A8_SRGB , - VK_FORMAT_R16G16_UNORM :Result:=4; - VK_FORMAT_R16G16_SNORM :Result:=4; - VK_FORMAT_R16G16_UINT :Result:=4; - VK_FORMAT_R16G16_SINT :Result:=4; - VK_FORMAT_R16G16_SFLOAT :Result:=4; + VK_FORMAT_B8G8R8A8_UNORM , + VK_FORMAT_B8G8R8A8_SNORM , + VK_FORMAT_B8G8R8A8_USCALED , + VK_FORMAT_B8G8R8A8_SSCALED , + VK_FORMAT_B8G8R8A8_UINT , + VK_FORMAT_B8G8R8A8_SINT , + VK_FORMAT_B8G8R8A8_SRGB , - VK_FORMAT_R16G16B16A16_UNORM :Result:=8; - VK_FORMAT_R16G16B16A16_SNORM :Result:=8; - VK_FORMAT_R16G16B16A16_UINT :Result:=8; - VK_FORMAT_R16G16B16A16_SINT :Result:=8; - VK_FORMAT_R16G16B16A16_SFLOAT :Result:=8; + VK_FORMAT_A8B8G8R8_UNORM_PACK32 , + VK_FORMAT_A8B8G8R8_SNORM_PACK32 , + VK_FORMAT_A8B8G8R8_USCALED_PACK32 , + VK_FORMAT_A8B8G8R8_SSCALED_PACK32 , + VK_FORMAT_A8B8G8R8_UINT_PACK32 , + VK_FORMAT_A8B8G8R8_SINT_PACK32 , + VK_FORMAT_A8B8G8R8_SRGB_PACK32 , - VK_FORMAT_R32_UINT :Result:=4; - VK_FORMAT_R32_SINT :Result:=4; - VK_FORMAT_R32_SFLOAT :Result:=4; + VK_FORMAT_A2R10G10B10_UNORM_PACK32 , + VK_FORMAT_A2R10G10B10_SNORM_PACK32 , + VK_FORMAT_A2R10G10B10_USCALED_PACK32, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32, + VK_FORMAT_A2R10G10B10_UINT_PACK32 , + VK_FORMAT_A2R10G10B10_SINT_PACK32 , + VK_FORMAT_A2B10G10R10_UNORM_PACK32 , + VK_FORMAT_A2B10G10R10_SNORM_PACK32 , + VK_FORMAT_A2B10G10R10_USCALED_PACK32, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32 , + VK_FORMAT_A2B10G10R10_SINT_PACK32 , - VK_FORMAT_R32G32_UINT :Result:=8; - VK_FORMAT_R32G32_SINT :Result:=8; - VK_FORMAT_R32G32_SFLOAT :Result:=8; + VK_FORMAT_R16G16_UNORM , + VK_FORMAT_R16G16_SNORM , + VK_FORMAT_R16G16_USCALED , + VK_FORMAT_R16G16_SSCALED , + VK_FORMAT_R16G16_UINT , + VK_FORMAT_R16G16_SINT , + VK_FORMAT_R16G16_SFLOAT , - VK_FORMAT_R32G32B32A32_UINT :Result:=16; - VK_FORMAT_R32G32B32A32_SINT :Result:=16; - VK_FORMAT_R32G32B32A32_SFLOAT :Result:=16; + VK_FORMAT_R32_UINT , + VK_FORMAT_R32_SINT , + VK_FORMAT_R32_SFLOAT , - VK_FORMAT_R5G6B5_UNORM_PACK16 :Result:=2; - VK_FORMAT_R4G4B4A4_UNORM_PACK16:Result:=2; + VK_FORMAT_B10G11R11_UFLOAT_PACK32 , + VK_FORMAT_R10G11B11_UFLOAT_FAKE32 , - VK_FORMAT_A2R10G10B10_UNORM_PACK32:Result:=4; - VK_FORMAT_A2B10G10R10_UNORM_PACK32:Result:=4; + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=4; - VK_FORMAT_B10G11R11_UFLOAT_PACK32 :Result:=4; - VK_FORMAT_R10G11B11_UFLOAT_FAKE32 :Result:=4; + VK_FORMAT_R16G16B16A16_UNORM , + VK_FORMAT_R16G16B16A16_SNORM , + VK_FORMAT_R16G16B16A16_USCALED , + VK_FORMAT_R16G16B16A16_SSCALED , + VK_FORMAT_R16G16B16A16_UINT , + VK_FORMAT_R16G16B16A16_SINT , + VK_FORMAT_R16G16B16A16_SFLOAT , - VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=4; + VK_FORMAT_R32G32_UINT , + VK_FORMAT_R32G32_SINT , + VK_FORMAT_R32G32_SFLOAT :Result:=8; + + VK_FORMAT_R32G32B32_UINT , + VK_FORMAT_R32G32B32_SINT , + VK_FORMAT_R32G32B32_SFLOAT :Result:=12; + + VK_FORMAT_R32G32B32A32_UINT , + VK_FORMAT_R32G32B32A32_SINT , + VK_FORMAT_R32G32B32A32_SFLOAT :Result:=16; //stencil - VK_FORMAT_S8_UINT :Result:=1; + VK_FORMAT_S8_UINT :Result:=1; //depth - VK_FORMAT_D16_UNORM :Result:=2; - VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4; - VK_FORMAT_D32_SFLOAT :Result:=4; + VK_FORMAT_D16_UNORM :Result:=2; + VK_FORMAT_X8_D24_UNORM_PACK32 :Result:=4; + VK_FORMAT_D32_SFLOAT :Result:=4; //depth stencil - VK_FORMAT_D16_UNORM_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D16_UNORM_S8_UINT'); - VK_FORMAT_D24_UNORM_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D24_UNORM_S8_UINT'); - VK_FORMAT_D32_SFLOAT_S8_UINT :Assert(false,'getFormatSize:VK_FORMAT_D32_SFLOAT_S8_UINT'); + VK_FORMAT_D16_UNORM_S8_UINT :Result:=3; + VK_FORMAT_D24_UNORM_S8_UINT :Result:=4; + VK_FORMAT_D32_SFLOAT_S8_UINT :Result:=5; //texel size VK_FORMAT_BC1_RGB_UNORM_BLOCK.. @@ -578,6 +621,11 @@ const VK_FORMAT_UNDEFINED ); + MUTABLE_5999:array[0..1] of TVkFormat=( + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, + VK_FORMAT_UNDEFINED + ); + MUTABLE_3232:array[0..10] of TVkFormat=( VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_SNORM, @@ -781,6 +829,8 @@ begin VK_FORMAT_B10G11R11_UFLOAT_PACK32 :Result:=@MUTABLE_8888; VK_FORMAT_R10G11B11_UFLOAT_FAKE32 :Result:=@MUTABLE_8888; + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 :Result:=@MUTABLE_5999; + VK_FORMAT_R16G16B16A16_UNORM :Result:=@MUTABLE_3232; VK_FORMAT_R16G16B16A16_SNORM :Result:=@MUTABLE_3232; VK_FORMAT_R16G16B16A16_USCALED:Result:=@MUTABLE_3232; @@ -922,6 +972,8 @@ begin VK_FORMAT_R10G11B11_UFLOAT_FAKE32:Result:=VK_FORMAT_R32_UINT; + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:Result:=VK_FORMAT_R32_UINT; + VK_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_USCALED, VK_FORMAT_R16G16B16A16_SSCALED, @@ -1053,8 +1105,6 @@ begin end; Function CompareNormalized(const a,b:TvImageKey):Integer; -var - ma,mb:Pointer; begin //1 Addr Result:=Integer(a.Addr>b.Addr)-Integer(a.Addrb.Addr2)-Integer(a.Addr20) then Exit; //2 cformat - ma:=GET_VK_IMAGE_MUTABLE(a.cformat); - mb:=GET_VK_IMAGE_MUTABLE(b.cformat); - Result:=Integer(ma>mb)-Integer(ma0) then Exit; //3 params Result:=CompareByte(GetNormalizedParams(a),GetNormalizedParams(b),SizeOf(TvImageKeyParams)); @@ -1456,6 +1504,9 @@ begin cinfo:=GetImageInfo; cinfo.format:=vkFixFormatSupport(cinfo.format,cinfo.tiling,cinfo.usage); + //save real format + FFormat:=cinfo.format; + cinfo.pNext:=@clist; MUTABLE:=GET_VK_IMAGE_MUTABLE(cinfo.format); diff --git a/vulkan/vImageManager.pas b/vulkan/vImageManager.pas index 72ab4791..66c7689a 100644 --- a/vulkan/vImageManager.pas +++ b/vulkan/vImageManager.pas @@ -550,6 +550,8 @@ begin if limits.VK_EXT_image_view_min_lod and (F.minLod<>0) then begin + uinfo.pNext:=@minfo; + // minfo:=Default(TVkImageViewMinLodCreateInfoEXT); minfo.sType :=VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT; minfo.minLod:=F.minLod; diff --git a/vulkan/vPipeline.pas b/vulkan/vPipeline.pas index 5185fa73..2c63fcb4 100644 --- a/vulkan/vPipeline.pas +++ b/vulkan/vPipeline.pas @@ -5,7 +5,6 @@ unit vPipeline; interface uses - g23tree, Vulkan, vDevice, vShader, @@ -81,105 +80,10 @@ type Destructor Destroy; override; end; - TvSetsPool=class; - - TvDescriptorSet=class - FParent:TvSetsPool; - FLayout:TvSetLayout; - FHandle:TVkDescriptorSet; - procedure _AllocDesc; - procedure _FreeDesc; - Destructor Destroy; override; - Procedure BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize); - Procedure BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); - end; - - _TvSetLayoutKey=object - Layout:TvSetLayout; - fcount:TVkUInt32; - function c(const a,b:_TvSetLayoutKey):Integer; static; - end; - - _TvSetLayoutSet=specialize T23treeSet<_TvSetLayoutKey,_TvSetLayoutKey>; - - _TvDescriptorSetCompare=object - function c(const a,b:TvDescriptorSet):Integer; static; - end; - - _TvDescriptorSetSet=specialize T23treeSet; - - AvDescriptorPoolSize=array of TVkDescriptorPoolSize; - - TvSetsPool=class - FHandle:TVkDescriptorPool; - FmaxSets:TVkUInt32; - FLayouts:_TvSetLayoutSet; - FSets:_TvDescriptorSetSet; - Destructor Destroy; override; - function _FindLayout(L:TvSetLayout):Boolean; - procedure ClearLayouts; - Procedure AddLayout(L:TvSetLayout;count:TVkUInt32=1); - Procedure AddFormPipelineLayout(L:TvPipelineLayout;count:TVkUInt32=1); - function Alloc(L:TvSetLayout):TvDescriptorSet; - function Compile:Boolean; - end; - /////// - TvDescriptorSet2=object - FHandle:TVkDescriptorSet; - Function IsValid:Boolean; - Procedure BindBuffer (aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize); - Procedure BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); - Procedure BindImage (aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); - Procedure BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler); - end; - - AvDescriptorSet2=Array of TvDescriptorSet2; - - TvDescriptorGroup=class(TvRefsObject) - //lock:Ptruint; - FSets:AvDescriptorSet2; - //Procedure Release; - end; - - AvDescriptorGroup=Array of TvDescriptorGroup; - - //PvSetsPoolKey=^TvSetsPoolKey; - //TvSetsPoolKey=record - // FPipeline:TvPipelineLayout; - // FNumber :PtrUint; - //end; - - TvSetsPool2=class - FHandle:TVkDescriptorPool; - //key:TvSetsPoolKey; - FPipeline:TvPipelineLayout; - FmaxGroup:TVkUInt32; - FmaxSets :TVkUInt32; - FAlcGroup:TVkUInt32; - //FGroups :AvDescriptorGroup; - Constructor Create(Pipeline:TvPipelineLayout;maxGroup:TVkUInt32); - Destructor Destroy; override; - function Compile:Boolean; - function Alloc(L:TvSetLayout):TvDescriptorSet2; - //function Alloc:TvDescriptorGroup; - function IsFull:Boolean; - function Alloc:AvDescriptorSet2; - end; - implementation -function _TvSetLayoutKey.c(const a,b:_TvSetLayoutKey):Integer; -begin - Result:=CompareByte(a.Layout,b.Layout,SizeOf(TvSetLayout)); -end; - -function _TvDescriptorSetCompare.c(const a,b:TvDescriptorSet):Integer; -begin - Result:=CompareByte(a,b,SizeOf(TvDescriptorSet)); -end; - Procedure TvSetLayout.Add(aBind:TVkUInt32;dType:TVkDescriptorType;Flags:TVkShaderStageFlags;count:TVkUInt32=1); var i:Integer; @@ -436,485 +340,6 @@ begin end; end; -// - -Destructor TvSetsPool.Destroy; -var - It:_TvDescriptorSetSet.Iterator; -begin - It:=FSets.cbegin; - if (It.Item<>nil) then - repeat - It.Item^.FHandle:=VK_NULL_HANDLE; - until not It.Next; - if (FHandle<>VK_NULL_HANDLE) then - begin - vkDestroyDescriptorPool(Device.FHandle,FHandle,nil); - end; - FSets.Free; - FLayouts.Free; -end; - -function TvSetsPool.Compile:Boolean; -var - i,b,L:Integer; - It:_TvSetLayoutSet.Iterator; - Ik:_TvSetLayoutKey; - Id:_TvDescriptorSetSet.Iterator; - FCounts:TvCountsGroup; - FSizes:AvDescriptorPoolSize; - cinfo:TVkDescriptorPoolCreateInfo; - r:TVkResult; -begin - Result:=False; - - if (FHandle<>VK_NULL_HANDLE) then Exit(true); - - if (FLayouts.Size=0) then Exit; - FSizes:=Default(AvDescriptorPoolSize); - - FmaxSets:=0; - FCounts:=Default(TvCountsGroup); - It:=FLayouts.cbegin; - repeat - Ik:=It.Item^; - if (Ik.Layout<>nil) and (Ik.fcount<>0) then - if (Length(Ik.Layout.key.FBinds)<>0) then - begin - FmaxSets:=FmaxSets+Ik.fcount; - For i:=0 to Ik.fcount-1 do - For b:=0 to High(Ik.Layout.key.FBinds) do - with Ik.Layout.key.FBinds[b] do - begin - Inc(FCounts[_GetIdByType(descriptorType)],descriptorCount); - end; - end; - until not It.Next; - - For i:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID do - if (FCounts[i]<>0) then - begin - L:=Length(FSizes); - SetLength(FSizes,L+1); - FSizes[L].type_ :=_GetTypeById(i); - FSizes[L].descriptorCount:=FCounts[i]; - end; - if (Length(FSizes)=0) then Exit; - - Id:=FSets.cbegin; - if (Id.Item<>nil) then - repeat - Id.Item^.FHandle:=VK_NULL_HANDLE; - until not Id.Next; - - It:=FLayouts.cbegin; - repeat - Ik:=It.Item^; - if (Ik.Layout<>nil) and (Ik.fcount<>0) then - begin - if not Ik.Layout.Compile then Exit; - end; - until not It.Next; - - cinfo:=Default(TVkDescriptorPoolCreateInfo); - cinfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - cinfo.flags :=ord(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT); - cinfo.poolSizeCount:=Length(FSizes); - cinfo.pPoolSizes :=@FSizes[0]; - cinfo.maxSets :=FmaxSets; - - r:=vkCreateDescriptorPool(Device.FHandle,@cinfo,nil,@FHandle); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkCreateDescriptorPool:',r); - Exit; - end; - - i:=0; - Id:=FSets.cbegin; - if (Id.Item<>nil) then - repeat - Id.Item^._AllocDesc; - Inc(i); - if (i>=FmaxSets) then Break; - until not Id.Next; - - Result:=True; -end; - -procedure TvSetsPool.ClearLayouts; -begin - FLayouts.Free; -end; - -function TvSetsPool._FindLayout(L:TvSetLayout):Boolean; -var - Ik:_TvSetLayoutKey; -begin - Ik.Layout:=L; - Ik.fcount:=0; - Result:=FLayouts.Contains(Ik); -end; - -Procedure TvSetsPool.AddLayout(L:TvSetLayout;count:TVkUInt32); -var - It:_TvSetLayoutSet.Iterator; - Ik:_TvSetLayoutKey; -begin - if (L=nil) then Exit; - if (count=0) then count:=1; - Ik.Layout:=L; - Ik.fcount:=count; - It:=FLayouts.find(Ik); - if (It.Item<>nil) then - begin - It.Item^.fcount:=It.Item^.fcount+count; - end else - begin - FLayouts.Insert(Ik); - end; -end; - -Procedure TvSetsPool.AddFormPipelineLayout(L:TvPipelineLayout;count:TVkUInt32); -var - i:Integer; -begin - if (L=nil) then Exit; - if (Length(L.key.FLayouts)<>0) then - For i:=0 to High(L.key.FLayouts) do - begin - AddLayout(L.key.FLayouts[i],count); - end; -end; - -function TvSetsPool.Alloc(L:TvSetLayout):TvDescriptorSet; -var - ainfo:TVkDescriptorSetAllocateInfo; - FResult:TVkDescriptorSet; - r:TVkResult; -begin - Result:=nil; - if (L=nil) then Exit; - if not _FindLayout(L) then Exit; - if not Compile then Exit; - if (FSets.Size>=FmaxSets) then Exit; - ainfo:=Default(TVkDescriptorSetAllocateInfo); - ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - ainfo.descriptorPool :=FHandle; - ainfo.descriptorSetCount:=1; - ainfo.pSetLayouts:=@L.FHandle; - r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FResult); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkAllocateDescriptorSets:',r); - Exit; - end; - Result:=TvDescriptorSet.Create; - Result.FParent:=Self; - Result.FLayout:=L; - Result.FHandle:=FResult; - FSets.Insert(Result); -end; - -procedure TvDescriptorSet._AllocDesc; -var - ainfo:TVkDescriptorSetAllocateInfo; - r:TVkResult; -begin - if (FParent<>nil) and (FLayout<>nil) then - if (FHandle=VK_NULL_HANDLE) and - (FParent.FHandle<>VK_NULL_HANDLE) then - begin - ainfo:=Default(TVkDescriptorSetAllocateInfo); - ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - ainfo.descriptorPool :=FParent.FHandle; - ainfo.descriptorSetCount:=1; - ainfo.pSetLayouts:=@FLayout.FHandle; - r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FHandle); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkAllocateDescriptorSets:',r); - Exit; - end; - end; -end; - -procedure TvDescriptorSet._FreeDesc; -var - r:TVkResult; -begin - if (FParent<>nil) then - if (FHandle<>VK_NULL_HANDLE) and - (FParent.FHandle<>VK_NULL_HANDLE) then - begin - r:=vkFreeDescriptorSets(Device.FHandle,FParent.FHandle,1,@FHandle); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkFreeDescriptorSets:',r); - end; - end; - FHandle:=VK_NULL_HANDLE; -end; - -Destructor TvDescriptorSet.Destroy; -begin - if (FParent<>nil) then - begin - _FreeDesc; - FParent.FSets.delete(Self); - end; - inherited; -end; - -//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER -//VK_DESCRIPTOR_TYPE_STORAGE_BUFFER -//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC -//VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC - -Procedure TvDescriptorSet.BindBuf(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize); -var - dwrite:TVkWriteDescriptorSet; - buf:TVkDescriptorBufferInfo; -begin - buf:=Default(TVkDescriptorBufferInfo); - buf.buffer:=buffer; - buf.offset:=offset; - buf.range :=range ; - - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=dtype; - dwrite.descriptorCount:=1; - dwrite.pBufferInfo :=@buf; - - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -Procedure TvDescriptorSet.BindSTI(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); -var - dwrite:TVkWriteDescriptorSet; - dimg:TVkDescriptorImageInfo; -begin - dimg:=Default(TVkDescriptorImageInfo); - dimg.imageView :=img; - dimg.imageLayout:=Layout; - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - dwrite.descriptorCount:=1; - dwrite.pImageInfo :=@dimg; - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -// - -Function TvDescriptorSet2.IsValid:Boolean; -begin - Result:=FHandle<>VK_NULL_HANDLE; -end; - -Procedure TvDescriptorSet2.BindBuffer(aBind,aElem:TVkUInt32;dtype:TVkDescriptorType;buffer:TVkBuffer;offset,range:TVkDeviceSize); -var - dwrite:TVkWriteDescriptorSet; - buf:TVkDescriptorBufferInfo; -begin - buf:=Default(TVkDescriptorBufferInfo); - buf.buffer:=buffer; - buf.offset:=offset; - buf.range :=range ; - - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=dtype; - dwrite.descriptorCount:=1; - dwrite.pBufferInfo :=@buf; - - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -Procedure TvDescriptorSet2.BindStorage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); -var - dwrite:TVkWriteDescriptorSet; - dimg:TVkDescriptorImageInfo; -begin - dimg:=Default(TVkDescriptorImageInfo); - dimg.imageView :=img; - dimg.imageLayout:=Layout; - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - dwrite.descriptorCount:=1; - dwrite.pImageInfo :=@dimg; - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -Procedure TvDescriptorSet2.BindImage(aBind,aElem:TVkUInt32;img:TVkImageView;Layout:TVkImageLayout); -var - dwrite:TVkWriteDescriptorSet; - dimg:TVkDescriptorImageInfo; -begin - dimg:=Default(TVkDescriptorImageInfo); - dimg.imageView :=img; - dimg.imageLayout:=Layout; - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - dwrite.descriptorCount:=1; - dwrite.pImageInfo :=@dimg; - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -Procedure TvDescriptorSet2.BindSampler(aBind,aElem:TVkUInt32;smp:TVkSampler); -var - dwrite:TVkWriteDescriptorSet; - dimg:TVkDescriptorImageInfo; -begin - dimg:=Default(TVkDescriptorImageInfo); - dimg.sampler:=smp; - dwrite:=Default(TVkWriteDescriptorSet); - dwrite.sType :=VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - dwrite.dstSet :=FHandle; - dwrite.dstBinding :=aBind; - dwrite.dstArrayElement:=aElem; - dwrite.descriptorType :=VK_DESCRIPTOR_TYPE_SAMPLER; - dwrite.descriptorCount:=1; - dwrite.pImageInfo :=@dimg; - vkUpdateDescriptorSets(Device.FHandle,1,@dwrite,0,nil); -end; - -Constructor TvSetsPool2.Create(Pipeline:TvPipelineLayout;maxGroup:TVkUInt32); -begin - FPipeline:=Pipeline; - FmaxGroup:=maxGroup; -end; - -Destructor TvSetsPool2.Destroy; -begin - if (FHandle<>VK_NULL_HANDLE) then - begin - vkDestroyDescriptorPool(Device.FHandle,FHandle,nil); - end; -end; - -function TvSetsPool2.Compile:Boolean; -var - i,p:Integer; - FSizes:AvDescriptorPoolSize; - cinfo:TVkDescriptorPoolCreateInfo; - r:TVkResult; -begin - Result:=False; - if (FHandle<>VK_NULL_HANDLE) then Exit(true); - - if (FPipeline=nil) then Exit; - if (FmaxGroup=0) then Exit; - - if (not FPipeline.Compile) then Exit; - - FSizes:=Default(AvDescriptorPoolSize); - SetLength(FSizes,FPipeline.FTypes); - - FmaxSets:=FPipeline.FSets*FmaxGroup; - - p:=0; - For i:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID do - begin - if (FPipeline.FCounts[i]<>0) then - begin - FSizes[p].type_ :=_GetTypeById(i); - FSizes[p].descriptorCount:=FPipeline.FCounts[i]*FmaxGroup; - Inc(p); - end; - end; - - if (Length(FSizes)=0) then Exit; - - cinfo:=Default(TVkDescriptorPoolCreateInfo); - cinfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - //cinfo.flags :=ord(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT); - cinfo.poolSizeCount:=Length(FSizes); - cinfo.pPoolSizes :=@FSizes[0]; - cinfo.maxSets :=FmaxSets; - - r:=vkCreateDescriptorPool(Device.FHandle,@cinfo,nil,@FHandle); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkCreateDescriptorPool:',r); - Exit; - end; - - Result:=True; -end; - -function TvSetsPool2.Alloc(L:TvSetLayout):TvDescriptorSet2; -var - ainfo:TVkDescriptorSetAllocateInfo; - FResult:TVkDescriptorSet; - r:TVkResult; -begin - Result:=Default(TvDescriptorSet2); - - if (L=nil) then Exit; - if L.IsSpace then Exit; - - if not Compile then Exit; - - ainfo:=Default(TVkDescriptorSetAllocateInfo); - ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - ainfo.descriptorPool :=FHandle; - ainfo.descriptorSetCount:=1; - ainfo.pSetLayouts :=@L.FHandle; - r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FResult); - if (r<>VK_SUCCESS) then - begin - Writeln(StdErr,'vkAllocateDescriptorSets:',r); - Exit; - end; - - Result.FHandle:=FResult; -end; - -function TvSetsPool2.IsFull:Boolean; -begin - Result:=(FAlcGroup>=FmaxGroup); -end; - -function TvSetsPool2.Alloc:AvDescriptorSet2; -var - i:Integer; -begin - Result:=nil; - if IsFull then Exit; - SetLength(Result,Length(FPipeline.key.FLayouts)); - If (Length(Result)<>0) then - For i:=0 to High(Result) do - begin - Result[i]:=Alloc(FPipeline.key.FLayouts[i]); - end; - Inc(FAlcGroup); -end; - -{ -Procedure TvDescriptorGroup.Release; -begin - lock:=0; -end; -} end. diff --git a/vulkan/vSetsPool.pas b/vulkan/vSetsPool.pas new file mode 100644 index 00000000..9f06824c --- /dev/null +++ b/vulkan/vSetsPool.pas @@ -0,0 +1,146 @@ +unit vSetsPool; + +{$mode ObjFPC}{$H+} + +interface + +uses + Vulkan, + vDevice, + vShader, + vDescriptorSet, + vPipeline; + +type + TvSetsPool2=class + FHandle :TVkDescriptorPool; + FLayout :TvPipelineLayout; + FmaxGroup:TVkUInt32; + FmaxSets :TVkUInt32; + FAlcGroup:TVkUInt32; + Constructor Create(Layout:TvPipelineLayout;maxGroup:TVkUInt32); + Destructor Destroy; override; + function Compile:Boolean; + function Alloc(L:TvSetLayout):TvDescriptorSet2; + function IsFull:Boolean; + function Alloc:AvDescriptorSet2; + end; + +implementation + +Constructor TvSetsPool2.Create(Layout:TvPipelineLayout;maxGroup:TVkUInt32); +begin + FLayout :=Layout; + FmaxGroup:=maxGroup; +end; + +Destructor TvSetsPool2.Destroy; +begin + if (FHandle<>VK_NULL_HANDLE) then + begin + vkDestroyDescriptorPool(Device.FHandle,FHandle,nil); + end; +end; + +function TvSetsPool2.Compile:Boolean; +type + AvDescriptorPoolSize=array[0..HI_DESCRIPTOR_ID] of TVkDescriptorPoolSize; +var + i,p:Integer; + FSizes:AvDescriptorPoolSize; + cinfo:TVkDescriptorPoolCreateInfo; + r:TVkResult; +begin + Result:=False; + if (FHandle<>VK_NULL_HANDLE) then Exit(true); + + if (FLayout=nil) then Exit; + if (FmaxGroup=0) then Exit; + + if (not FLayout.Compile) then Exit; + + if (FLayout.FTypes=0) then Exit; + + FSizes:=Default(AvDescriptorPoolSize); + + FmaxSets:=FLayout.FSets*FmaxGroup; + + p:=0; + For i:=LO_DESCRIPTOR_ID to HI_DESCRIPTOR_ID do + begin + if (FLayout.FCounts[i]<>0) then + begin + FSizes[p].type_ :=_GetTypeById(i); + FSizes[p].descriptorCount:=FLayout.FCounts[i]*FmaxGroup; + Inc(p); + end; + end; + + cinfo:=Default(TVkDescriptorPoolCreateInfo); + cinfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + //cinfo.flags :=ord(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT); + cinfo.poolSizeCount:=FLayout.FTypes; + cinfo.pPoolSizes :=@FSizes[0]; + cinfo.maxSets :=FmaxSets; + + r:=vkCreateDescriptorPool(Device.FHandle,@cinfo,nil,@FHandle); + if (r<>VK_SUCCESS) then + begin + Writeln(StdErr,'vkCreateDescriptorPool:',r); + Exit; + end; + + Result:=True; +end; + +function TvSetsPool2.Alloc(L:TvSetLayout):TvDescriptorSet2; +var + ainfo:TVkDescriptorSetAllocateInfo; + FResult:TVkDescriptorSet; + r:TVkResult; +begin + Result:=Default(TvDescriptorSet2); + + if (L=nil) then Exit; + if L.IsSpace then Exit; + + if not Compile then Exit; + + ainfo:=Default(TVkDescriptorSetAllocateInfo); + ainfo.sType :=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + ainfo.descriptorPool :=FHandle; + ainfo.descriptorSetCount:=1; + ainfo.pSetLayouts :=@L.FHandle; + r:=vkAllocateDescriptorSets(Device.FHandle,@ainfo,@FResult); + if (r<>VK_SUCCESS) then + begin + Writeln(StdErr,'vkAllocateDescriptorSets:',r); + Exit; + end; + + Result.FHandle:=FResult; +end; + +function TvSetsPool2.IsFull:Boolean; +begin + Result:=(FAlcGroup>=FmaxGroup); +end; + +function TvSetsPool2.Alloc:AvDescriptorSet2; +var + i:Integer; +begin + Result:=nil; + if IsFull then Exit; + SetLength(Result,Length(FLayout.key.FLayouts)); + If (Length(Result)<>0) then + For i:=0 to High(Result) do + begin + Result[i]:=Alloc(FLayout.key.FLayouts[i]); + end; + Inc(FAlcGroup); +end; + + +end. + diff --git a/vulkan/vSetsPoolManager.pas b/vulkan/vSetsPoolManager.pas index 864d4e3d..f2c7db6e 100644 --- a/vulkan/vSetsPoolManager.pas +++ b/vulkan/vSetsPoolManager.pas @@ -10,9 +10,11 @@ uses g23tree, Vulkan, vPipeline, - vCmdBuffer; + vSetsPool, + vDescriptorSet, + vDependence; -Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup; +Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup; implementation @@ -41,11 +43,11 @@ type end; TvSetsPoolUnbound=class - FPipeline:TvPipelineLayout; + FLayout:TvPipelineLayout; FQueue:TIntrusiveMPSCQueue; FPools:TvSetsPool2Set; FLast:TvSetsPool2; - Constructor Create(Pipeline:TvPipelineLayout); + Constructor Create(Layout:TvPipelineLayout); Procedure NewPool; function Alloc:TvDescriptorGroupNode; procedure PushNode(N:TvDescriptorGroupNode); @@ -82,9 +84,9 @@ begin Result:=Integer(Pointer(a^)>Pointer(b^))-Integer(Pointer(a^)nil) then begin - Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FPipeline)); + Result:=TvSetsPoolUnbound(ptruint(i.Item^)-ptruint(@TvSetsPoolUnbound(nil).FLayout)); end; end; -Function _Fetch(Pipeline:TvPipelineLayout):TvDescriptorGroupNode; +Function _Fetch(Layout:TvPipelineLayout):TvDescriptorGroupNode; var t:TvSetsPoolUnbound; n:TvDescriptorGroupNode; @@ -163,12 +167,12 @@ var begin Result:=nil; - t:=_Find(Pipeline); + t:=_Find(Layout); if (t=nil) then begin - t:=TvSetsPoolUnbound.Create(Pipeline); - FSetsPoolUnbounds.Insert(@t.FPipeline); + t:=TvSetsPoolUnbound.Create(Layout); + FSetsPoolUnbounds.Insert(@t.FLayout); end; n:=t.Alloc; @@ -176,15 +180,15 @@ begin Result:=n; end; -Function FetchDescriptorGroup(cmd:TvCustomCmdBuffer;Pipeline:TvPipelineLayout):TvDescriptorGroup; +Function FetchDescriptorGroup(cmd:TvDependenciesObject;Layout:TvPipelineLayout):TvDescriptorGroup; begin Result:=nil; - if (Pipeline=nil) then Exit; - if Pipeline.isSpace then Exit; + if (Layout=nil) then Exit; + if Layout.isSpace then Exit; FSetsPoolUnbounds.Lock_wr; - Result:=_Fetch(Pipeline); + Result:=_Fetch(Layout); cmd.RefTo(Result);