diff --git a/chip/pm4_me.pas b/chip/pm4_me.pas index fcd02e19..f126204e 100644 --- a/chip/pm4_me.pas +++ b/chip/pm4_me.pas @@ -504,6 +504,8 @@ begin end; end; +procedure pm4_Writeback_Finish(var ctx:t_me_render_context); forward; + // procedure t_me_render_context.FinishCmdBuffer; var @@ -513,6 +515,8 @@ var begin if (Cmd=nil) then Exit; + pm4_Writeback_Finish(Self); + r:=Cmd.QueueSubmit; Writeln('QueueSubmit:',r); @@ -1169,11 +1173,15 @@ begin end; -procedure pm4_Writeback(var ctx:t_me_render_context); +procedure pm4_Writeback_After(var ctx:t_me_render_context); var i:Integer; ri:TvImage2; + rd:TvCustomImage2; + rs:TvCustomImage2; + + resource_instance:p_pm4_resource_instance; begin //write back @@ -1181,14 +1189,28 @@ begin For i:=0 to ctx.rt_info^.RT_COUNT-1 do if (ctx.rt_info^.RT_INFO[i].attachment<>VK_ATTACHMENT_UNUSED) then begin - ri:=FetchImage(ctx.Cmd, ctx.rt_info^.RT_INFO[i].FImageInfo, [iu_attachment] //RenderCmd.RT_INFO[i].IMAGE_USAGE ); - pm4_write_back(ctx.Cmd,ri); + ri.mark_init; + + resource_instance:=ctx.node^.scope.find_image_resource_instance(ctx.rt_info^.RT_INFO[i].FImageInfo); + Assert(resource_instance<>nil); + + if (resource_instance^.next_overlap.mem_usage<>0) then + begin + pm4_write_back(ctx.Cmd,ri); + // + resource_instance^.resource^.rwriteback:=False; + end else + begin + // + resource_instance^.resource^.rwriteback:=True; + end; + end; if ctx.rt_info^.DB_ENABLE then @@ -1200,8 +1222,50 @@ begin //RenderCmd.DB_INFO.DEPTH_USAGE ); - pm4_write_back(ctx.Cmd,ri.DepthOnly ); - pm4_write_back(ctx.Cmd,ri.StencilOnly); + rd:=ri.DepthOnly; + rs:=ri.StencilOnly; + + if (rd<>nil) then + begin + rd.mark_init; + + resource_instance:=ctx.node^.scope.find_image_resource_instance(rd.key); + Assert(resource_instance<>nil); + + if (resource_instance^.next_overlap.mem_usage<>0) then + begin + pm4_write_back(ctx.Cmd,rd); + // + resource_instance^.resource^.rwriteback:=False; + end else + begin + // + resource_instance^.resource^.rwriteback:=True; + end; + + end; + + + + if (rs<>nil) then + begin + rs.mark_init; + + resource_instance:=ctx.node^.scope.find_image_resource_instance(rs.key); + Assert(resource_instance<>nil); + + if (resource_instance^.next_overlap.mem_usage<>0) then + begin + pm4_write_back(ctx.Cmd,rs); + // + resource_instance^.resource^.rwriteback:=False; + end else + begin + // + resource_instance^.resource^.rwriteback:=True; + end; + + end; // end; @@ -1209,6 +1273,46 @@ begin //write back end; +procedure pm4_Writeback_Finish(var ctx:t_me_render_context); +var + i:Integer; + + ri:TvImage2; + + resource:p_pm4_resource; +begin + if (ctx.stream=nil) then Exit; + + //write back + + resource:=ctx.stream^.resource_set.Min; + + while (resource<>nil) do + begin + + if resource^.rwriteback then + begin + + if (resource^.rtype=R_IMG) then + begin + + ri:=FetchImage(ctx.Cmd, + resource^.rkey, + []); + // + pm4_write_back(ctx.Cmd,ri); + // + resource^.rwriteback:=False; + end; + + end; + + resource:=ctx.stream^.resource_set.Next(resource); + end; + + //write back +end; + procedure pm4_Draw(var ctx:t_me_render_context;node:p_pm4_node_draw); begin // @@ -1250,7 +1354,7 @@ begin ///////// - pm4_Writeback(ctx); + pm4_Writeback_After(ctx); end; diff --git a/chip/pm4_stream.pas b/chip/pm4_stream.pas index 3ad7f1a7..675d146e 100644 --- a/chip/pm4_stream.pas +++ b/chip/pm4_stream.pas @@ -158,6 +158,8 @@ type rsize :DWORD; rkey :TvImageKey; // + rwriteback:Boolean; + // function c(n1,n2:p_pm4_resource):Integer; static; end; diff --git a/vulkan/vImageManager.pas b/vulkan/vImageManager.pas index b53f6ef1..0a3f8b29 100644 --- a/vulkan/vImageManager.pas +++ b/vulkan/vImageManager.pas @@ -54,6 +54,14 @@ type TvImageView2Set=specialize T23treeSet; + t_change_rate=object + state :Integer; + trigger:Integer; + planned:Integer; + procedure mark_init; + function need_read:Boolean; + end; + TvCustomImage2=class(TvCustomImage) // key :TvImageKey; @@ -61,8 +69,7 @@ type size:Ptruint; tobj:p_vm_track_object; // - ref_trigger:Ptruint; - ref_planned:Ptruint; + change_rate:t_change_rate; // Parent :TvCustomImage2; DepthOnly :TvCustomImage2; @@ -70,9 +77,11 @@ type // lock:Pointer; // - Constructor Create; Destructor Destroy; override; procedure assign_vm_track; virtual; + procedure mark_init; + function get_change_rate:t_change_rate; + procedure apply_change_rate(r:t_change_rate); Function GetSubresRange:TVkImageSubresourceRange; virtual; Function GetSubresLayer:TVkImageSubresourceLayers; virtual; function _FetchView(cmd:TvCustomCmdBuffer;const F:TvImageViewKey;usage:TVkFlags):TvImageView2; virtual; abstract; @@ -205,7 +214,7 @@ end; function on_trigger(handle:Pointer;mode:Integer):Integer; SysV_ABI_CDecl; var image:TvCustomImage2; - i:Ptruint; + i:Integer; begin Result:=DO_NOTHING; @@ -216,18 +225,18 @@ begin case mode of 0://direct begin - System.InterlockedIncrement64(image.ref_trigger); + System.InterlockedIncrement(image.change_rate.trigger); end; 1://planned begin - System.InterlockedIncrement64(image.ref_planned); + System.InterlockedIncrement(image.change_rate.planned); end; 2://differed begin - i:=System.InterlockedExchangeAdd64(image.ref_planned,0); + i:=System.InterlockedExchangeAdd(image.change_rate.planned,0); - System.InterlockedExchangeAdd64(image.ref_trigger,+i); - System.InterlockedExchangeAdd64(image.ref_planned,-i); + System.InterlockedExchangeAdd(image.change_rate.trigger,+i); + System.InterlockedExchangeAdd(image.change_rate.planned,-i); end; else; end; @@ -237,12 +246,6 @@ end; // -Constructor TvCustomImage2.Create; -begin - inherited; - ref_trigger:=1; -end; - Destructor TvCustomImage2.Destroy; begin if (tobj<>nil) then @@ -280,6 +283,35 @@ begin rw_wunlock(lock) end; +procedure t_change_rate.mark_init; +begin + state:=1; +end; + +function t_change_rate.need_read:Boolean; +begin + Result:=(state=0) or (trigger<>0) or (planned<>0); +end; + +procedure TvCustomImage2.mark_init; +begin + System.InterlockedExchange(change_rate.state,1); +end; + +function TvCustomImage2.get_change_rate:t_change_rate; +begin + Result.state :=System.InterlockedExchangeAdd(change_rate.state ,0); + Result.trigger:=System.InterlockedExchangeAdd(change_rate.trigger,0); + Result.planned:=System.InterlockedExchangeAdd(change_rate.planned,0); +end; + +procedure TvCustomImage2.apply_change_rate(r:t_change_rate); +begin + System.InterlockedExchange (change_rate.state , r.state); + System.InterlockedExchangeAdd(change_rate.trigger,-r.trigger); + System.InterlockedExchangeAdd(change_rate.planned,-r.planned); +end; + Function TvCustomImage2.GetSubresRange:TVkImageSubresourceRange; begin Result:=Default(TVkImageSubresourceRange); diff --git a/vulkan/vImageTiling.pas b/vulkan/vImageTiling.pas index 2d909fad..8e9c902a 100644 --- a/vulkan/vImageTiling.pas +++ b/vulkan/vImageTiling.pas @@ -760,18 +760,15 @@ end; procedure pm4_load_from(cmd:TvCustomCmdBuffer;image:TvCustomImage2;IMAGE_USAGE:Byte); var cb:t_load_from_cb; - ref_trigger:Ptruint; - ref_planned:Ptruint; + change_rate:t_change_rate; begin if (cmd=nil) or (image=nil) then Exit; if (IMAGE_USAGE and TM_READ)=0 then Exit; - ref_trigger:=System.InterlockedExchangeAdd64(image.ref_trigger,0); - ref_planned:=System.InterlockedExchangeAdd64(image.ref_planned,0); + change_rate:=image.get_change_rate; - if (ref_trigger=0) and - (ref_planned=0) then Exit; + if not change_rate.need_read then Exit; cb:=a_tiling_cbs[Byte(image.key.params.tiling)].load_from; @@ -785,8 +782,9 @@ begin cb(cmd,image); - System.InterlockedExchangeAdd64(image.ref_trigger,-ref_trigger); - System.InterlockedExchangeAdd64(image.ref_planned,-ref_planned); + change_rate.mark_init; + + image.apply_change_rate(change_rate); image.assign_vm_track; end; @@ -809,6 +807,8 @@ begin cb(cmd,image); + image.mark_init; + image.assign_vm_track; cmd.AddPlannedTrigger(QWORD(image.key.Addr),QWORD(image.key.Addr)+image.size,image.tobj);