From 69f37626075c67e766ba6aa5dd752fe2ca16e8c3 Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Thu, 16 May 2024 15:08:20 +0300 Subject: [PATCH] + --- chip/pm4_me.pas | 63 ++++++++++++------------ gui/cfg_edit.lfm | 42 +++++++++++++++- gui/cfg_edit.pas | 3 ++ gui/game_info.pas | 11 +++++ gui/game_run.pas | 9 +++- gui/main.lfm | 6 +-- sys/dev/dev_dce.pas | 3 +- sys/dev/display_interface.pas | 10 ++-- sys/dev/display_soft.pas | 5 +- sys/jit/kern_jit.pas | 54 +++++++++++++-------- sys/jit/kern_jit_asm.pas | 35 +++++++++++--- sys/kern/kern_proc.pas | 4 +- sys/kern/kern_time.pas | 14 +++++- sys/md/md_time.pas | 49 ++++++++++++++++--- sys/time.pas | 3 ++ vulkan/vDevice.pas | 3 +- vulkan/vMemory.pas | 90 ++++++++++++++++++----------------- 17 files changed, 274 insertions(+), 130 deletions(-) diff --git a/chip/pm4_me.pas b/chip/pm4_me.pas index 18ef94cc..4dfddfb3 100644 --- a/chip/pm4_me.pas +++ b/chip/pm4_me.pas @@ -56,13 +56,35 @@ type end; var - use_renderdoc:Boolean=True; + use_renderdoc_capture:Boolean=False; implementation uses kern_dmem; +procedure StartFrameCapture; +begin + if use_renderdoc_capture then + begin + if (renderdoc.IsFrameCapturing()=0) then + begin + renderdoc.StartFrameCapture(0,0); + end; + end; +end; + +procedure EndFrameCapture; +begin + if use_renderdoc_capture then + begin + if (renderdoc.IsFrameCapturing()<>0) then + begin + renderdoc.EndFrameCapture(0,0); + end; + end; +end; + procedure t_pm4_me.Init; begin queue.Create; @@ -477,16 +499,7 @@ var r:TVkResult; begin - if use_renderdoc then - begin - renderdoc.LoadRenderDoc; - renderdoc.UnloadCrashHandler; - - if (renderdoc.IsTargetControlConnected<>0) then - begin - renderdoc.StartFrameCapture(0,0); - end; - end; + StartFrameCapture; // if (FCmdPool=nil) then @@ -534,11 +547,6 @@ begin CmdBuffer.ReleaseResource; CmdBuffer.Free; - - if use_renderdoc then - begin - renderdoc.EndFrameCapture(0,0); - end; end; procedure pm4_DrawIndexAuto(node:p_pm4_node_DrawIndexAuto); @@ -550,16 +558,7 @@ var r:TVkResult; begin - if use_renderdoc then - begin - renderdoc.LoadRenderDoc; - renderdoc.UnloadCrashHandler; - - if (renderdoc.IsTargetControlConnected<>0) then - begin - renderdoc.StartFrameCapture(0,0); - end; - end; + StartFrameCapture; // if (FCmdPool=nil) then @@ -606,15 +605,11 @@ begin CmdBuffer.ReleaseResource; CmdBuffer.Free; - - if use_renderdoc then - begin - renderdoc.EndFrameCapture(0,0); - end; end; procedure pm4_EventWriteEop(node:p_pm4_node_EventWriteEop); begin + EndFrameCapture; Case node^.dataSel of // @@ -635,6 +630,12 @@ var node:p_pm4_node; begin + if use_renderdoc_capture then + begin + renderdoc.LoadRenderDoc; + renderdoc.UnloadCrashHandler; + end; + repeat stream:=nil; diff --git a/gui/cfg_edit.lfm b/gui/cfg_edit.lfm index a30c6638..ec7a4c84 100644 --- a/gui/cfg_edit.lfm +++ b/gui/cfg_edit.lfm @@ -13,11 +13,11 @@ object frmCfgEditor: TfrmCfgEditor Height = 274 Top = 0 Width = 397 - ActivePage = Tab_MainInfo + ActivePage = Tab_Misc Align = alCustom Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Bottom = 10 - TabIndex = 0 + TabIndex = 3 TabOrder = 0 object Tab_MainInfo: TTabSheet Caption = 'Main' @@ -354,6 +354,44 @@ object frmCfgEditor: TfrmCfgEditor TabOrder = 3 end end + object Tab_Misc: TTabSheet + Caption = 'Misc' + ClientHeight = 246 + ClientWidth = 389 + object Edt_MiscInfo_strict_ps4_freq: TCheckBox + AnchorSideLeft.Control = Tab_Misc + AnchorSideTop.Control = Tab_Misc + AnchorSideRight.Control = Tab_Misc + AnchorSideRight.Side = asrBottom + Left = 10 + Height = 19 + Top = 10 + Width = 369 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 10 + BorderSpacing.Top = 10 + BorderSpacing.Right = 10 + Caption = 'Strict rdtsc timer frequency' + TabOrder = 0 + end + object Edt_MiscInfo_renderdoc_capture: TCheckBox + AnchorSideLeft.Control = Tab_Misc + AnchorSideTop.Control = Edt_MiscInfo_strict_ps4_freq + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Tab_Misc + AnchorSideRight.Side = asrBottom + Left = 10 + Height = 19 + Top = 39 + Width = 369 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 10 + BorderSpacing.Top = 10 + BorderSpacing.Right = 10 + Caption = 'Use renderdoc capture' + TabOrder = 1 + end + end end object BtnCancel: TButton AnchorSideLeft.Control = Owner diff --git a/gui/cfg_edit.pas b/gui/cfg_edit.pas index 88e90a3a..a973aacc 100644 --- a/gui/cfg_edit.pas +++ b/gui/cfg_edit.pas @@ -22,6 +22,7 @@ type BtnDataOpen: TButton; Edt_BootparamInfo_halt_on_exit: TCheckBox; Edt_JITInfo_debug_info: TCheckBox; + Edt_MiscInfo_strict_ps4_freq: TCheckBox; Edt_JITInfo_relative_analize: TCheckBox; Edt_JITInfo_print_asm: TCheckBox; Edt_BootparamInfo_print_guest_syscall: TCheckBox; @@ -34,9 +35,11 @@ type EditPages: TPageControl; Edt_MainInfo_system: TEdit; Edt_MainInfo_data: TEdit; + Edt_MiscInfo_renderdoc_capture: TCheckBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; + Tab_Misc: TTabSheet; Tab_JIT: TTabSheet; Tab_MainInfo: TTabSheet; Tab_BootparamInfo: TTabSheet; diff --git a/gui/game_info.pas b/gui/game_info.pas index dcb3c492..5aa5fce3 100644 --- a/gui/game_info.pas +++ b/gui/game_info.pas @@ -144,15 +144,26 @@ type Constructor Create; override; end; + TMiscInfo=class(TAbstractObject) + private + Fstrict_ps4_freq :Boolean; + Frenderdoc_capture:Boolean; + published + property strict_ps4_freq :Boolean read Fstrict_ps4_freq write Fstrict_ps4_freq; + property renderdoc_capture:Boolean read Frenderdoc_capture write Frenderdoc_capture; + end; + TConfigInfo=class(TAbstractObject) private FMainInfo :TMainInfo; FBootParamInfo:TBootParamInfo; FJITInfo :TJITInfo; + FMiscInfo :TMiscInfo; published property MainInfo :TMainInfo read FMainInfo write FMainInfo; property BootParamInfo:TBootParamInfo read FBootParamInfo write FBootParamInfo; property JITInfo :TJITInfo read FJITInfo write FJITInfo; + property MiscInfo :TMiscInfo read FMiscInfo write FMiscInfo; end; TGameInfo=class(TAbstractObject) diff --git a/gui/game_run.pas b/gui/game_run.pas index 1c527880..6cd49cc4 100644 --- a/gui/game_run.pas +++ b/gui/game_run.pas @@ -58,6 +58,9 @@ uses dev_dce, display_soft, + time, + pm4_me, + //internal libs ps4_libSceSystemService, ps4_libSceUserService, @@ -134,6 +137,8 @@ begin // + time.strict_ps4_freq :=ConfInfo.MiscInfo.strict_ps4_freq; + pm4_me.use_renderdoc_capture:=ConfInfo.MiscInfo.renderdoc_capture; end; procedure prepare(GameStartupInfo:TGameStartupInfo); SysV_ABI_CDecl; @@ -148,11 +153,11 @@ begin //re_init_tty; //init_tty:=@re_init_tty; + load_config(GameStartupInfo.FConfInfo); + //init all sys_init; - load_config(GameStartupInfo.FConfInfo); - if (p_host_ipc<>nil) then begin THostIpcConnect(p_host_ipc).thread_new; diff --git a/gui/main.lfm b/gui/main.lfm index 61edbfce..5fc8a131 100644 --- a/gui/main.lfm +++ b/gui/main.lfm @@ -6,10 +6,10 @@ object frmMain: TfrmMain Caption = 'fpPS4' ClientHeight = 343 ClientWidth = 623 - Position = poScreenCenter - LCLVersion = '3.99.0.0' OnCreate = FormCreate OnKeyDown = FormKeyDown + Position = poScreenCenter + LCLVersion = '3.2.0.0' object Pages: TPageControl Left = 0 Height = 275 @@ -85,8 +85,8 @@ object frmMain: TfrmMain Left = 79 Top = 2 ImageIndex = 0 - Style = tbsCheck OnClick = TBPlayClick + Style = tbsCheck end object TBPause: TToolButton Left = 147 diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas index a3ddd9b1..52a6851d 100644 --- a/sys/dev/dev_dce.pas +++ b/sys/dev/dev_dce.pas @@ -58,7 +58,6 @@ uses subr_backtrace, sys_vm_object, vm_pager, - md_time, kern_proc, kern_timeout; @@ -101,7 +100,7 @@ begin mtx_unlock(dce_mtx); - vblank_tsc:=rdtsc; + vblank_tsc:=rdtsc(); i:=vblank_count; vblank_count:=vblank_count+1; diff --git a/sys/dev/display_interface.pas b/sys/dev/display_interface.pas index 4a65f785..28ce3f0e 100644 --- a/sys/dev/display_interface.pas +++ b/sys/dev/display_interface.pas @@ -7,7 +7,7 @@ interface uses sys_event, kern_mtx, - md_time; + time; const //SceVideoOutPixelFormat @@ -192,12 +192,12 @@ begin last_status.flipArg :=submit^.flipArg; last_status.flipArg2 :=submit^.flipArg2; last_status.count :=last_status.count+1; - last_status.submitTsc :=rdtsc; + last_status.submitTsc :=rdtsc(); last_status.currentBuffer:=submit^.bufferIndex; knote_eventid(EVENTID_FLIP, submit^.flipArg); - last_status.tsc :=rdtsc; + last_status.tsc :=rdtsc(); last_status.processTime:=last_status.tsc; Result:=0; @@ -208,12 +208,12 @@ begin last_status.flipArg :=submit^.flipArg; last_status.flipArg2 :=submit^.flipArg2; last_status.count :=last_status.count+1; - last_status.submitTsc :=rdtsc; + last_status.submitTsc :=rdtsc(); last_status.currentBuffer:=submit^.bufferIndex; knote_eventid(EVENTID_FLIP, submit^.flipArg); - last_status.tsc :=rdtsc; + last_status.tsc :=rdtsc(); last_status.processTime:=last_status.tsc; Result:=0; diff --git a/sys/dev/display_soft.pas b/sys/dev/display_soft.pas index 52f8d012..f753f88e 100644 --- a/sys/dev/display_soft.pas +++ b/sys/dev/display_soft.pas @@ -8,7 +8,6 @@ uses LFQueue, display_interface, time, - md_time, kern_thr, kern_mtx; @@ -573,7 +572,7 @@ begin if (Node=nil) then Exit(EBUSY); Node^.submit:=submit^; - Node^.tsc :=rdtsc; + Node^.tsc :=rdtsc(); FQueue.FQueue.Push(Node); @@ -652,7 +651,7 @@ begin last_status.count :=last_status.count+1; last_status.submitTsc :=Node^.tsc; last_status.currentBuffer :=submit^.bufferIndex; - last_status.tsc :=rdtsc; + last_status.tsc :=rdtsc(); last_status.processTime :=last_status.tsc; mtx_unlock(mtx^); diff --git a/sys/jit/kern_jit.pas b/sys/jit/kern_jit.pas index 616c36ed..b1ed9da1 100644 --- a/sys/jit/kern_jit.pas +++ b/sys/jit/kern_jit.pas @@ -23,6 +23,7 @@ implementation uses sysutils, + time, vm_pmap_prot, vm_pmap, vm_map, @@ -134,9 +135,13 @@ label _cpuid_7, _cpuid_80000000, _cpuid_80000001, - _cpuid_80000008; + _cpuid_80000008, + _exit; asm - pushf + movq %rax, %r14 + seto %al + lahf + xchg %rax, %r14 cmp $0,%eax je _cpuid_0 @@ -157,14 +162,18 @@ asm je _cpuid_80000008 //unknow id - popf - mov %rax,%r15 + + xchg %r14, %rax + addb $127, %al + sahf + + mov %r14, %r15 call jit_save_ctx - mov %r14,%rdi - mov %r15,%rsi + mov %r14, %rdi + mov %r15, %rsi jmp _jit_cpuid - + //not reach _cpuid_0: @@ -176,8 +185,7 @@ asm mov $0x69746E65,%edx mov $0x444D4163,%ecx - popf - ret + jmp _exit _cpuid_1: @@ -204,8 +212,7 @@ asm or $0x00080800,%ebx //cpu_procinfo - popf - ret + jmp _exit _cpuid_7: @@ -214,8 +221,7 @@ asm mov $0x0,%edx mov $0x0,%ecx - popf - ret + jmp _exit _cpuid_80000000: @@ -227,8 +233,7 @@ asm mov $0x69746e65,%edx mov $0x444d4163,%ecx - popf - ret + jmp _exit _cpuid_80000001: @@ -237,8 +242,7 @@ asm mov $0x2fd3fbff,%edx //amd_feature mov $0x154837ff,%ecx //amd_feature2 - popf - ret + jmp _exit _cpuid_80000008: @@ -247,8 +251,12 @@ asm mov $0x00000000,%edx mov $0x00003007,%ecx //cpu_procinfo2 - popf - ret + _exit: + + xchg %r14, %rax + addb $127, %al + sahf + movq %r14, %rax end; @@ -1006,7 +1014,13 @@ end; procedure op_rdtsc(var ctx:t_jit_context2); begin - add_orig(ctx); + if time.strict_ps4_freq then + begin + ctx.builder.call_far(@strict_ps4_rdtsc_jit); + end else + begin + add_orig(ctx); + end; end; procedure op_nop(var ctx:t_jit_context2); diff --git a/sys/jit/kern_jit_asm.pas b/sys/jit/kern_jit_asm.pas index 3d2de186..8afe387a 100644 --- a/sys/jit/kern_jit_asm.pas +++ b/sys/jit/kern_jit_asm.pas @@ -62,9 +62,13 @@ procedure jit_load_ctx; procedure jit_save_to_sys_save(td:p_kthread); procedure sys_save_to_jit_save(td:p_kthread); +procedure strict_ps4_rdtsc_jit; assembler; + implementation uses + time, + md_time, trap, ucontext, md_context, @@ -77,12 +81,6 @@ function jmp_dispatcher(addr,plt,from:Pointer):Pointer; external; // -procedure jit_sigsegv(addr:Pointer); -begin - print_error_td('jit_sigsegv:0x'+HexStr(addr)); - Assert(False); -end; - procedure jit_simple_save_ctx; assembler; nostackframe; asm movqq %rdi, - kthread.td_frame.tf_r13 + kthread.td_frame.tf_rdi(%r13) @@ -574,6 +572,31 @@ asm jmp jit_jmp_dispatch end; +procedure strict_ps4_rdtsc_jit; assembler; nostackframe; +asm + seto %al + lahf + movq %rax, %r14 + // + rdtsc + // + shl $32, %rdx + or %rdx, %rax + // + mulq tsc_freq(%rip) + divq md_tsc_freq(%rip) + // + mov %rax, %rdx + shr $32, %rdx + shl $32, %rax + shr $32, %rax + // + xchg %r14, %rax + addb $127, %al + sahf + movq %r14, %rax +end; + function IS_JIT_FUNC(rip:qword):Boolean; public; begin Result:=( diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas index 9ff3259d..eeb20c97 100644 --- a/sys/kern/kern_proc.pas +++ b/sys/kern/kern_proc.pas @@ -77,7 +77,7 @@ implementation uses elf_machdep, - md_time; + time; // @@ -137,7 +137,7 @@ begin p_proc.p_randomized_path:='system'; - p_proc.p_ptc:=rdtsc; + p_proc.p_ptc:=rdtsc(); end; end. diff --git a/sys/kern/kern_time.pas b/sys/kern/kern_time.pas index c3328764..d4a5ea61 100644 --- a/sys/kern/kern_time.pas +++ b/sys/kern/kern_time.pas @@ -38,15 +38,25 @@ uses Procedure timeinit; begin md_timeinit; + // + if strict_ps4_freq then + begin + tsc_freq:=PS4_TSC_FREQ; + rdtsc :=@md_rdtsc_freq; + end else + begin + tsc_freq:=md_tsc_freq; + rdtsc :=@md_rdtsc; + end; + // getmicrouptime(@boottime); - tsc_freq:=get_rdtsc_freq; end; procedure getmicrouptime(tvp:p_timeval); var time:Int64; begin - time:=get_unit_uptime; + time:=md_rdtsc_unit(); tvp^.tv_sec :=(time div UNIT_PER_SEC); tvp^.tv_usec:=(time mod UNIT_PER_SEC) div 10; end; diff --git a/sys/md/md_time.pas b/sys/md/md_time.pas index f4a3d8ff..caa758db 100644 --- a/sys/md/md_time.pas +++ b/sys/md/md_time.pas @@ -10,10 +10,16 @@ uses ntapi, time; +var + md_tsc_freq :QWORD=0; + md_unit_freq:QWORD=UNIT_PER_SEC; + Procedure md_timeinit; -function rdtsc:QWORD; assembler; -function get_rdtsc_freq:QWORD; +function md_rdtsc:QWORD; assembler; +function md_rdtsc_unit:QWORD; assembler; +function md_rdtsc_freq:QWORD; assembler; +function md_get_rdtsc_freq:QWORD; function get_proc_time:Int64; function get_proc_time_freq:Int64; @@ -42,17 +48,46 @@ var begin NtQueryTimerResolution(@min,@max,@cur); NtSetTimerResolution(max,True,@cur); + // + md_tsc_freq:=md_get_rdtsc_freq; end; -function rdtsc:QWORD; assembler; nostackframe; +function md_rdtsc:QWORD; assembler; nostackframe; asm lfence rdtsc lfence + // shl $32,%rdx or %rdx,%rax end; +function md_rdtsc_unit:QWORD; assembler; nostackframe; +asm + lfence + rdtsc + lfence + // + shl $32,%rdx + or %rdx,%rax + // + mulq md_unit_freq(%rip) + divq md_tsc_freq (%rip) +end; + +function md_rdtsc_freq:QWORD; assembler; nostackframe; +asm + lfence + rdtsc + lfence + // + shl $32,%rdx + or %rdx,%rax + // + mulq tsc_freq(%rip) + divq md_tsc_freq(%rip) +end; + function _get_rdtsc_freq:QWORD; var shared_page:PQWORD; @@ -90,12 +125,12 @@ begin begin qpc_freq :=get_proc_time_freq; qpc_begin:=get_proc_time; - tsc_begin:=rdtsc; + tsc_begin:=md_rdtsc; Sleep(2); qpc_end:=get_proc_time; - tsc_end:=rdtsc; + tsc_end:=md_rdtsc; if (qpc_end<>qpc_begin) then begin @@ -108,7 +143,7 @@ begin Result:=tsc_freq; end; -function get_rdtsc_freq:QWORD; +function md_get_rdtsc_freq:QWORD; begin Result:=_get_rdtsc_freq; @@ -326,7 +361,7 @@ begin CLOCK_EXT_RAW_NETWORK: begin //nanouptime + time - time^:=get_unit_uptime; + time^:=md_rdtsc_unit; end; CLOCK_SECOND: diff --git a/sys/time.pas b/sys/time.pas index d950b356..5d1e8056 100644 --- a/sys/time.pas +++ b/sys/time.pas @@ -132,6 +132,9 @@ function itimerfix(tv:p_timeval):Integer; var boottime:timeval; tsc_freq:QWORD=0; + rdtsc :function:QWORD; SysV_ABI_CDecl; + + strict_ps4_freq:Boolean=False; implementation diff --git a/vulkan/vDevice.pas b/vulkan/vDevice.pas index ed79dee6..0190030c 100644 --- a/vulkan/vDevice.pas +++ b/vulkan/vDevice.pas @@ -524,8 +524,7 @@ begin For i:=0 to count-1 do begin - Write(getstr_queueFlags(pFamily[i].queueFlags)); - Writeln(':',pFamily[i].queueCount); + Writeln(getstr_queueFlags(pFamily[i].queueFlags),':',pFamily[i].queueCount); end; FreeMem(pFamily); diff --git a/vulkan/vMemory.pas b/vulkan/vMemory.pas index 8f1e59a9..01ad9035 100644 --- a/vulkan/vMemory.pas +++ b/vulkan/vMemory.pas @@ -327,6 +327,7 @@ end; Constructor TvMemManager.Create; var mr:TVkMemoryRequirements; + s:RawByteString; i:Byte; begin mr:=GetHostMappedRequirements; @@ -334,22 +335,35 @@ begin Writeln('[HostMappedRequirements]'); Writeln(' Alignment=',mr.alignment); - Write(' MemoryType='); + s:=''; For i:=0 to 31 do if ((1 shl i) and (mr.memoryTypeBits))<>0 then begin - Write(i,','); + if (s='') then + begin + s:=IntToStr(i); + end else + begin + s:=s+','+IntToStr(i); + end; end; - Writeln; + Writeln(' MemoryType=',S); FSparceMemoryTypes:=GetSparceMemoryTypes; - Write(' SparceType='); + + s:=''; For i:=0 to 31 do if ((1 shl i) and (FSparceMemoryTypes))<>0 then begin - Write(i,','); + if (s='') then + begin + s:=IntToStr(i); + end else + begin + s:=s+','+IntToStr(i); + end; end; - Writeln; + Writeln(' SparceType=',s); FProperties:=Default(TVkPhysicalDeviceMemoryProperties); vkGetPhysicalDeviceMemoryProperties(VulkanApp.FPhysicalDevice,@FProperties); @@ -528,52 +542,42 @@ end; procedure TvMemManager.PrintMemoryType(typeFilter:TVkUInt32); var + s:RawByteString; i:TVkUInt32; + + procedure append(TestFlag:TVkFlags;const name:RawByteString); inline; + begin + if ((FProperties.memoryTypes[i].propertyFlags and TestFlag)<>0) then + begin + if (s='') then + begin + s:=s+name; + end else + begin + s:=s+'|'+name; + end; + end; + end; + begin For i:=0 to FProperties.memoryTypeCount-1 do begin if ((typeFilter and (1 shl i))<>0) then begin - Write(i,':',HexStr(FProperties.memoryTypes[i].propertyFlags,8)); + s:=''; - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))<>0 then - Write(' DEVICE_LOCAL'); + append(ord(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ),'DEVICE_LOCAL'); + append(ord(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT ),'HOST_VISIBLE'); + append(ord(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ),'HOST_COHERENT'); + append(ord(VK_MEMORY_PROPERTY_HOST_CACHED_BIT ),'HOST_CACHED'); + append(ord(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT ),'LAZILY_ALLOCATED'); + append(ord(VK_MEMORY_PROPERTY_PROTECTED_BIT ),'PROTECTED'); + append(ord(VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD),'DEVICE_COHERENT_AMD'); + append(ord(VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD),'DEVICE_UNCACHED_AMD'); + append(ord(VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV ),'RDMA_CAPABLE_NV'); - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))<>0 then - Write(' HOST_VISIBLE'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))<>0 then - Write(' HOST_COHERENT'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_HOST_CACHED_BIT))<>0 then - Write(' HOST_CACHED'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT))<>0 then - Write(' LAZILY_ALLOCATED'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_PROTECTED_BIT))<>0 then - Write(' PROTECTED'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD))<>0 then - Write(' DEVICE_COHERENT_AMD'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD))<>0 then - Write(' DEVICE_UNCACHED_AMD'); - - if (FProperties.memoryTypes[i].propertyFlags and - TVkUInt32(VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV))<>0 then - Write(' RDMA_CAPABLE_NV'); - - Writeln; + Write(i,':',HexStr(FProperties.memoryTypes[i].propertyFlags,8),':',s); end; end;