diff --git a/chip/pm4_me.pas b/chip/pm4_me.pas index 068940da..45aa854c 100644 --- a/chip/pm4_me.pas +++ b/chip/pm4_me.pas @@ -687,12 +687,76 @@ end; // +function GetMixedFlag(const curr:t_pm4_usage):Byte; +begin + if (PopCnt(DWORD(curr.img_usage))>1) then + begin + Result:=TM_MIXED; + end else + begin + Result:=0; + end; +end; + +function GetImageLayout(const curr:t_pm4_usage):TVkImageLayout; +begin + if (PopCnt(DWORD(curr.img_usage))>1) then + begin + Result:=VK_IMAGE_LAYOUT_GENERAL; + end else + case t_image_usage(BsfDWord(DWORD(curr.img_usage))) of + iu_attachment: + begin + Result:=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + end; + iu_depthstenc: + begin + if ((curr.shd_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; + iu_sampled, + iu_storage: + begin + if ((curr.shd_usage and (TM_WRITE or TM_CLEAR))<>0) then + begin + Result:=VK_IMAGE_LAYOUT_GENERAL; + end else + begin + Result:=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + end; + end; + else + Result:=VK_IMAGE_LAYOUT_UNDEFINED; + end; +end; + +function ConvertRW(IMAGE_USAGE:Byte;R,W:TVkAccessFlagBits):TVkAccessFlags; inline; +begin + Result:=(ord(R)*ord((IMAGE_USAGE and TM_READ )<>0) ) or + (ord(W)*ord((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) ); +end; + +function GetAccessMask(const curr:t_pm4_usage):TVkAccessFlags; +begin + Result:= + ConvertRW(curr.shd_usage,VK_ACCESS_SHADER_READ_BIT ,VK_ACCESS_SHADER_WRITE_BIT ) or + ConvertRW(curr.clr_usage,VK_ACCESS_COLOR_ATTACHMENT_READ_BIT ,VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT ) or + ConvertRW(curr.dsa_usage,VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); +end; + procedure Prepare_Uniforms(var ctx:t_me_render_context; var UniformBuilder:TvUniformBuilder); var i:Integer; ri:TvImage2; + + resource_instance:p_pm4_resource_instance; begin //Writeln('[Prepare_Uniforms]->'); @@ -702,23 +766,30 @@ begin With UniformBuilder.FImages[i] do begin - ri:=FetchImage(ctx.Cmd, - FImage, - [iu_sampled] - ); + resource_instance:=ctx.node^.scope.find_image_resource_instance(FImage); + + Assert(resource_instance<>nil); + + ri:=TvImage2(resource_instance^.resource^.rimage); + + if (ri=nil) then + begin + ri:=FetchImage(ctx.Cmd, + FImage, + {[iu_sampled]} resource_instance^.curr.img_usage + ); + + resource_instance^.resource^.rimage:=ri; + end; //Writeln(ri.key.cformat); pm4_load_from(ctx.Cmd,ri,TM_READ); - begin - - ri.PushBarrier(ctx.Cmd, - ord(VK_ACCESS_SHADER_READ_BIT), - VK_IMAGE_LAYOUT_GENERAL, - ord(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) or - ord(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) ); - end; + ri.PushBarrier(ctx.Cmd, + GetAccessMask(resource_instance^.curr), + GetImageLayout(resource_instance^.curr), + ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT)); end; end; @@ -733,8 +804,7 @@ end; procedure Bind_Uniforms(var ctx:t_me_render_context; BindPoint:TVkPipelineBindPoint; - var UniformBuilder:TvUniformBuilder; - ShaderGroup:TvShaderGroup); + var UniformBuilder:TvUniformBuilder); var i:Integer; @@ -764,24 +834,24 @@ begin resource_instance:=ctx.node^.scope.find_image_resource_instance(FImage); - if (resource_instance<>nil) then - begin - Writeln('ri:curr:',HexStr(resource_instance^.curr.mem_usage,1), - ' prev:',HexStr(resource_instance^.prev.mem_usage,1), - ' next:',HexStr(resource_instance^.next.mem_usage,1) - ); - end; + Assert(resource_instance<>nil); + ri:=TvImage2(resource_instance^.resource^.rimage); + + Assert(ri<>nil); + + { ri:=FetchImage(ctx.Cmd, FImage, [iu_sampled] ); + } iv:=ri.FetchView(ctx.Cmd,FView,iu_sampled); DescriptorGroup.BindImage(fset,bind, iv.FHandle, - VK_IMAGE_LAYOUT_GENERAL); + GetImageLayout(resource_instance^.curr)); end; @@ -811,6 +881,7 @@ begin resource_instance:=ctx.node^.scope.find_buffer_resource_instance(addr,size); + { if (resource_instance<>nil) then begin @@ -820,6 +891,7 @@ begin ); end; + } buf:=FetchHostBuffer(ctx.Cmd,QWORD(addr),size,ord(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)); @@ -914,13 +986,15 @@ begin // - Writeln('init_img:',HexStr(resource^.rkey.Addr),' ',(resource^.rkey.params.width),'x',(resource^.rkey.params.height)); + //Writeln('init_img:',HexStr(resource^.rkey.Addr),' ',(resource^.rkey.params.width),'x',(resource^.rkey.params.height)); ri:=FetchImage(ctx.Cmd, resource^.rkey, i^.curr.img_usage + i^.next.img_usage ); + resource^.rimage:=ri; + pm4_load_from(ctx.Cmd,ri,i^.curr.mem_usage); end else if (resource^.rtype=R_HTILE) then @@ -954,12 +1028,6 @@ begin rt_info.DB_INFO.FImageInfo, [iu_depthstenc] ); - { - ri.PushBarrier(CmdBuffer, - ord(VK_ACCESS_TRANSFER_READ_BIT), - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - ord(VK_PIPELINE_STAGE_TRANSFER_BIT)); - } ri.PushBarrier(CmdBuffer, ord(VK_ACCESS_TRANSFER_WRITE_BIT), @@ -1021,7 +1089,9 @@ var ri:TvImage2; iv:TvImageView2; - resource_instance:p_pm4_resource_instance; + color_instance:array[0..7] of p_pm4_resource_instance; + + htile_instance:p_pm4_resource_instance; begin RP_KEY.Clear; @@ -1029,9 +1099,16 @@ begin For i:=0 to ctx.rt_info^.RT_COUNT-1 do begin + color_instance[i]:=ctx.node^.scope.find_image_resource_instance(ctx.rt_info^.RT_INFO[i].FImageInfo); + + Assert(color_instance[i]<>nil); + + //TODO: fixup cformat + RP_KEY.AddColorAt(ctx.rt_info^.RT_INFO[i].attachment, ctx.rt_info^.RT_INFO[i].FImageInfo.cformat, - ctx.rt_info^.RT_INFO[i].IMAGE_USAGE, + ctx.rt_info^.RT_INFO[i].IMAGE_USAGE or + GetMixedFlag(color_instance[i]^.curr), ctx.rt_info^.RT_INFO[i].FImageInfo.params.samples); end; @@ -1042,27 +1119,29 @@ begin //set clear flag on cleared htile if (ctx.rt_info^.DB_INFO.HTILE_INFO.TILE_SURFACE_ENABLE<>0) then begin - resource_instance:=ctx.node^.scope.find_htile_resource_instance(ctx.rt_info^.DB_INFO.HTILE_INFO.KEY.Addr, + htile_instance:=ctx.node^.scope.find_htile_resource_instance(ctx.rt_info^.DB_INFO.HTILE_INFO.KEY.Addr, ctx.rt_info^.DB_INFO.HTILE_INFO.SIZE); + Assert(htile_instance<>nil); - Assert(resource_instance<>nil); - - if resource_instance^.resource^.rclear then + if htile_instance^.resource^.rclear then begin //clear TM_READ ctx.rt_info^.DB_INFO.DEPTH_USAGE:=ctx.rt_info^.DB_INFO.DEPTH_USAGE and (not TM_READ); //set TM_CLEAR ctx.rt_info^.DB_INFO.DEPTH_USAGE:=ctx.rt_info^.DB_INFO.DEPTH_USAGE or TM_CLEAR; - resource_instance^.resource^.rclear:=False; + htile_instance^.resource^.rclear:=False; end; end; + //TODO: fixup cformat + RP_KEY.AddDepthAt(ctx.rt_info^.RT_COUNT, //add to last attachment id ctx.rt_info^.DB_INFO.FImageInfo.cformat, ctx.rt_info^.DB_INFO.DEPTH_USAGE, - ctx.rt_info^.DB_INFO.STENCIL_USAGE); + ctx.rt_info^.DB_INFO.STENCIL_USAGE, + ctx.rt_info^.DB_INFO.FImageInfo.params.samples); RP_KEY.SetZorderStage(ctx.rt_info^.DB_INFO.zorder_stage); @@ -1129,11 +1208,15 @@ begin if (ctx.rt_info^.RT_COUNT<>0) then For i:=0 to ctx.rt_info^.RT_COUNT-1 do begin + //TODO: fixup cformat + FB_KEY.AddImageAt(ctx.rt_info^.RT_INFO[i].FImageInfo); end; if ctx.rt_info^.DB_ENABLE then begin + //TODO: fixup cformat + FB_KEY.AddImageAt(ctx.rt_info^.DB_INFO.FImageInfo); end; end else @@ -1159,40 +1242,32 @@ begin For i:=0 to ctx.rt_info^.RT_COUNT-1 do begin - resource_instance:=ctx.node^.scope.find_image_resource_instance(ctx.rt_info^.RT_INFO[i].FImageInfo); + ri:=TvImage2(color_instance[i]^.resource^.rimage); - if (resource_instance<>nil) then + if (ri=nil) then begin - Writeln('ra:curr:',HexStr(resource_instance^.curr.mem_usage,1), - ' prev:',HexStr(resource_instance^.prev.mem_usage,1), - ' next:',HexStr(resource_instance^.next.mem_usage,1) - ); + ri:=FetchImage(ctx.Cmd, + ctx.rt_info^.RT_INFO[i].FImageInfo, + {[iu_attachment]} color_instance[i]^.curr.img_usage + ); + + color_instance[i]^.resource^.rimage:=ri; end; - ctx.Render.AddClearColor(ctx.rt_info^.RT_INFO[i].CLEAR_COLOR); - - ri:=FetchImage(ctx.Cmd, - ctx.rt_info^.RT_INFO[i].FImageInfo, - [iu_attachment] - ); - pm4_load_from(ctx.Cmd,ri,ctx.rt_info^.RT_INFO[i].IMAGE_USAGE); iv:=ri.FetchView(ctx.Cmd,ctx.rt_info^.RT_INFO[i].FImageView,iu_attachment); - { - ri.PushBarrier(CmdBuffer, - ord(VK_ACCESS_TRANSFER_READ_BIT), - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - ord(VK_PIPELINE_STAGE_TRANSFER_BIT)); - } - ri.PushBarrier(ctx.Cmd, - GetColorAccessMask(ctx.rt_info^.RT_INFO[i].IMAGE_USAGE), - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL {VK_IMAGE_LAYOUT_GENERAL}, + GetAccessMask(color_instance[i]^.curr), + GetImageLayout(color_instance[i]^.curr), ord(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) or ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) ); + // + + ctx.Render.AddClearColor(ctx.rt_info^.RT_INFO[i].CLEAR_COLOR); + // if limits.VK_KHR_imageless_framebuffer then begin @@ -1208,8 +1283,9 @@ begin if ctx.rt_info^.DB_ENABLE then begin - resource_instance:=ctx.node^.scope.find_image_resource_instance(GetDepthOnly(ctx.rt_info^.DB_INFO.FImageInfo)); + //resource_instance:=ctx.node^.scope.find_image_resource_instance(GetDepthOnly(ctx.rt_info^.DB_INFO.FImageInfo)); + { if (resource_instance<>nil) then begin Writeln('rd:curr:',HexStr(resource_instance^.curr.mem_usage,1), @@ -1217,9 +1293,11 @@ begin ' next:',HexStr(resource_instance^.next.mem_usage,1) ); end; + } - resource_instance:=ctx.node^.scope.find_image_resource_instance(GetStencilOnly(ctx.rt_info^.DB_INFO.FImageInfo)); + //resource_instance:=ctx.node^.scope.find_image_resource_instance(GetStencilOnly(ctx.rt_info^.DB_INFO.FImageInfo)); + { if (resource_instance<>nil) then begin Writeln('rs:curr:',HexStr(resource_instance^.curr.mem_usage,1), @@ -1227,6 +1305,7 @@ begin ' next:',HexStr(resource_instance^.next.mem_usage,1) ); end; + } // @@ -1242,15 +1321,8 @@ begin iv:=ri.FetchView(ctx.Cmd,iu_depthstenc); - { - ri.PushBarrier(CmdBuffer, - ord(VK_ACCESS_TRANSFER_READ_BIT), - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - ord(VK_PIPELINE_STAGE_TRANSFER_BIT)); - } - ri.PushBarrier(ctx.Cmd, - GetDepthStencilAccessMask(ctx.rt_info^.DB_INFO.DEPTH_USAGE,ctx.rt_info^.DB_INFO.STENCIL_USAGE), + GetDepthStencilAccessAttachMask(ctx.rt_info^.DB_INFO.DEPTH_USAGE,ctx.rt_info^.DB_INFO.STENCIL_USAGE), GetDepthStencilSendLayout(ctx.rt_info^.DB_INFO.DEPTH_USAGE,ctx.rt_info^.DB_INFO.STENCIL_USAGE), ord(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) or ctx.rt_info^.DB_INFO.zorder_stage @@ -1295,8 +1367,7 @@ begin Bind_Uniforms(ctx, BP_GRAPHICS, - FUniformBuilder, - ctx.rt_info^.ShaderGroup); + FUniformBuilder); Bind_Pushs(ctx,ctx.rt_info^.ShaderGroup,@ctx.rt_info^.USERDATA); @@ -1318,16 +1389,17 @@ 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] - ); - - ri.mark_init; resource_instance:=ctx.node^.scope.find_image_resource_instance(ctx.rt_info^.RT_INFO[i].FImageInfo); + Assert(resource_instance<>nil); + ri:=TvImage2(resource_instance^.resource^.rimage); + + Assert(ri<>nil); + + ri.mark_init; + if (resource_instance^.next_overlap.mem_usage<>0) then begin pm4_write_back(ctx.Cmd,ri); @@ -1422,9 +1494,10 @@ begin if (resource^.rtype=R_IMG) then begin - ri:=FetchImage(ctx.Cmd, - resource^.rkey, - []); + ri:=TvImage2(resource^.rimage); + + Assert(ri<>nil); + // pm4_write_back(ctx.Cmd,ri); // @@ -1656,8 +1729,7 @@ begin Bind_Uniforms(ctx, BP_COMPUTE, - FUniformBuilder, - CP_KEY.FShaderGroup); + FUniformBuilder); Bind_Pushs(ctx,CP_KEY.FShaderGroup,dst); diff --git a/chip/pm4_stream.pas b/chip/pm4_stream.pas index 52476050..7172d906 100644 --- a/chip/pm4_stream.pas +++ b/chip/pm4_stream.pas @@ -130,10 +130,17 @@ const R_HTILE=2; type - t_pm4_usage=record - mem_usage:Integer; - img_usage:s_image_usage; + t_pm4_usage=packed record + case Byte of + 0:(DATA:QWORD); + 1:(mem_usage:Byte; + shd_usage:Byte; + clr_usage:Byte; + dsa_usage:Byte; + img_usage:s_image_usage + ); end; + {$IF sizeof(s_image_usage)<>4}{$STOP sizeof(s_image_usage)<>4}{$ENDIF} operator + (a,b:t_pm4_usage):t_pm4_usage; @@ -160,6 +167,8 @@ type rsize :DWORD; rkey :TvImageKey; // + rimage:TObject; + // rclear :Boolean; rwriteback:Boolean; // @@ -399,10 +408,10 @@ var // -operator + (a,b:t_pm4_usage):t_pm4_usage; +operator + (a,b:t_pm4_usage):t_pm4_usage; inline; begin - Result.mem_usage:=a.mem_usage or b.mem_usage; - Result.img_usage:=b.img_usage + b.img_usage; + //hack + Result.DATA:=a.DATA or b.DATA; end; // @@ -633,6 +642,8 @@ begin end; function t_pm4_resource_stream_scope.fetch_resource_instance(scope:p_pm4_resource_curr_scope;r:p_pm4_resource;mem_usage:Integer;img_usage:s_image_usage):p_pm4_resource_instance; +var + curr:t_pm4_usage; begin Result:=scope^.find_resource_instance(r); @@ -642,14 +653,29 @@ begin Result^:=Default(t_pm4_resource_instance); // Result^.resource:=r; - Result^.curr.mem_usage:=mem_usage; - Result^.curr.img_usage:=img_usage; - end else - begin - Result^.curr.mem_usage:=Result^.curr.mem_usage or mem_usage; - Result^.curr.img_usage:=Result^.curr.img_usage + img_usage; end; + curr.mem_usage:=mem_usage; + curr.shd_usage:=0; + curr.clr_usage:=0; + curr.dsa_usage:=0; + + if ([iu_sampled,iu_storage]*img_usage<>[]) then + begin + curr.shd_usage:=mem_usage; + end; + + if (iu_attachment in img_usage) then + begin + curr.clr_usage:=mem_usage; + end; + + if (iu_depthstenc in img_usage) then + begin + curr.dsa_usage:=mem_usage; + end; + + Result^.curr:=Result^.curr + curr; end; function t_pm4_resource_stream_scope.insert_image_resource(scope:p_pm4_resource_curr_scope;const rkey:TvImageKey;mem_usage:Integer;img_usage:s_image_usage):p_pm4_resource_instance; diff --git a/vulkan/vCmdBuffer.pas b/vulkan/vCmdBuffer.pas index c45f3738..629d171f 100644 --- a/vulkan/vCmdBuffer.pas +++ b/vulkan/vCmdBuffer.pas @@ -105,6 +105,7 @@ type Procedure BindPipeline(BindPoint:TVkPipelineBindPoint;F:TVkPipeline); Function IsRenderPass:Boolean; Procedure EndRenderPass; + function BeforePushBarrier:TVkCommandBuffer; function QueueSubmit:TVkResult; function Wait(timeout:TVkUInt64):TVkResult; @@ -470,6 +471,23 @@ begin end; end; +function TvCustomCmdBuffer.BeforePushBarrier:TVkCommandBuffer; +begin + Result:=0; + + if (Self=nil) then + begin + Writeln(stderr,'Self=nil,',{$I %LINE%}); + Exit; + end; + + if (not BeginCmdBuffer) then Exit; + + EndRenderPass; + + Result:=FCmdbuf; +end; + function TvCmdBuffer.BindCompute(CP:TvComputePipeline2):Boolean; begin Result:=False; diff --git a/vulkan/vImage.pas b/vulkan/vImage.pas index 4ea451be..2708763c 100644 --- a/vulkan/vImage.pas +++ b/vulkan/vImage.pas @@ -19,7 +19,7 @@ type PvImageBarrier=^TvImageBarrier; TvImageBarrier=object type - t_push_cb=procedure of object; + t_push_cb=function():TVkCommandBuffer of object; var //image:TVkImage; //range:TVkImageSubresourceRange; @@ -88,6 +88,7 @@ const TM_READ =1; TM_WRITE=2; TM_CLEAR=4; + TM_MIXED=8; type t_image_usage=(iu_attachment,iu_depthstenc,iu_sampled,iu_storage,iu_buffer,iu_htile); @@ -248,8 +249,9 @@ Function GetAspectMaskByFormat(cformat:TVkFormat):DWORD; Function GetDepthStencilInitLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout; Function GetDepthStencilSendLayout(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkImageLayout; -Function GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags; -Function GetColorAccessMask(IMAGE_USAGE:Byte):TVkAccessFlags; +Function GetDepthStencilAccessAttachMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags; +function GetColorSendLayout(IMAGE_USAGE:Byte):TVkImageLayout; +Function GetColorAccessAttachMask(IMAGE_USAGE:Byte):TVkAccessFlags; Function getFormatSize(cformat:TVkFormat):Byte; //in bytes function IsTexelFormat(cformat:TVkFormat):Boolean; @@ -1943,7 +1945,7 @@ begin end; end; -Function GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags; +Function GetDepthStencilAccessAttachMask(DEPTH_USAGE,STENCIL_USAGE:Byte):TVkAccessFlags; var IMAGE_USAGE:Byte; begin @@ -1953,7 +1955,18 @@ begin (ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)*ord((IMAGE_USAGE and (TM_WRITE or TM_CLEAR))<>0) ); end; -Function GetColorAccessMask(IMAGE_USAGE:Byte):TVkAccessFlags; +function GetColorSendLayout(IMAGE_USAGE:Byte):TVkImageLayout; +begin + if ((IMAGE_USAGE and TM_MIXED)<>0) then + begin + Result:=VK_IMAGE_LAYOUT_GENERAL; + end else + begin + Result:=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + end; +end; + +Function GetColorAccessAttachMask(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) ); @@ -1968,6 +1981,72 @@ begin StageMask :=ord(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); end; +function IsRead(dstAccessMask:TVkAccessFlags):Boolean; inline; +begin + Result:=dstAccessMask and + ( + ord(VK_ACCESS_INDIRECT_COMMAND_READ_BIT) or + ord(VK_ACCESS_INDEX_READ_BIT) or + ord(VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT) or + ord(VK_ACCESS_UNIFORM_READ_BIT) or + ord(VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) or + ord(VK_ACCESS_SHADER_READ_BIT) or + ord(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) or + ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) or + ord(VK_ACCESS_TRANSFER_READ_BIT) or + ord(VK_ACCESS_HOST_READ_BIT) or + ord(VK_ACCESS_MEMORY_READ_BIT) + )<>0; +end; + +function IsWrite(dstAccessMask:TVkAccessFlags):Boolean; inline; +begin + Result:=dstAccessMask and + ( + ord(VK_ACCESS_SHADER_WRITE_BIT) or + ord(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) or + ord(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) or + ord(VK_ACCESS_TRANSFER_WRITE_BIT) or + ord(VK_ACCESS_HOST_WRITE_BIT) or + ord(VK_ACCESS_MEMORY_WRITE_BIT) + )<>0; +end; + +const + ALL_GRAPHICS_STAGE:TVkPipelineStageFlags=( + ord(VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT) or + ord(VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT) or + ord(VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT) or + ord(VK_PIPELINE_STAGE_VERTEX_INPUT_BIT) or + ord(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) or + ord(VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT) or + ord(VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT) or + ord(VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) or + ord(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) or + ord(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT) or + ord(VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT) or + ord(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) or + ord(VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT) or + ord(VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT) or + ord(VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) or + ord(VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT) + ); + +function ChangeStage(curr,next:TVkPipelineStageFlags):Boolean; +begin + if ((curr and ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))<>0) then + begin + curr:=(curr and (not ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))) or ALL_GRAPHICS_STAGE; + end; + + if ((next and ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))<>0) then + begin + next:=(next and (not ord(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT))) or ALL_GRAPHICS_STAGE; + end; + + Result:=((curr and next)<>next); +end; + function TvImageBarrier.Push(cmd:TVkCommandBuffer; cb:t_push_cb; image:TVkImage; @@ -1980,17 +2059,29 @@ var begin Result:=False; - if (AccessMask<>dstAccessMask) or + //RAW + //WAR + //WAW + + if (AccessMask<>dstAccessMask ) or (ImgLayout <>newImageLayout) or - (StageMask <>dstStageMask) then + ChangeStage(StageMask,dstStageMask) or + + (IsRead (AccessMask) and IsWrite(dstAccessMask)) or + (IsWrite(AccessMask) and IsRead (dstAccessMask)) or + (IsWrite(AccessMask) and IsWrite(dstAccessMask)) + + then begin Result:=True; if (cb<>nil) then begin - cb(); + cmd:=cb(); end; + if (cmd=0) then Exit; + info:=Default(TVkImageMemoryBarrier); info.sType :=VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; info.srcAccessMask :=AccessMask; @@ -2003,7 +2094,7 @@ begin vkCmdPipelineBarrier(cmd, StageMask, dstStageMask, - 0, + ord(VK_DEPENDENCY_BY_REGION_BIT), 0, nil, 0, nil, 1, @info); diff --git a/vulkan/vImageManager.pas b/vulkan/vImageManager.pas index 66c7689a..6bf32a72 100644 --- a/vulkan/vImageManager.pas +++ b/vulkan/vImageManager.pas @@ -413,7 +413,7 @@ begin if (not cmd.BeginCmdBuffer) then Exit; if Barrier.Push(cmd.FCmdbuf, - @cmd.EndRenderPass, + @cmd.BeforePushBarrier, Parent.FHandle, GetSubresRange, dstAccessMask, @@ -689,7 +689,7 @@ begin rw_wlock(lock); if Barrier.Push(cmd.FCmdbuf, - @cmd.EndRenderPass, + @cmd.BeforePushBarrier, FHandle, GetSubresRange, dstAccessMask, diff --git a/vulkan/vRenderPassManager.pas b/vulkan/vRenderPassManager.pas index 33823184..6e496025 100644 --- a/vulkan/vRenderPassManager.pas +++ b/vulkan/vRenderPassManager.pas @@ -29,8 +29,8 @@ type Procedure SetZorderStage(s:TVkPipelineStageFlags); Procedure _AddColorRef(id:TVkUInt32;IMAGE_USAGE:Byte); Procedure _SetDepthRef(id:TVkUInt32;DEPTH_USAGE,STENCIL_USAGE:Byte); - Procedure AddColorAt(id:TVkUInt32;format:TVkFormat;IMAGE_USAGE,samples:Byte); - Procedure AddDepthAt(id:TVkUInt32;format:TVkFormat;DEPTH_USAGE,STENCIL_USAGE:Byte); + Procedure AddColorAt(id:TVkUInt32;aformat:TVkFormat;IMAGE_USAGE,asamples:Byte); + Procedure AddDepthAt(id:TVkUInt32;aformat:TVkFormat;DEPTH_USAGE,STENCIL_USAGE,asamples:Byte); end; TvRenderPass2=class(TvRenderPass) @@ -95,8 +95,23 @@ var am:TVkAccessFlags; begin if (RefCount>7) then Exit; - ColorRef[RefCount].attachment:=id; - ColorRef[RefCount].layout :=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL{VK_IMAGE_LAYOUT_GENERAL}; + + if (id<>VK_ATTACHMENT_UNUSED) then + begin + with ColorRef[RefCount] do + begin + attachment:=id; + layout:=GetColorSendLayout(IMAGE_USAGE); + end; + end else + begin + with ColorRef[RefCount] do + begin + attachment:=VK_ATTACHMENT_UNUSED; + layout:=VK_IMAGE_LAYOUT_UNDEFINED; + end; + end; + Inc(RefCount); if (id<>VK_ATTACHMENT_UNUSED) then @@ -104,7 +119,7 @@ begin 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); + am:=GetColorAccessAttachMask(IMAGE_USAGE); Dependency.srcAccessMask:=Dependency.srcAccessMask or am; Dependency.dstAccessMask:=Dependency.dstAccessMask or am; @@ -120,71 +135,92 @@ begin DepthRef.attachment:=id; DepthRef.layout :=GetDepthStencilSendLayout(DEPTH_USAGE,STENCIL_USAGE); - am:=GetDepthStencilAccessMask(DEPTH_USAGE,STENCIL_USAGE); + am:=GetDepthStencilAccessAttachMask(DEPTH_USAGE,STENCIL_USAGE); Dependency.srcAccessMask:=Dependency.srcAccessMask or am; Dependency.dstAccessMask:=Dependency.dstAccessMask or am; end; -Procedure TvRenderPassKey.AddColorAt(id:TVkUInt32;format:TVkFormat;IMAGE_USAGE,samples:Byte); +Procedure TvRenderPassKey.AddColorAt(id:TVkUInt32;aformat:TVkFormat;IMAGE_USAGE,asamples:Byte); begin if (AtdCount>8) then Exit; ColorAtd[AtdCount]:=Default(TVkAttachmentDescription); - ColorAtd[AtdCount].format :=format; - ColorAtd[AtdCount].samples:=TVkSampleCountFlagBits(samples); With ColorAtd[AtdCount] 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; + begin + format :=aformat; + samples:=TVkSampleCountFlagBits(asamples); - With ColorAtd[AtdCount] do - if ((IMAGE_USAGE and TM_WRITE)<>0) then - begin - storeOp:=VK_ATTACHMENT_STORE_OP_STORE; - end else + stencilLoadOp :=VK_ATTACHMENT_LOAD_OP_DONT_CARE; + stencilStoreOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE; + end; + + if (id<>VK_ATTACHMENT_UNUSED) then + begin + With ColorAtd[AtdCount] 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 ColorAtd[AtdCount] 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; + + With ColorAtd[AtdCount] do + if ((IMAGE_USAGE and TM_READ)<>0) then + begin + initialLayout:=GetColorSendLayout(IMAGE_USAGE); + end else + begin + initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED; + end; + + With ColorAtd[AtdCount] do + begin + finalLayout:=GetColorSendLayout(IMAGE_USAGE); + end; + end else + begin + With ColorAtd[AtdCount] do begin + loadOp :=VK_ATTACHMENT_LOAD_OP_DONT_CARE; storeOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE; - end; - ColorAtd[AtdCount].stencilLoadOp :=VK_ATTACHMENT_LOAD_OP_DONT_CARE; - ColorAtd[AtdCount].stencilStoreOp:=VK_ATTACHMENT_STORE_OP_DONT_CARE; - - With ColorAtd[AtdCount] do - if ((IMAGE_USAGE and TM_READ)<>0) then - begin - initialLayout:=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - end else - begin initialLayout:=VK_IMAGE_LAYOUT_UNDEFINED; + finalLayout :=VK_IMAGE_LAYOUT_UNDEFINED; end; - - With ColorAtd[AtdCount] do - begin - finalLayout:=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - end; + end; Inc(AtdCount); _AddColorRef(id,IMAGE_USAGE); end; -Procedure TvRenderPassKey.AddDepthAt(id:TVkUInt32;format:TVkFormat;DEPTH_USAGE,STENCIL_USAGE:Byte); +Procedure TvRenderPassKey.AddDepthAt(id:TVkUInt32;aformat:TVkFormat;DEPTH_USAGE,STENCIL_USAGE,asamples:Byte); begin if (AtdCount>8) then Exit; ColorAtd[AtdCount]:=Default(TVkAttachmentDescription); - ColorAtd[AtdCount].format :=format; - ColorAtd[AtdCount].samples:=VK_SAMPLE_COUNT_1_BIT; + + With ColorAtd[AtdCount] do + begin + format :=aformat; + samples:=TVkSampleCountFlagBits(asamples); + end; With ColorAtd[AtdCount] do if ((DEPTH_USAGE and TM_CLEAR)<>0) then