diff --git a/appveyor.yml b/appveyor.yml index 6738ced..f338cff 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.1.9.build-{build} +version: 0.1.10.build-{build} image: Visual Studio 2019 environment: matrix: diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 8457075..6d60788 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD) set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000") endif() -project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.9) +project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.10) include(src_script.cmake) diff --git a/source/emulator/include/Emulator/Graphics/Graphics.h b/source/emulator/include/Emulator/Graphics/Graphics.h index be62dbf..20ccc23 100644 --- a/source/emulator/include/Emulator/Graphics/Graphics.h +++ b/source/emulator/include/Emulator/Graphics/Graphics.h @@ -11,18 +11,14 @@ namespace Kyty::Libs::Graphics { -namespace HW { -struct VsStageRegisters; -} // namespace HW - KYTY_SUBSYSTEM_DEFINE(Graphics); void GraphicsDbgDumpDcb(const char* type, uint32_t num_dw, uint32_t* cmd_buffer); namespace Gen4 { -int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier); -int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier); +int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const uint32_t* vs_regs, uint32_t shader_modifier); +int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const uint32_t* vs_regs, uint32_t shader_modifier); int KYTY_SYSV_ABI GraphicsSetPsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs); int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs); int KYTY_SYSV_ABI GraphicsUpdatePsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs); @@ -76,11 +72,29 @@ namespace Gen5 { struct Shader; struct CommandBuffer; struct ShaderRegister; +struct Label; -int KYTY_SYSV_ABI GraphicsInit(uint32_t* state, uint32_t ver); -void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2(uint32_t ver); -void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver); -int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatile void* code); +int KYTY_SYSV_ABI GraphicsInit(uint32_t* state, uint32_t ver); +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2(uint32_t ver); +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver); +int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatile void* code); +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs, const Shader* hs, const Shader* gs, + uint32_t prim_type); +int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs, const Shader* ps); +int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type); +int KYTY_SYSV_ABI GraphicsSuspendPoint(); + +uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset, const uint32_t* values, + uint32_t num_values); +uint32_t* KYTY_SYSV_ABI GraphicsCbReleaseMem(CommandBuffer* buf, uint8_t action, uint16_t gcr_cntl, uint8_t dst, uint8_t cache_policy, + const volatile Label* address, uint8_t data_sel, uint64_t data, uint16_t gds_offset, + uint16_t gds_size, uint8_t interrupt, uint32_t interrupt_ctx_id); uint32_t* KYTY_SYSV_ABI GraphicsDcbResetQueue(CommandBuffer* buf, uint32_t op, uint32_t state); uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf, uint32_t video_out_handle, uint32_t display_buffer_index); uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); @@ -88,20 +102,26 @@ uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegistersIndirect(CommandBuffer* buf, co uint32_t* KYTY_SYSV_ABI GraphicsDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); uint32_t* KYTY_SYSV_ABI GraphicsDcbSetIndexSize(CommandBuffer* buf, uint8_t index_size, uint8_t cache_policy); uint32_t* KYTY_SYSV_ABI GraphicsDcbDrawIndexAuto(CommandBuffer* buf, uint32_t index_count, uint64_t modifier); -int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); -int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); -int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); -int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); -int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); -int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); -int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs, const Shader* hs, const Shader* gs, - uint32_t prim_type); -int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs, const Shader* ps); -uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset, const uint32_t* values, - uint32_t num_values); -int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type); +uint32_t* KYTY_SYSV_ABI GraphicsDcbEventWrite(CommandBuffer* buf, uint8_t event_type, const volatile void* address); +uint32_t* KYTY_SYSV_ABI GraphicsDcbAcquireMem(CommandBuffer* buf, uint8_t engine, uint32_t cb_db_op, uint32_t gcr_cntl, + const volatile void* base, uint64_t size_bytes, uint32_t poll_cycles); +uint32_t* KYTY_SYSV_ABI GraphicsDcbWriteData(CommandBuffer* buf, uint8_t dst, uint8_t cache_policy, uint64_t address_or_offset, + const void* data, uint32_t num_dwords, uint8_t increment, uint8_t write_confirm); +uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitRegMem(CommandBuffer* buf, uint8_t size, uint8_t compare_function, uint8_t op, uint8_t cache_policy, + const volatile void* address, uint64_t reference, uint64_t mask, uint32_t poll_cycles); +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetFlip(CommandBuffer* buf, uint32_t video_out_handle, int32_t display_buffer_index, uint32_t flip_mode, + int64_t flip_arg); + } // namespace Gen5 +namespace Gen5Driver { + +struct Packet; + +int KYTY_SYSV_ABI GraphicsDriverSubmitDcb(const Packet* packet); + +} // namespace Gen5Driver + } // namespace Kyty::Libs::Graphics #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/include/Emulator/Graphics/GraphicsRender.h b/source/emulator/include/Emulator/Graphics/GraphicsRender.h index 9688ac3..92dabff 100644 --- a/source/emulator/include/Emulator/Graphics/GraphicsRender.h +++ b/source/emulator/include/Emulator/Graphics/GraphicsRender.h @@ -11,8 +11,9 @@ namespace Kyty::Libs::Graphics { namespace HW { -class HardwareContext; +class Context; class UserConfig; +class Shader; } // namespace HW class CommandProcessor; @@ -55,7 +56,6 @@ public: VulkanCommandPool* GetPool() { return m_pool; } [[nodiscard]] bool IsExecute() const { return m_execute; } - private: VulkanCommandPool* m_pool = nullptr; uint32_t m_index = static_cast(-1); @@ -67,9 +67,9 @@ private: void GraphicsRenderInit(); void GraphicsRenderCreateContext(); -void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, HW::UserConfig* ucfg, +void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::UserConfig* ucfg, HW::Shader* sh_ctx, uint32_t index_type_and_size, uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type); -void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, HW::UserConfig* ucfg, +void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::UserConfig* ucfg, HW::Shader* sh_ctx, uint32_t index_count, uint32_t flags); void GraphicsRenderWriteAtEndOfPipe64(uint64_t submit_id, CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value); void GraphicsRenderWriteAtEndOfPipeClockCounter(uint64_t submit_id, CommandBuffer* buffer, uint64_t* dst_gpu_addr); @@ -88,7 +88,7 @@ void GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBack64(uint64_t submit_id, void GraphicsRenderWriteAtEndOfPipeWithInterrupt64(uint64_t submit_id, CommandBuffer* buffer, uint64_t* dst_gpu_addr, uint64_t value); void GraphicsRenderWriteAtEndOfPipeWithInterrupt32(uint64_t submit_id, CommandBuffer* buffer, uint32_t* dst_gpu_addr, uint32_t value); void GraphicsRenderWriteBack(CommandProcessor* cp); -void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, uint32_t thread_group_x, +void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::Shader* sh_ctx, uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode); void GraphicsRenderMemoryBarrier(CommandBuffer* buffer); void GraphicsRenderRenderTextureBarrier(CommandBuffer* buffer, uint64_t vaddr, uint64_t size); diff --git a/source/emulator/include/Emulator/Graphics/HardwareContext.h b/source/emulator/include/Emulator/Graphics/HardwareContext.h index 6ebc1b1..a7b6781 100644 --- a/source/emulator/include/Emulator/Graphics/HardwareContext.h +++ b/source/emulator/include/Emulator/Graphics/HardwareContext.h @@ -204,18 +204,18 @@ struct RenderControl struct ClipControl { - uint32_t user_clip_planes = 0; - uint32_t user_clip_plane_mode = 0; - uint32_t clip_space = 0; - uint32_t vertex_kill_mode = 0; - uint32_t min_z_clip_enable = 0; - uint32_t max_z_clip_enable = 0; - bool user_clip_plane_negate_y = false; - bool clip_enable = false; - bool user_clip_plane_cull_only = false; - bool cull_on_clipping_error_disable = false; - bool linear_attribute_clip_enable = false; - bool force_viewport_index_from_vs_enable = false; + uint8_t user_clip_planes = 0; + uint8_t user_clip_plane_mode = 0; + bool dx_clip_space = false; + bool vertex_kill_any = false; + bool min_z_clip_disable = false; + bool max_z_clip_disable = false; + bool user_clip_plane_negate_y = false; + bool clip_disable = false; + bool user_clip_plane_cull_only = false; + bool cull_on_clipping_error_disable = false; + bool linear_attribute_clip_enable = false; + bool force_viewport_index_from_vs_enable = false; }; struct DepthControl @@ -318,6 +318,16 @@ struct AaSampleControl uint32_t locations[16] = {}; }; +struct DepthShaderControl +{ + uint32_t other_bits = 0; + uint8_t conservative_z_export_value = 0; + uint8_t shader_z_behavior = 0; + bool shader_kill_enable = false; + bool shader_z_export_enable = false; + bool shader_execute_on_noop = false; +}; + struct AaConfig { uint8_t msaa_num_samples = 0; @@ -371,10 +381,6 @@ struct VsStageRegisters uint32_t m_spiShaderPgmRsrc1Vs = 0; uint32_t m_spiShaderPgmRsrc2Vs = 0; - uint32_t m_spiVsOutConfig = 0; - uint32_t m_spiShaderPosFormat = 0; - uint32_t m_paClVsOutCntl = 0; - [[nodiscard]] uint64_t GetGpuAddress() const; [[nodiscard]] bool GetStreamoutEnabled() const; [[nodiscard]] uint32_t GetSgprCount() const; @@ -385,26 +391,12 @@ struct VsStageRegisters struct PsStageRegisters { - uint64_t data_addr = 0; - uint8_t vgprs = 0; - uint8_t sgprs = 0; - uint8_t scratch_en = 0; - uint8_t user_sgpr = 0; - uint8_t wave_cnt_en = 0; - uint32_t shader_z_format = 0; - uint8_t target_output_mode[8] = {}; - uint32_t ps_input_ena = 0; - uint32_t ps_input_addr = 0; - uint32_t ps_in_control = 0; - uint32_t baryc_cntl = 0; - - uint8_t conservative_z_export_value = 0; - uint8_t shader_z_behavior = 0; - bool shader_kill_enable = false; - bool shader_z_export_enable = false; - bool shader_execute_on_noop = false; - - uint32_t m_cbShaderMask = 0; + uint64_t data_addr = 0; + uint8_t vgprs = 0; + uint8_t sgprs = 0; + uint8_t scratch_en = 0; + uint8_t user_sgpr = 0; + uint8_t wave_cnt_en = 0; }; struct CsStageRegisters @@ -427,6 +419,42 @@ struct CsStageRegisters uint8_t lds_size = 0; }; +struct ShaderRegisters +{ + uint32_t m_spiVsOutConfig = 0; + uint32_t m_spiShaderPosFormat = 0; + uint32_t m_paClVsOutCntl = 0; + + uint32_t ps_interpolator_settings[32] = {0}; + // uint32_t ps_input_num = 0; + + uint32_t m_spiShaderIdxFormat = 0; + uint32_t m_geNggSubgrpCntl = 0; + uint32_t m_vgtGsInstanceCnt = 0; + uint32_t m_vgtGsOnchipCntl = 0; + uint32_t m_geMaxOutputPerSubgroup = 0; + uint32_t m_vgtEsgsRingItemsize = 0; + uint32_t m_vgtGsMaxVertOut = 0; + uint32_t m_vgtGsOutPrimType = 0; + + uint32_t shader_z_format = 0; + uint8_t target_output_mode[8] = {}; + uint32_t ps_input_ena = 0; + uint32_t ps_input_addr = 0; + uint32_t ps_in_control = 0; + uint32_t baryc_cntl = 0; + uint32_t m_cbShaderMask = 0; + + uint32_t m_paScShaderControl = 0; + + DepthShaderControl db_shader_control; + + [[nodiscard]] uint32_t GetExportCount() const { return 1u + ((m_spiVsOutConfig >> 1u) & 0x1Fu); } + [[nodiscard]] uint32_t GetEsVertsPerSubgrp() const { return (m_vgtGsOnchipCntl >> 0u) & 0x7FFu; } + [[nodiscard]] uint32_t GetGsPrimsPerSubgrp() const { return (m_vgtGsOnchipCntl >> 11u) & 0x7FFu; } + [[nodiscard]] uint32_t GetGsInstPrimsInSubgrp() const { return (m_vgtGsOnchipCntl >> 22u) & 0x3FFu; } +}; + enum class UserSgprType { Unknown, @@ -453,8 +481,6 @@ struct VertexShaderInfo struct PixelShaderInfo { PsStageRegisters ps_regs; - uint32_t ps_interpolator_settings[32] = {0}; - uint32_t ps_input_num = 0; UserSgprInfo ps_user_sgpr; uint32_t ps_embedded_id = 0; bool ps_embedded = false; @@ -467,15 +493,15 @@ struct ComputeShaderInfo UserSgprInfo cs_user_sgpr; }; -class HardwareContext +class Context { public: - HardwareContext() = default; - virtual ~HardwareContext() = default; + Context() = default; + virtual ~Context() = default; - KYTY_CLASS_DEFAULT_COPY(HardwareContext); + KYTY_CLASS_DEFAULT_COPY(Context); - void Reset() { *this = HardwareContext(); } + void Reset() { *this = Context(); } void SetColorBase(uint32_t slot, const ColorBase& base) { m_render_targets[slot].base = base; } void SetColorPitch(uint32_t slot, const ColorPitch& pitch) { m_render_targets[slot].pitch = pitch; } @@ -554,56 +580,6 @@ public: } [[nodiscard]] const ScreenViewport& GetScreenViewport() const { return m_screen_viewport; } - void SetVsShader(const VsStageRegisters* vs_regs, uint32_t shader_modifier) - { - m_vs.vs_regs = *vs_regs; - m_vs.vs_shader_modifier = shader_modifier; - m_vs.vs_embedded = false; - } - void UpdateVsShader(const VsStageRegisters* vs_regs, uint32_t shader_modifier) - { - m_vs.vs_regs.m_spiShaderPgmLoVs = vs_regs->m_spiShaderPgmLoVs; - m_vs.vs_regs.m_spiShaderPgmHiVs = vs_regs->m_spiShaderPgmHiVs; - m_vs.vs_regs.m_spiShaderPgmRsrc1Vs = vs_regs->m_spiShaderPgmRsrc1Vs; - m_vs.vs_regs.m_spiShaderPgmRsrc2Vs = vs_regs->m_spiShaderPgmRsrc2Vs; - m_vs.vs_shader_modifier = shader_modifier; - m_vs.vs_embedded = false; - } - void SetVsEmbedded(uint32_t id, uint32_t shader_modifier) - { - m_vs.vs_embedded_id = id; - m_vs.vs_shader_modifier = shader_modifier; - m_vs.vs_embedded = true; - } - - void SetPsShader(const PsStageRegisters* ps_regs) - { - m_ps.ps_regs = *ps_regs; - m_ps.ps_embedded = false; - } - void UpdatePsShader(const PsStageRegisters* ps_regs) - { - m_ps.ps_regs.data_addr = ps_regs->data_addr; - m_ps.ps_regs.vgprs = ps_regs->vgprs; - m_ps.ps_regs.sgprs = ps_regs->sgprs; - m_ps.ps_regs.scratch_en = ps_regs->scratch_en; - m_ps.ps_regs.user_sgpr = ps_regs->user_sgpr; - m_ps.ps_regs.wave_cnt_en = ps_regs->wave_cnt_en; - m_ps.ps_regs.shader_z_format = ps_regs->shader_z_format; - m_ps.ps_embedded = false; - } - void SetPsEmbedded(uint32_t id) - { - m_ps.ps_embedded_id = id; - m_ps.ps_embedded = true; - } - - void SetCsShader(const CsStageRegisters* cs_regs, uint32_t shader_modifier) - { - m_cs.cs_regs = *cs_regs; - m_cs.cs_shader_modifier = shader_modifier; - } - [[nodiscard]] const BlendColor& GetBlendColor() const { return m_blend_color; } void SetBlendColor(const BlendColor& color) { m_blend_color = color; } [[nodiscard]] const ClipControl& GetClipControl() const { return m_clip_control; } @@ -629,6 +605,153 @@ public: [[nodiscard]] const AaConfig& GetAaConfig() const { return m_aa_config; } void SetAaConfig(const AaConfig& config) { m_aa_config = config; } + [[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; } + void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; } + [[nodiscard]] uint8_t GetStencilClearValue() const { return m_stencil_clear_value; } + void SetStencilClearValue(uint8_t clear_value) { m_stencil_clear_value = clear_value; } + + [[nodiscard]] float GetLineWidth() const { return m_line_width; } + void SetLineWidth(float width) { m_line_width = width; } + + [[nodiscard]] const ShaderRegisters& GetShaderRegisters() const { return m_sh_regs; } + + void SetVsOutConfig(uint32_t value) { m_sh_regs.m_spiVsOutConfig = value; } + void SetShaderPosFormat(uint32_t value) { m_sh_regs.m_spiShaderPosFormat = value; } + void SetClVsOutCntl(uint32_t value) { m_sh_regs.m_paClVsOutCntl = value; } + void SetShaderIdxFormat(uint32_t value) { m_sh_regs.m_spiShaderIdxFormat = value; } + void SetNggSubgrpCntl(uint32_t value) { m_sh_regs.m_geNggSubgrpCntl = value; } + void SetGsInstanceCnt(uint32_t value) { m_sh_regs.m_vgtGsInstanceCnt = value; } + void SetGsOnchipCntl(uint32_t value) { m_sh_regs.m_vgtGsOnchipCntl = value; } + void SetMaxOutputPerSubgroup(uint32_t value) { m_sh_regs.m_geMaxOutputPerSubgroup = value; } + void SetEsgsRingItemsize(uint32_t value) { m_sh_regs.m_vgtEsgsRingItemsize = value; } + void SetGsMaxVertOut(uint32_t value) { m_sh_regs.m_vgtGsMaxVertOut = value; } + void SetGsOutPrimType(uint32_t value) { m_sh_regs.m_vgtGsOutPrimType = value; } + + void SetPsInputSettings(uint32_t id, uint32_t value) + { + m_sh_regs.ps_interpolator_settings[id] = value; + // m_sh_regs.ps_input_num = ((id + 1) > m_sh_regs.ps_input_num ? (id + 1) : m_sh_regs.ps_input_num); + } + + void SetShaderZFormat(uint32_t value) { m_sh_regs.shader_z_format = value; } + void SetTargetOutputMode(uint32_t slot, uint8_t value) { m_sh_regs.target_output_mode[slot] = value; } + void SetPsInputEna(uint32_t value) { m_sh_regs.ps_input_ena = value; } + void SetPsInputAddr(uint32_t value) { m_sh_regs.ps_input_addr = value; } + void SetPsInControl(uint32_t value) { m_sh_regs.ps_in_control = value; } + void SetBarycCntl(uint32_t value) { m_sh_regs.baryc_cntl = value; } + void SetShaderMask(uint32_t value) { m_sh_regs.m_cbShaderMask = value; } + void SetDepthShaderControl(const DepthShaderControl& value) { m_sh_regs.db_shader_control = value; } + + void SetScShaderControl(uint32_t value) { m_sh_regs.m_paScShaderControl = value; } + +private: + float m_line_width = 1.0f; + + BlendControl m_blend_control[8]; + BlendColor m_blend_color; + RenderTarget m_render_targets[8]; + uint32_t m_render_target_mask = 0; + ScreenViewport m_screen_viewport; + ClipControl m_clip_control; + ColorControl m_color_control; + ScanModeControl m_scan_mode_control; + + AaSampleControl m_aa_sample_control; + AaConfig m_aa_config; + + uint32_t m_shader_stages = 0; + + DepthRenderTarget m_depth_render_target; + RenderControl m_render_control; + DepthControl m_depth_control; + StencilControl m_stencil_control; + StencilMask m_stencil_mask; + float m_depth_clear_value = 0.0f; + uint8_t m_stencil_clear_value = 0; + + ModeControl m_mode_control; + EqaaControl m_eqaa_control; + + ShaderRegisters m_sh_regs; +}; + +class UserConfig +{ +public: + UserConfig() = default; + virtual ~UserConfig() = default; + + KYTY_CLASS_DEFAULT_COPY(UserConfig); + + void Reset() { *this = UserConfig(); } + + void SetPrimitiveType(uint32_t prim_type) { m_prim_type = prim_type; } + [[nodiscard]] uint32_t GetPrimType() const { return m_prim_type; } + +private: + uint32_t m_prim_type = 0; +}; + +class Shader +{ +public: + Shader() = default; + virtual ~Shader() = default; + + KYTY_CLASS_DEFAULT_COPY(Shader); + + void Reset() { *this = Shader(); } + + void SetVsShader(const VsStageRegisters& vs_regs, uint32_t shader_modifier) + { + m_vs.vs_regs = vs_regs; + m_vs.vs_shader_modifier = shader_modifier; + m_vs.vs_embedded = false; + } + + void UpdateVsShader(const VsStageRegisters& vs_regs, uint32_t shader_modifier) + { + m_vs.vs_regs.m_spiShaderPgmLoVs = vs_regs.m_spiShaderPgmLoVs; + m_vs.vs_regs.m_spiShaderPgmHiVs = vs_regs.m_spiShaderPgmHiVs; + m_vs.vs_regs.m_spiShaderPgmRsrc1Vs = vs_regs.m_spiShaderPgmRsrc1Vs; + m_vs.vs_regs.m_spiShaderPgmRsrc2Vs = vs_regs.m_spiShaderPgmRsrc2Vs; + m_vs.vs_shader_modifier = shader_modifier; + m_vs.vs_embedded = false; + } + void SetVsEmbedded(uint32_t id, uint32_t shader_modifier) + { + m_vs.vs_embedded_id = id; + m_vs.vs_shader_modifier = shader_modifier; + m_vs.vs_embedded = true; + } + + void SetPsShader(const PsStageRegisters& ps_regs) + { + m_ps.ps_regs = ps_regs; + m_ps.ps_embedded = false; + } + void UpdatePsShader(const PsStageRegisters& ps_regs) + { + m_ps.ps_regs.data_addr = ps_regs.data_addr; + m_ps.ps_regs.vgprs = ps_regs.vgprs; + m_ps.ps_regs.sgprs = ps_regs.sgprs; + m_ps.ps_regs.scratch_en = ps_regs.scratch_en; + m_ps.ps_regs.user_sgpr = ps_regs.user_sgpr; + m_ps.ps_regs.wave_cnt_en = ps_regs.wave_cnt_en; + m_ps.ps_embedded = false; + } + void SetPsEmbedded(uint32_t id) + { + m_ps.ps_embedded_id = id; + m_ps.ps_embedded = true; + } + + void SetCsShader(const CsStageRegisters& cs_regs, uint32_t shader_modifier) + { + m_cs.cs_regs = cs_regs; + m_cs.cs_shader_modifier = shader_modifier; + } + void SetVsUserSgpr(uint32_t id, uint32_t value, UserSgprType type) { m_vs.vs_user_sgpr.value[id] = value; @@ -647,71 +770,15 @@ public: m_cs.cs_user_sgpr.type[id] = type; m_cs.cs_user_sgpr.count = ((id + 1) > m_cs.cs_user_sgpr.count ? (id + 1) : m_cs.cs_user_sgpr.count); } - void SetPsInputSettings(uint32_t id, uint32_t value) - { - m_ps.ps_interpolator_settings[id] = value; - m_ps.ps_input_num = ((id + 1) > m_ps.ps_input_num ? (id + 1) : m_ps.ps_input_num); - } [[nodiscard]] const PixelShaderInfo& GetPs() const { return m_ps; } [[nodiscard]] const VertexShaderInfo& GetVs() const { return m_vs; } [[nodiscard]] const ComputeShaderInfo& GetCs() const { return m_cs; } - [[nodiscard]] float GetDepthClearValue() const { return m_depth_clear_value; } - void SetDepthClearValue(float clear_value) { m_depth_clear_value = clear_value; } - [[nodiscard]] uint8_t GetStencilClearValue() const { return m_stencil_clear_value; } - void SetStencilClearValue(uint8_t clear_value) { m_stencil_clear_value = clear_value; } - - [[nodiscard]] float GetLineWidth() const { return m_line_width; } - void SetLineWidth(float width) { m_line_width = width; } - private: - float m_line_width = 1.0f; - - BlendControl m_blend_control[8]; - BlendColor m_blend_color; - RenderTarget m_render_targets[8]; - uint32_t m_render_target_mask = 0; - ScreenViewport m_screen_viewport; - ClipControl m_clip_control; - ColorControl m_color_control; - ScanModeControl m_scan_mode_control; - - AaSampleControl m_aa_sample_control; - AaConfig m_aa_config; - VertexShaderInfo m_vs; PixelShaderInfo m_ps; ComputeShaderInfo m_cs; - uint32_t m_shader_stages = 0; - - DepthRenderTarget m_depth_render_target; - RenderControl m_render_control; - DepthControl m_depth_control; - StencilControl m_stencil_control; - StencilMask m_stencil_mask; - float m_depth_clear_value = 0.0f; - uint8_t m_stencil_clear_value = 0; - - ModeControl m_mode_control; - EqaaControl m_eqaa_control; -}; - -class UserConfig -{ -public: - UserConfig() = default; - virtual ~UserConfig() = default; - - KYTY_CLASS_DEFAULT_COPY(UserConfig); - - void Reset() { *this = UserConfig(); } - - void SetPrimitiveType(uint32_t prim_type) { m_prim_type = prim_type; } - [[nodiscard]] uint32_t GetPrimType() const { return m_prim_type; } - -private: - uint32_t m_prim_type = 0; }; inline uint64_t VsStageRegisters::GetGpuAddress() const diff --git a/source/emulator/include/Emulator/Graphics/Pm4.h b/source/emulator/include/Emulator/Graphics/Pm4.h index 62f7bf6..23bd33c 100644 --- a/source/emulator/include/Emulator/Graphics/Pm4.h +++ b/source/emulator/include/Emulator/Graphics/Pm4.h @@ -14,8 +14,9 @@ class File; #define KYTY_PM4_GET(u, r, f) (((u) >> Pm4::r##_##f##_SHIFT) & Pm4::r##_##f##_MASK) #define KYTY_PM4(len, op, r) \ - (0xC0000000u | (((static_cast(len) - 2u) & 0x3fffu) << 16u) | (((op)&0xffu) << 8u) | (((r)&0x3fu) << 2u)) + (0xC0000000u | (((static_cast(len) - 2u) & 0x3fffu) << 16u) | (((op)&0xffu) << 8u) | (((r) & (Pm4::R_NUM - 1u)) << 2u)) +#define KYTY_PM4_R(cmd_id) (((cmd_id) >> 2u) & (Pm4::R_NUM - 1u)) #define KYTY_PM4_LEN(cmd_id) ((((cmd_id) >> 16u) & 0x3fffu) + 2u) namespace Kyty::Libs::Graphics::Pm4 { @@ -69,26 +70,37 @@ constexpr uint32_t IT_WAIT_ON_DE_COUNTER_DIFF = 0x88; constexpr uint32_t IT_DISPATCH_DRAW_PREAMBLE = 0x8C; constexpr uint32_t IT_DISPATCH_DRAW = 0x8D; -constexpr uint32_t R_ZERO = 0x00; -constexpr uint32_t R_VS = 0x01; -constexpr uint32_t R_PS = 0x02; -constexpr uint32_t R_DRAW_INDEX = 0x03; -constexpr uint32_t R_DRAW_INDEX_AUTO = 0x04; -constexpr uint32_t R_DRAW_RESET = 0x05; -constexpr uint32_t R_WAIT_FLIP_DONE = 0x06; -constexpr uint32_t R_CS = 0x07; -constexpr uint32_t R_DISPATCH_DIRECT = 0x08; -constexpr uint32_t R_DISPATCH_RESET = 0x09; -constexpr uint32_t R_DISPATCH_WAIT_MEM = 0x0A; -constexpr uint32_t R_PUSH_MARKER = 0x0B; -constexpr uint32_t R_POP_MARKER = 0x0C; -constexpr uint32_t R_VS_EMBEDDED = 0x0D; -constexpr uint32_t R_PS_EMBEDDED = 0x0E; -constexpr uint32_t R_VS_UPDATE = 0x0F; -constexpr uint32_t R_PS_UPDATE = 0x10; -constexpr uint32_t R_SH_REGS = 0x11; -constexpr uint32_t R_CX_REGS = 0x12; -constexpr uint32_t R_UC_REGS = 0x13; +/* Custom codes. Implemented via IT_NOP */ + +constexpr uint32_t R_ZERO = 0x00; +constexpr uint32_t R_VS = 0x01; +constexpr uint32_t R_PS = 0x02; +constexpr uint32_t R_DRAW_INDEX = 0x03; +constexpr uint32_t R_DRAW_INDEX_AUTO = 0x04; +constexpr uint32_t R_DRAW_RESET = 0x05; +constexpr uint32_t R_WAIT_FLIP_DONE = 0x06; +constexpr uint32_t R_CS = 0x07; +constexpr uint32_t R_DISPATCH_DIRECT = 0x08; +constexpr uint32_t R_DISPATCH_RESET = 0x09; +constexpr uint32_t R_WAIT_MEM_32 = 0x0A; +constexpr uint32_t R_PUSH_MARKER = 0x0B; +constexpr uint32_t R_POP_MARKER = 0x0C; +constexpr uint32_t R_VS_EMBEDDED = 0x0D; +constexpr uint32_t R_PS_EMBEDDED = 0x0E; +constexpr uint32_t R_VS_UPDATE = 0x0F; +constexpr uint32_t R_PS_UPDATE = 0x10; +constexpr uint32_t R_SH_REGS_INDIRECT = 0x11; +constexpr uint32_t R_CX_REGS_INDIRECT = 0x12; +constexpr uint32_t R_UC_REGS_INDIRECT = 0x13; +constexpr uint32_t R_ACQUIRE_MEM = 0x14; +constexpr uint32_t R_WRITE_DATA = 0x15; +constexpr uint32_t R_WAIT_MEM_64 = 0x16; +constexpr uint32_t R_FLIP = 0x17; +constexpr uint32_t R_RELEASE_MEM = 0x18; + +constexpr uint32_t R_NUM = 0x3F + 1; + +/* Context registers */ constexpr uint32_t DB_RENDER_CONTROL = 0x0; constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_SHIFT = 0; @@ -106,14 +118,21 @@ constexpr uint32_t DB_RENDER_CONTROL_COPY_CENTROID_MASK = 0x1; constexpr uint32_t DB_RENDER_CONTROL_COPY_SAMPLE_SHIFT = 8; constexpr uint32_t DB_RENDER_CONTROL_COPY_SAMPLE_MASK = 0xF; +constexpr uint32_t DB_COUNT_CONTROL = 0x1; + constexpr uint32_t DB_DEPTH_VIEW = 0x2; constexpr uint32_t DB_DEPTH_VIEW_SLICE_START_SHIFT = 0; constexpr uint32_t DB_DEPTH_VIEW_SLICE_START_MASK = 0x7FF; constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_SHIFT = 13; constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_MASK = 0x7FF; -constexpr uint32_t DB_HTILE_DATA_BASE = 0x5; -constexpr uint32_t DB_DEPTH_SIZE_XY = 0x7; +constexpr uint32_t DB_RENDER_OVERRIDE = 0x3; +constexpr uint32_t DB_RENDER_OVERRIDE2 = 0x4; +constexpr uint32_t DB_HTILE_DATA_BASE = 0x5; +constexpr uint32_t PS_SHADER_SAMPLE_EXCLUSION_MASK = 0x6; +constexpr uint32_t DB_DEPTH_SIZE_XY = 0x7; +constexpr uint32_t DB_DEPTH_BOUNDS_MIN = 0x8; +constexpr uint32_t DB_DEPTH_BOUNDS_MAX = 0x9; constexpr uint32_t DB_STENCIL_CLEAR = 0xA; constexpr uint32_t DB_STENCIL_CLEAR_CLEAR_SHIFT = 0; @@ -135,6 +154,8 @@ constexpr uint32_t PA_SC_SCREEN_SCISSOR_BR_BR_X_MASK = 0xFFFF; constexpr uint32_t PA_SC_SCREEN_SCISSOR_BR_BR_Y_SHIFT = 16; constexpr uint32_t PA_SC_SCREEN_SCISSOR_BR_BR_Y_MASK = 0xFFFF; +constexpr uint32_t DB_DFSM_CONTROL = 0xE; + constexpr uint32_t DB_DEPTH_INFO = 0xF; constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_SHIFT = 0; constexpr uint32_t DB_DEPTH_INFO_ADDR5_SWIZZLE_MASK_MASK = 0xF; @@ -171,15 +192,10 @@ constexpr uint32_t DB_STENCIL_INFO_TILE_MODE_INDEX_MASK = 0x7; constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_SHIFT = 29; constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_MASK = 0x1; -constexpr uint32_t DB_Z_READ_BASE = 0x12; -constexpr uint32_t DB_STENCIL_READ_BASE = 0x13; -constexpr uint32_t DB_Z_WRITE_BASE = 0x14; -constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15; -constexpr uint32_t DB_Z_READ_BASE_HI = 0x1A; -constexpr uint32_t DB_STENCIL_READ_BASE_HI = 0x1B; -constexpr uint32_t DB_Z_WRITE_BASE_HI = 0x1C; -constexpr uint32_t DB_STENCIL_WRITE_BASE_HI = 0x1D; -constexpr uint32_t DB_HTILE_DATA_BASE_HI = 0x1E; +constexpr uint32_t DB_Z_READ_BASE = 0x12; +constexpr uint32_t DB_STENCIL_READ_BASE = 0x13; +constexpr uint32_t DB_Z_WRITE_BASE = 0x14; +constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15; constexpr uint32_t DB_DEPTH_SIZE = 0x16; constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_SHIFT = 0; @@ -191,6 +207,30 @@ constexpr uint32_t DB_DEPTH_SLICE = 0x17; constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_SHIFT = 0; constexpr uint32_t DB_DEPTH_SLICE_SLICE_TILE_MAX_MASK = 0x3FFFFF; +constexpr uint32_t DB_Z_READ_BASE_HI = 0x1A; +constexpr uint32_t DB_STENCIL_READ_BASE_HI = 0x1B; +constexpr uint32_t DB_Z_WRITE_BASE_HI = 0x1C; +constexpr uint32_t DB_STENCIL_WRITE_BASE_HI = 0x1D; +constexpr uint32_t DB_HTILE_DATA_BASE_HI = 0x1E; +constexpr uint32_t DB_RMI_L2_CACHE_CONTROL = 0x1F; +constexpr uint32_t TA_BC_BASE_ADDR = 0x20; +constexpr uint32_t TA_BC_BASE_ADDR_HI = 0x21; +constexpr uint32_t PA_SC_WINDOW_OFFSET = 0x80; +constexpr uint32_t PA_SC_WINDOW_SCISSOR_TL = 0x81; +constexpr uint32_t PA_SC_WINDOW_SCISSOR_BR = 0x82; +constexpr uint32_t PA_SC_CLIPRECT_RULE = 0x83; +constexpr uint32_t PA_SC_CLIPRECT_0_TL = 0x84; +constexpr uint32_t PA_SC_CLIPRECT_0_BR = 0x85; + +constexpr uint32_t PA_SU_HARDWARE_SCREEN_OFFSET = 0x8D; +constexpr uint32_t PA_SU_HARDWARE_SCREEN_OFFSET_HW_SCREEN_OFFSET_X_SHIFT = 0; +constexpr uint32_t PA_SU_HARDWARE_SCREEN_OFFSET_HW_SCREEN_OFFSET_X_MASK = 0x1FF; +constexpr uint32_t PA_SU_HARDWARE_SCREEN_OFFSET_HW_SCREEN_OFFSET_Y_SHIFT = 16; +constexpr uint32_t PA_SU_HARDWARE_SCREEN_OFFSET_HW_SCREEN_OFFSET_Y_MASK = 0x1FF; + +constexpr uint32_t CB_TARGET_MASK = 0x8E; +constexpr uint32_t CB_SHADER_MASK = 0x8F; + constexpr uint32_t PA_SC_GENERIC_SCISSOR_TL = 0x90; constexpr uint32_t PA_SC_GENERIC_SCISSOR_TL_TL_X_SHIFT = 0; constexpr uint32_t PA_SC_GENERIC_SCISSOR_TL_TL_X_MASK = 0x7FFF; @@ -205,12 +245,21 @@ constexpr uint32_t PA_SC_GENERIC_SCISSOR_BR_BR_X_MASK = 0x7FFF; constexpr uint32_t PA_SC_GENERIC_SCISSOR_BR_BR_Y_SHIFT = 16; constexpr uint32_t PA_SC_GENERIC_SCISSOR_BR_BR_Y_MASK = 0x7FFF; -constexpr uint32_t PA_SC_VPORT_ZMIN_0 = 0xB4; - -constexpr uint32_t CB_BLEND_RED = 0x105; -constexpr uint32_t CB_BLEND_GREEN = 0x106; -constexpr uint32_t CB_BLEND_BLUE = 0x107; -constexpr uint32_t CB_BLEND_ALPHA = 0x108; +constexpr uint32_t PA_SC_VPORT_SCISSOR_0_TL = 0x94; +constexpr uint32_t PA_SC_VPORT_SCISSOR_0_BR = 0x95; +constexpr uint32_t PA_SC_VPORT_ZMIN_0 = 0xB4; +constexpr uint32_t PA_SC_VPORT_ZMAX_0 = 0xB5; +constexpr uint32_t PA_SC_RIGHT_VERT_GRID = 0xE8; +constexpr uint32_t PA_SC_LEFT_VERT_GRID = 0xE9; +constexpr uint32_t PA_SC_HORIZ_GRID = 0xEA; +constexpr uint32_t PA_SC_FOV_WINDOW_LR = 0xEB; +constexpr uint32_t PA_SC_FOV_WINDOW_TB = 0xEC; +constexpr uint32_t CB_RMI_GL2_CACHE_CONTROL = 0x104; +constexpr uint32_t CB_BLEND_RED = 0x105; +constexpr uint32_t CB_BLEND_GREEN = 0x106; +constexpr uint32_t CB_BLEND_BLUE = 0x107; +constexpr uint32_t CB_BLEND_ALPHA = 0x108; +constexpr uint32_t CB_DCC_CONTROL = 0x109; constexpr uint32_t DB_STENCIL_CONTROL = 0x10B; constexpr uint32_t DB_STENCIL_CONTROL_STENCILFAIL_SHIFT = 0; @@ -246,9 +295,29 @@ constexpr uint32_t DB_STENCILREFMASK_BF_STENCILWRITEMASK_BF_MASK = 0xFF; constexpr uint32_t DB_STENCILREFMASK_BF_STENCILOPVAL_BF_SHIFT = 24; constexpr uint32_t DB_STENCILREFMASK_BF_STENCILOPVAL_BF_MASK = 0xFF; -constexpr uint32_t PA_CL_VPORT_XSCALE = 0x10F; - -constexpr uint32_t SPI_PS_INPUT_CNTL_0 = 0x191; +constexpr uint32_t PA_CL_VPORT_XSCALE = 0x10F; +constexpr uint32_t PA_CL_VPORT_XOFFSET = 0x110; +constexpr uint32_t PA_CL_VPORT_YSCALE = 0x111; +constexpr uint32_t PA_CL_VPORT_YOFFSET = 0x112; +constexpr uint32_t PA_CL_VPORT_ZSCALE = 0x113; +constexpr uint32_t PA_CL_VPORT_ZOFFSET = 0x114; +constexpr uint32_t PA_CL_UCP_0_X = 0x16F; +constexpr uint32_t PA_CL_UCP_0_Y = 0x170; +constexpr uint32_t PA_CL_UCP_0_Z = 0x171; +constexpr uint32_t PA_CL_UCP_0_W = 0x172; +constexpr uint32_t SPI_PS_INPUT_CNTL_0 = 0x191; +constexpr uint32_t SPI_PS_INPUT_CNTL_31 = 0x1B0; +constexpr uint32_t SPI_VS_OUT_CONFIG = 0x1B1; +constexpr uint32_t SPI_PS_INPUT_ENA = 0x1B3; +constexpr uint32_t SPI_PS_INPUT_ADDR = 0x1B4; +constexpr uint32_t SPI_INTERP_CONTROL_0 = 0x1B5; +constexpr uint32_t SPI_PS_IN_CONTROL = 0x1B6; +constexpr uint32_t SPI_BARYC_CNTL = 0x1B8; +constexpr uint32_t SPI_TMPRING_SIZE = 0x1BA; +constexpr uint32_t SPI_SHADER_IDX_FORMAT = 0x1C2; +constexpr uint32_t SPI_SHADER_POS_FORMAT = 0x1C3; +constexpr uint32_t SPI_SHADER_Z_FORMAT = 0x1C4; +constexpr uint32_t SPI_SHADER_COL_FORMAT = 0x1C5; constexpr uint32_t CB_BLEND0_CONTROL = 0x1E0; constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT = 0; @@ -268,6 +337,8 @@ constexpr uint32_t CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_MASK = 0x1; constexpr uint32_t CB_BLEND0_CONTROL_ENABLE_SHIFT = 30; constexpr uint32_t CB_BLEND0_CONTROL_ENABLE_MASK = 0x1; +constexpr uint32_t GE_MAX_OUTPUT_PER_SUBGROUP = 0x1FF; + constexpr uint32_t DB_DEPTH_CONTROL = 0x200; constexpr uint32_t DB_DEPTH_CONTROL_STENCIL_ENABLE_SHIFT = 0; constexpr uint32_t DB_DEPTH_CONTROL_STENCIL_ENABLE_MASK = 0x1; @@ -304,12 +375,56 @@ constexpr uint32_t DB_EQAA_INTERPOLATE_COMP_Z_MASK = 0x1; constexpr uint32_t DB_EQAA_STATIC_ANCHOR_ASSOCIATIONS_SHIFT = 20; constexpr uint32_t DB_EQAA_STATIC_ANCHOR_ASSOCIATIONS_MASK = 0x1; +constexpr uint32_t DB_SHADER_CONTROL = 0x203; +constexpr uint32_t DB_SHADER_CONTROL_Z_EXPORT_ENABLE_SHIFT = 0; +constexpr uint32_t DB_SHADER_CONTROL_Z_EXPORT_ENABLE_MASK = 0x1; +constexpr uint32_t DB_SHADER_CONTROL_Z_ORDER_SHIFT = 4; +constexpr uint32_t DB_SHADER_CONTROL_Z_ORDER_MASK = 0x3; +constexpr uint32_t DB_SHADER_CONTROL_KILL_ENABLE_SHIFT = 6; +constexpr uint32_t DB_SHADER_CONTROL_KILL_ENABLE_MASK = 0x1; +constexpr uint32_t DB_SHADER_CONTROL_EXEC_ON_NOOP_SHIFT = 10; +constexpr uint32_t DB_SHADER_CONTROL_EXEC_ON_NOOP_MASK = 0x1; +constexpr uint32_t DB_SHADER_CONTROL_CONSERVATIVE_Z_EXPORT_SHIFT = 13; +constexpr uint32_t DB_SHADER_CONTROL_CONSERVATIVE_Z_EXPORT_MASK = 0x3; + constexpr uint32_t CB_COLOR_CONTROL = 0x202; constexpr uint32_t CB_COLOR_CONTROL_MODE_SHIFT = 4; constexpr uint32_t CB_COLOR_CONTROL_MODE_MASK = 0x7; constexpr uint32_t CB_COLOR_CONTROL_ROP3_SHIFT = 16; constexpr uint32_t CB_COLOR_CONTROL_ROP3_MASK = 0xFF; +constexpr uint32_t PA_CL_CLIP_CNTL = 0x204; +constexpr uint32_t PA_CL_CLIP_CNTL_UCP_ENA_SHIFT = 0; +constexpr uint32_t PA_CL_CLIP_CNTL_UCP_ENA_MASK = 0x3F; +constexpr uint32_t PA_CL_CLIP_CNTL_PS_UCP_Y_SCALE_NEG_SHIFT = 13; +constexpr uint32_t PA_CL_CLIP_CNTL_PS_UCP_Y_SCALE_NEG_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_PS_UCP_MODE_SHIFT = 14; +constexpr uint32_t PA_CL_CLIP_CNTL_PS_UCP_MODE_MASK = 0x3; +constexpr uint32_t PA_CL_CLIP_CNTL_CLIP_DISABLE_SHIFT = 16; +constexpr uint32_t PA_CL_CLIP_CNTL_CLIP_DISABLE_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_UCP_CULL_ONLY_ENA_SHIFT = 17; +constexpr uint32_t PA_CL_CLIP_CNTL_UCP_CULL_ONLY_ENA_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_BOUNDARY_EDGE_FLAG_ENA_SHIFT = 18; +constexpr uint32_t PA_CL_CLIP_CNTL_BOUNDARY_EDGE_FLAG_ENA_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF_SHIFT = 19; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_DIS_CLIP_ERR_DETECT_SHIFT = 20; +constexpr uint32_t PA_CL_CLIP_CNTL_DIS_CLIP_ERR_DETECT_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_VTX_KILL_OR_SHIFT = 21; +constexpr uint32_t PA_CL_CLIP_CNTL_VTX_KILL_OR_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_RASTERIZATION_KILL_SHIFT = 22; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_RASTERIZATION_KILL_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_LINEAR_ATTR_CLIP_ENA_SHIFT = 24; +constexpr uint32_t PA_CL_CLIP_CNTL_DX_LINEAR_ATTR_CLIP_ENA_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_VTE_VPORT_PROVOKE_DISABLE_SHIFT = 25; +constexpr uint32_t PA_CL_CLIP_CNTL_VTE_VPORT_PROVOKE_DISABLE_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_NEAR_DISABLE_SHIFT = 26; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_NEAR_DISABLE_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_FAR_DISABLE_SHIFT = 27; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_FAR_DISABLE_MASK = 0x1; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_PROG_NEAR_ENA_SHIFT = 28; +constexpr uint32_t PA_CL_CLIP_CNTL_ZCLIP_PROG_NEAR_ENA_MASK = 0x1; + constexpr uint32_t PA_SU_SC_MODE_CNTL = 0x205; constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_FRONT_SHIFT = 0; constexpr uint32_t PA_SU_SC_MODE_CNTL_CULL_FRONT_MASK = 0x1; @@ -334,10 +449,21 @@ constexpr uint32_t PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST_MASK = 0x1; constexpr uint32_t PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS_SHIFT = 20; constexpr uint32_t PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS_MASK = 0x1; +constexpr uint32_t PA_CL_VTE_CNTL = 0x206; +constexpr uint32_t PA_CL_VS_OUT_CNTL = 0x207; +constexpr uint32_t PA_SU_SMALL_PRIM_FILTER_CNTL = 0x20C; +constexpr uint32_t PA_CL_OBJPRIM_ID_CNTL = 0x20D; +constexpr uint32_t PA_STEREO_CNTL = 0x210; +constexpr uint32_t PA_STATE_STEREO_X = 0x211; +constexpr uint32_t PA_SU_POINT_SIZE = 0x280; +constexpr uint32_t PA_SU_POINT_MINMAX = 0x281; + constexpr uint32_t PA_SU_LINE_CNTL = 0x282; constexpr uint32_t PA_SU_LINE_CNTL_WIDTH_SHIFT = 0; constexpr uint32_t PA_SU_LINE_CNTL_WIDTH_MASK = 0xFFFF; +constexpr uint32_t VGT_GS_ONCHIP_CNTL = 0x291; + constexpr uint32_t PA_SC_MODE_CNTL_0 = 0x292; constexpr uint32_t PA_SC_MODE_CNTL_0_MSAA_ENABLE_SHIFT = 0; constexpr uint32_t PA_SC_MODE_CNTL_0_MSAA_ENABLE_MASK = 0x1; @@ -346,7 +472,13 @@ constexpr uint32_t PA_SC_MODE_CNTL_0_VPORT_SCISSOR_ENABLE_MASK = 0x1; constexpr uint32_t PA_SC_MODE_CNTL_0_LINE_STIPPLE_ENABLE_SHIFT = 2; constexpr uint32_t PA_SC_MODE_CNTL_0_LINE_STIPPLE_ENABLE_MASK = 0x1; -constexpr uint32_t VGT_GS_OUT_PRIM_TYPE = 0x29B; +constexpr uint32_t PA_SC_MODE_CNTL_1 = 0x293; +constexpr uint32_t VGT_GS_OUT_PRIM_TYPE = 0x29B; +constexpr uint32_t VGT_PRIMITIVEID_EN = 0x2A1; +constexpr uint32_t VGT_PRIMITIVEID_RESET = 0x2A3; +constexpr uint32_t VGT_DRAW_PAYLOAD_CNTL = 0x2A6; +constexpr uint32_t VGT_ESGS_RING_ITEMSIZE = 0x2AB; +constexpr uint32_t VGT_REUSE_OFF = 0x2AD; constexpr uint32_t DB_HTILE_SURFACE = 0x2AF; constexpr uint32_t DB_HTILE_SURFACE_LINEAR_SHIFT = 0; @@ -364,9 +496,24 @@ constexpr uint32_t DB_HTILE_SURFACE_PREFETCH_HEIGHT_MASK = 0x3F; constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_SHIFT = 16; constexpr uint32_t DB_HTILE_SURFACE_DST_OUTSIDE_ZERO_TO_ONE_MASK = 0x1; -constexpr uint32_t VGT_SHADER_STAGES_EN = 0x2D5; - -constexpr uint32_t PA_SC_CENTROID_PRIORITY_0 = 0x2F5; +constexpr uint32_t DB_SRESULTS_COMPARE_STATE0 = 0x2B0; +constexpr uint32_t DB_SRESULTS_COMPARE_STATE1 = 0x2B1; +constexpr uint32_t VGT_GS_MAX_VERT_OUT = 0x2CE; +constexpr uint32_t GE_NGG_SUBGRP_CNTL = 0x2D3; +constexpr uint32_t VGT_TESS_DISTRIBUTION = 0x2D4; +constexpr uint32_t VGT_SHADER_STAGES_EN = 0x2D5; +constexpr uint32_t VGT_LS_HS_CONFIG = 0x2D6; +constexpr uint32_t VGT_TF_PARAM = 0x2DB; +constexpr uint32_t DB_ALPHA_TO_MASK = 0x2DC; +constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x2DE; +constexpr uint32_t PA_SU_POLY_OFFSET_CLAMP = 0x2DF; +constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_SCALE = 0x2E0; +constexpr uint32_t PA_SU_POLY_OFFSET_FRONT_OFFSET = 0x2E1; +constexpr uint32_t PA_SU_POLY_OFFSET_BACK_SCALE = 0x2E2; +constexpr uint32_t PA_SU_POLY_OFFSET_BACK_OFFSET = 0x2E3; +constexpr uint32_t VGT_GS_INSTANCE_CNT = 0x2E4; +constexpr uint32_t PA_SC_CENTROID_PRIORITY_0 = 0x2F5; +constexpr uint32_t PA_SC_CENTROID_PRIORITY_1 = 0x2F6; constexpr uint32_t PA_SC_AA_CONFIG = 0x2F8; constexpr uint32_t PA_SC_AA_CONFIG_MSAA_NUM_SAMPLES_SHIFT = 0; @@ -378,24 +525,52 @@ constexpr uint32_t PA_SC_AA_CONFIG_MAX_SAMPLE_DIST_MASK = 0xF; constexpr uint32_t PA_SC_AA_CONFIG_MSAA_EXPOSED_SAMPLES_SHIFT = 20; constexpr uint32_t PA_SC_AA_CONFIG_MSAA_EXPOSED_SAMPLES_MASK = 0x7; -constexpr uint32_t PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 = 0x2FE; +constexpr uint32_t PA_SU_VTX_CNTL = 0x2F9; +constexpr uint32_t PA_CL_GB_VERT_CLIP_ADJ = 0x2FA; +constexpr uint32_t PA_CL_GB_VERT_DISC_ADJ = 0x2FB; +constexpr uint32_t PA_CL_GB_HORZ_CLIP_ADJ = 0x2FC; +constexpr uint32_t PA_CL_GB_HORZ_DISC_ADJ = 0x2FD; +constexpr uint32_t PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 = 0x2FE; +constexpr uint32_t PA_SC_AA_MASK_X0Y0_X1Y0 = 0x30E; +constexpr uint32_t PA_SC_AA_MASK_X0Y1_X1Y1 = 0x30F; +constexpr uint32_t PA_SC_SHADER_CONTROL = 0x310; +constexpr uint32_t PA_SC_BINNER_CNTL_0 = 0x311; +constexpr uint32_t PA_SC_BINNER_CNTL_1 = 0x312; +constexpr uint32_t PA_SC_CONSERVATIVE_RASTERIZATION_CNTL = 0x313; +constexpr uint32_t PA_SC_NGG_MODE_CNTL = 0x314; +constexpr uint32_t CB_COLOR0_BASE = 0x318; +constexpr uint32_t CB_COLOR0_VIEW = 0x31B; +constexpr uint32_t CB_COLOR0_INFO = 0x31C; +constexpr uint32_t CB_COLOR0_ATTRIB = 0x31D; +constexpr uint32_t CB_COLOR0_DCC_CONTROL = 0x31E; +constexpr uint32_t CB_COLOR0_CMASK = 0x31F; +constexpr uint32_t CB_COLOR0_FMASK = 0x321; +constexpr uint32_t CB_COLOR0_CLEAR_WORD0 = 0x323; +constexpr uint32_t CB_COLOR0_CLEAR_WORD1 = 0x324; +constexpr uint32_t CB_COLOR0_DCC_BASE = 0x325; +constexpr uint32_t CB_COLOR0_BASE_EXT = 0x390; +constexpr uint32_t CB_COLOR0_CMASK_BASE_EXT = 0x398; +constexpr uint32_t CB_COLOR0_FMASK_BASE_EXT = 0x3A0; +constexpr uint32_t CB_COLOR0_DCC_BASE_EXT = 0x3A8; +constexpr uint32_t CB_COLOR0_ATTRIB2 = 0x3B0; +constexpr uint32_t CB_COLOR0_ATTRIB3 = 0x3B8; -constexpr uint32_t CB_COLOR0_BASE = 0x318; -constexpr uint32_t CB_COLOR0_VIEW = 0x31B; -constexpr uint32_t CB_COLOR0_INFO = 0x31C; -constexpr uint32_t CB_COLOR0_ATTRIB = 0x31D; -constexpr uint32_t CB_COLOR0_DCC_CONTROL = 0x31E; -constexpr uint32_t CB_COLOR0_CMASK = 0x31F; -constexpr uint32_t CB_COLOR0_FMASK = 0x321; -constexpr uint32_t CB_COLOR0_CLEAR_WORD0 = 0x323; -constexpr uint32_t CB_COLOR0_CLEAR_WORD1 = 0x324; -constexpr uint32_t CB_COLOR0_DCC_BASE = 0x325; -constexpr uint32_t CB_COLOR0_BASE_EXT = 0x390; -constexpr uint32_t CB_COLOR0_CMASK_BASE_EXT = 0x398; -constexpr uint32_t CB_COLOR0_FMASK_BASE_EXT = 0x3A0; -constexpr uint32_t CB_COLOR0_DCC_BASE_EXT = 0x3A8; -constexpr uint32_t CB_COLOR0_ATTRIB2 = 0x3B0; -constexpr uint32_t CB_COLOR0_ATTRIB3 = 0x3B8; +/* Fake codes. Don't exist on real HW */ + +constexpr uint32_t FSR_RECURSIONS0 = 0x800003FC; +constexpr uint32_t FSR_RECURSIONS1 = 0x800003FD; +constexpr uint32_t PA_SC_FSR_ENABLE = 0x800003FE; +constexpr uint32_t CX_NOP = 0x800003FF; + +constexpr uint32_t CX_NUM = 0x3FF + 1; + +/* Shader registers */ + +constexpr uint32_t SPI_SHADER_PGM_RSRC4_PS = 0x1; +constexpr uint32_t SPI_SHADER_PGM_CHKSUM_PS = 0x6; +constexpr uint32_t SPI_SHADER_PGM_RSRC3_PS = 0x7; +constexpr uint32_t SPI_SHADER_PGM_LO_PS = 0x8; +constexpr uint32_t SPI_SHADER_PGM_HI_PS = 0x9; constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS = 0xA; constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT = 0; @@ -411,11 +586,42 @@ constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK = 0x1F; constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT = 7; constexpr uint32_t SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK = 0x0; -constexpr uint32_t SPI_SHADER_USER_DATA_PS_0 = 0xC; -constexpr uint32_t SPI_SHADER_USER_DATA_PS_15 = 0x1B; - -constexpr uint32_t SPI_SHADER_USER_DATA_VS_0 = 0x4C; -constexpr uint32_t SPI_SHADER_USER_DATA_VS_15 = 0x5B; +constexpr uint32_t SPI_SHADER_USER_DATA_PS_0 = 0xC; +constexpr uint32_t SPI_SHADER_USER_DATA_PS_15 = 0x1B; +constexpr uint32_t SPI_SHADER_USER_ACCUM_PS_0 = 0x32; +constexpr uint32_t SPI_SHADER_USER_DATA_VS_0 = 0x4C; +constexpr uint32_t SPI_SHADER_USER_DATA_VS_15 = 0x5B; +constexpr uint32_t SPI_SHADER_PGM_CHKSUM_GS = 0x80; +constexpr uint32_t SPI_SHADER_PGM_RSRC4_GS = 0x81; +constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_LO_GS = 0x82; +constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_HI_GS = 0x83; +constexpr uint32_t SPI_SHADER_PGM_RSRC3_GS = 0x87; +constexpr uint32_t SPI_SHADER_PGM_LO_GS = 0x88; +constexpr uint32_t SPI_SHADER_PGM_HI_GS = 0x89; +constexpr uint32_t SPI_SHADER_PGM_RSRC1_GS = 0x8A; +constexpr uint32_t SPI_SHADER_PGM_RSRC2_GS = 0x8B; +constexpr uint32_t SPI_SHADER_USER_DATA_GS_0 = 0x8C; +constexpr uint32_t SPI_SHADER_USER_ACCUM_ESGS_0 = 0xB2; +constexpr uint32_t SPI_SHADER_PGM_LO_ES = 0xC8; +constexpr uint32_t SPI_SHADER_PGM_HI_ES = 0xC9; +constexpr uint32_t SPI_SHADER_PGM_CHKSUM_HS = 0x100; +constexpr uint32_t SPI_SHADER_PGM_RSRC4_HS = 0x101; +constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_LO_HS = 0x102; +constexpr uint32_t SPI_SHADER_USER_DATA_ADDR_HI_HS = 0x103; +constexpr uint32_t SPI_SHADER_PGM_RSRC3_HS = 0x107; +constexpr uint32_t SPI_SHADER_PGM_LO_HS = 0x108; +constexpr uint32_t SPI_SHADER_PGM_HI_HS = 0x109; +constexpr uint32_t SPI_SHADER_PGM_RSRC1_HS = 0x10A; +constexpr uint32_t SPI_SHADER_PGM_RSRC2_HS = 0x10B; +constexpr uint32_t SPI_SHADER_USER_DATA_HS_0 = 0x10C; +constexpr uint32_t SPI_SHADER_USER_ACCUM_LSHS_0 = 0x132; +constexpr uint32_t SPI_SHADER_PGM_LO_LS = 0x148; +constexpr uint32_t SPI_SHADER_PGM_HI_LS = 0x149; +constexpr uint32_t COMPUTE_START_X = 0x204; +constexpr uint32_t COMPUTE_START_Y = 0x205; +constexpr uint32_t COMPUTE_START_Z = 0x206; +constexpr uint32_t COMPUTE_PGM_LO = 0x20C; +constexpr uint32_t COMPUTE_PGM_HI = 0x20D; constexpr uint32_t COMPUTE_PGM_RSRC1 = 0x212; constexpr uint32_t COMPUTE_PGM_RSRC1_VGPRS_SHIFT = 0; @@ -443,14 +649,62 @@ constexpr uint32_t COMPUTE_PGM_RSRC2_TIDIG_COMP_CNT_MASK = 0x3; constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_SHIFT = 15; constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_MASK = 0x1FF; -constexpr uint32_t COMPUTE_USER_DATA_0 = 0x240; -constexpr uint32_t COMPUTE_USER_DATA_15 = 0x24F; +constexpr uint32_t COMPUTE_RESOURCE_LIMITS = 0x215; +constexpr uint32_t COMPUTE_DESTINATION_EN_SE0 = 0x216; +constexpr uint32_t COMPUTE_DESTINATION_EN_SE1 = 0x217; +constexpr uint32_t COMPUTE_TMPRING_SIZE = 0x218; +constexpr uint32_t COMPUTE_DESTINATION_EN_SE2 = 0x219; +constexpr uint32_t COMPUTE_DESTINATION_EN_SE3 = 0x21A; +constexpr uint32_t COMPUTE_USER_ACCUM_0 = 0x224; +constexpr uint32_t COMPUTE_PGM_RSRC3 = 0x228; +constexpr uint32_t COMPUTE_SHADER_CHKSUM = 0x22A; +constexpr uint32_t COMPUTE_USER_DATA_0 = 0x240; +constexpr uint32_t COMPUTE_USER_DATA_15 = 0x24F; +constexpr uint32_t COMPUTE_DISPATCH_TUNNEL = 0x27D; + +/* Fake codes. Don't exist on real HW */ + +constexpr uint32_t SH_NOP = 0x800002FF; + +constexpr uint32_t SH_NUM = 0x2FF + 1; /* User config registers */ -constexpr uint32_t GE_CNTL = 0x25b; -constexpr uint32_t GE_USER_VGPR_EN = 0x262; -constexpr uint32_t PRIMITIVE_TYPE = 0x242; +constexpr uint32_t VGT_PRIMITIVE_TYPE = 0x242; +constexpr uint32_t VGT_OBJECT_ID = 0x248; +constexpr uint32_t GE_INDX_OFFSET = 0x24A; +constexpr uint32_t GE_MULTI_PRIM_IB_RESET_EN = 0x24B; +constexpr uint32_t VGT_HS_OFFCHIP_PARAM = 0x24F; +constexpr uint32_t VGT_TF_MEMORY_BASE = 0x250; +constexpr uint32_t GE_CNTL = 0x25B; +constexpr uint32_t GE_USER_VGPR1 = 0x25C; +constexpr uint32_t GE_USER_VGPR2 = 0x25D; +constexpr uint32_t GE_USER_VGPR3 = 0x25E; +constexpr uint32_t GE_STEREO_CNTL = 0x25F; +constexpr uint32_t GE_USER_VGPR_EN = 0x262; +constexpr uint32_t TA_CS_BC_BASE_ADDR = 0x380; +constexpr uint32_t TA_CS_BC_BASE_ADDR_HI = 0x381; +constexpr uint32_t TEXTURE_GRADIENT_FACTORS = 0x382; +constexpr uint32_t GDS_OA_CNTL = 0x41D; +constexpr uint32_t GDS_OA_COUNTER = 0x41E; +constexpr uint32_t GDS_OA_ADDRESS = 0x41F; + +/* Fake codes. Don't exist on real HW */ + +constexpr uint32_t FSR_EXTEND_SUBPIXEL_ROUNDING = 0x80003FF4; +constexpr uint32_t FSR_ALPHA_VALUE0 = 0x80003FF5; +constexpr uint32_t FSR_ALPHA_VALUE1 = 0x80003FF6; +constexpr uint32_t FSR_CONTROL_POINT0 = 0x80003FF7; +constexpr uint32_t FSR_CONTROL_POINT1 = 0x80003FF8; +constexpr uint32_t FSR_CONTROL_POINT2 = 0x80003FF9; +constexpr uint32_t FSR_CONTROL_POINT3 = 0x80003FFA; +constexpr uint32_t FSR_WINDOW0 = 0x80003FFB; +constexpr uint32_t FSR_WINDOW1 = 0x80003FFC; +constexpr uint32_t TEXTURE_GRADIENT_CONTROL = 0x80003FFD; +constexpr uint32_t MEMORY_MAPPING_MASK = 0x80003FFE; +constexpr uint32_t UC_NOP = 0x80003FFF; + +constexpr uint32_t UC_NUM = 0x3FFF + 1; void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_dw, uint32_t num_dw); diff --git a/source/emulator/include/Emulator/Graphics/Shader.h b/source/emulator/include/Emulator/Graphics/Shader.h index fec1749..3928bc3 100644 --- a/source/emulator/include/Emulator/Graphics/Shader.h +++ b/source/emulator/include/Emulator/Graphics/Shader.h @@ -17,6 +17,7 @@ namespace HW { struct VertexShaderInfo; struct PixelShaderInfo; struct ComputeShaderInfo; +struct ShaderRegisters; } // namespace HW enum class ShaderType @@ -802,18 +803,19 @@ struct ShaderPixelInputInfo }; void ShaderCalcBindingIndices(ShaderBindResources* bind); -void ShaderGetInputInfoVS(const HW::VertexShaderInfo* regs, ShaderVertexInputInfo* info); -void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const ShaderVertexInputInfo* vs_info, ShaderPixelInputInfo* ps_info); -void ShaderGetInputInfoCS(const HW::ComputeShaderInfo* regs, ShaderComputeInputInfo* info); +void ShaderGetInputInfoVS(const HW::VertexShaderInfo* regs, const HW::ShaderRegisters* sh, ShaderVertexInputInfo* info); +void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const HW::ShaderRegisters* sh, const ShaderVertexInputInfo* vs_info, + ShaderPixelInputInfo* ps_info); +void ShaderGetInputInfoCS(const HW::ComputeShaderInfo* regs, const HW::ShaderRegisters* sh, ShaderComputeInputInfo* info); void ShaderDbgDumpInputInfo(const ShaderVertexInputInfo* info); void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo* info); void ShaderDbgDumpInputInfo(const ShaderComputeInputInfo* info); ShaderId ShaderGetIdVS(const HW::VertexShaderInfo* regs, const ShaderVertexInputInfo* input_info); ShaderId ShaderGetIdPS(const HW::PixelShaderInfo* regs, const ShaderPixelInputInfo* input_info); ShaderId ShaderGetIdCS(const HW::ComputeShaderInfo* regs, const ShaderComputeInputInfo* input_info); -ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs); -ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs); -ShaderCode ShaderParseCS(const HW::ComputeShaderInfo* regs); +ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs, const HW::ShaderRegisters* sh); +ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs, const HW::ShaderRegisters* sh); +ShaderCode ShaderParseCS(const HW::ComputeShaderInfo* regs, const HW::ShaderRegisters* sh); // ShaderBindParameters ShaderGetBindParametersVS(const ShaderCode& code, const ShaderVertexInputInfo* input_info); // ShaderBindParameters ShaderGetBindParametersPS(const ShaderCode& code, const ShaderPixelInputInfo* input_info); // ShaderBindParameters ShaderGetBindParametersCS(const ShaderCode& code, const ShaderComputeInputInfo* input_info); diff --git a/source/emulator/src/Graphics/Graphics.cpp b/source/emulator/src/Graphics/Graphics.cpp index 34e7e82..d439c35 100644 --- a/source/emulator/src/Graphics/Graphics.cpp +++ b/source/emulator/src/Graphics/Graphics.cpp @@ -73,7 +73,7 @@ namespace Gen4 { LIB_NAME("GraphicsDriver", "GraphicsDriver"); -int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier) +int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const uint32_t* vs_regs, uint32_t shader_modifier) { PRINT_NAME(); @@ -83,22 +83,22 @@ int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::Vs printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); - printf("\t vs_regs.m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmLoVs); - printf("\t vs_regs.m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmHiVs); - printf("\t vs_regs.m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc1Vs); - printf("\t vs_regs.m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc2Vs); - printf("\t vs_regs.m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs->m_spiVsOutConfig); - printf("\t vs_regs.m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs->m_spiShaderPosFormat); - printf("\t vs_regs.m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs->m_paClVsOutCntl); + printf("\t m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs[0]); + printf("\t m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs[1]); + printf("\t m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs[2]); + printf("\t m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs[3]); + printf("\t m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs[4]); + printf("\t m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs[5]); + printf("\t m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs[6]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS); cmd[1] = shader_modifier; - memcpy(&cmd[2], vs_regs, sizeof(HW::VsStageRegisters)); + memcpy(&cmd[2], vs_regs, static_cast(7) * 4); return OK; } -int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier) +int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const uint32_t* vs_regs, uint32_t shader_modifier) { PRINT_NAME(); @@ -108,17 +108,17 @@ int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const HW: printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); - printf("\t vs_regs.m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmLoVs); - printf("\t vs_regs.m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmHiVs); - printf("\t vs_regs.m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc1Vs); - printf("\t vs_regs.m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc2Vs); - printf("\t vs_regs.m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs->m_spiVsOutConfig); - printf("\t vs_regs.m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs->m_spiShaderPosFormat); - printf("\t vs_regs.m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs->m_paClVsOutCntl); + printf("\t m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs[0]); + printf("\t m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs[1]); + printf("\t m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs[2]); + printf("\t m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs[3]); + printf("\t m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs[4]); + printf("\t m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs[5]); + printf("\t m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs[6]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS_UPDATE); cmd[1] = shader_modifier; - memcpy(&cmd[2], vs_regs, sizeof(HW::VsStageRegisters)); + memcpy(&cmd[2], vs_regs, static_cast(7) * 4); return OK; } @@ -162,18 +162,18 @@ int KYTY_SYSV_ABI GraphicsSetPsShader(uint32_t* cmd, uint64_t size, const uint32 printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); - printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); - printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); - printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); - printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); - printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); - printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); - printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); - printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); - printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); - printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); - printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); - printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); + printf("\t m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); + printf("\t m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); + printf("\t m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); + printf("\t m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); + printf("\t m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); + printf("\t m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); + printf("\t m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); + printf("\t m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); + printf("\t m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); + printf("\t m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); + printf("\t m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); + printf("\t m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); @@ -203,18 +203,18 @@ int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uin printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); - printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); - printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); - printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); - printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); - printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); - printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); - printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); - printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); - printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); - printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); - printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); - printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); + printf("\t m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); + printf("\t m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); + printf("\t m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); + printf("\t m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); + printf("\t m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); + printf("\t m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); + printf("\t m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); + printf("\t m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); + printf("\t m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); + printf("\t m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); + printf("\t m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); + printf("\t m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); @@ -235,18 +235,18 @@ int KYTY_SYSV_ABI GraphicsUpdatePsShader(uint32_t* cmd, uint64_t size, const uin printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); - printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); - printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); - printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); - printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); - printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); - printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); - printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); - printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); - printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); - printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); - printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); - printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); + printf("\t m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); + printf("\t m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); + printf("\t m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); + printf("\t m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); + printf("\t m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); + printf("\t m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); + printf("\t m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); + printf("\t m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); + printf("\t m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); + printf("\t m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); + printf("\t m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); + printf("\t m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_UPDATE); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); @@ -264,18 +264,18 @@ int KYTY_SYSV_ABI GraphicsUpdatePsShader350(uint32_t* cmd, uint64_t size, const printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); - printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); - printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); - printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); - printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); - printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); - printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); - printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); - printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); - printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); - printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); - printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); - printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); + printf("\t m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); + printf("\t m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); + printf("\t m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); + printf("\t m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); + printf("\t m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); + printf("\t m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); + printf("\t m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); + printf("\t m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); + printf("\t m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); + printf("\t m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); + printf("\t m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); + printf("\t m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_UPDATE); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); @@ -293,13 +293,13 @@ int KYTY_SYSV_ABI GraphicsSetCsShaderWithModifier(uint32_t* cmd, uint64_t size, printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); - printf("\t cs_regs.m_computePgmLo = %08" PRIx32 "\n", cs_regs[0]); - printf("\t cs_regs.m_computePgmHi = %08" PRIx32 "\n", cs_regs[1]); - printf("\t cs_regs.m_computePgmRsrc1 = %08" PRIx32 "\n", cs_regs[2]); - printf("\t cs_regs.m_computePgmRsrc2 = %08" PRIx32 "\n", cs_regs[3]); - printf("\t cs_regs.m_computeNumThreadX = %08" PRIx32 "\n", cs_regs[4]); - printf("\t cs_regs.m_computeNumThreadY = %08" PRIx32 "\n", cs_regs[5]); - printf("\t cs_regs.m_computeNumThreadZ = %08" PRIx32 "\n", cs_regs[6]); + printf("\t m_computePgmLo = %08" PRIx32 "\n", cs_regs[0]); + printf("\t m_computePgmHi = %08" PRIx32 "\n", cs_regs[1]); + printf("\t m_computePgmRsrc1 = %08" PRIx32 "\n", cs_regs[2]); + printf("\t m_computePgmRsrc2 = %08" PRIx32 "\n", cs_regs[3]); + printf("\t m_computeNumThreadX = %08" PRIx32 "\n", cs_regs[4]); + printf("\t m_computeNumThreadY = %08" PRIx32 "\n", cs_regs[5]); + printf("\t m_computeNumThreadZ = %08" PRIx32 "\n", cs_regs[6]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_CS); cmd[1] = shader_modifier; @@ -315,12 +315,12 @@ int KYTY_SYSV_ABI GraphicsDrawIndex(uint32_t* cmd, uint64_t size, uint32_t index EXIT_NOT_IMPLEMENTED(size < 6); - printf("\tcmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); - printf("\tsize = %" PRIu64 "\n", size); - printf("\tindex_count = %" PRIu32 "\n", index_count); - printf("\tindex_addr = %016" PRIx64 "\n", reinterpret_cast(index_addr)); - printf("\tflags = %08" PRIx32 "\n", flags); - printf("\ttype = %" PRIu32 "\n", type); + printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t size = %" PRIu64 "\n", size); + printf("\t index_count = %" PRIu32 "\n", index_count); + printf("\t index_addr = %016" PRIx64 "\n", reinterpret_cast(index_addr)); + printf("\t flags = %08" PRIx32 "\n", flags); + printf("\t type = %" PRIu32 "\n", type); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DRAW_INDEX); cmd[1] = index_count; @@ -592,7 +592,7 @@ int KYTY_SYSV_ABI GraphicsComputeWaitOnAddress(uint32_t* cmd, uint64_t size, uin printf("\t func = %" PRIu32 "\n", func); printf("\t ref = %08" PRIx32 "\n", ref); - cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DISPATCH_WAIT_MEM); + cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_WAIT_MEM_32); cmd[1] = static_cast(reinterpret_cast(gpu_addr) & 0xffffffffu); cmd[2] = static_cast((reinterpret_cast(gpu_addr) >> 32u) & 0xffffffffu); cmd[3] = mask; @@ -921,63 +921,466 @@ struct CommandBuffer } }; -static RegisterDefaultInfo g_reg_info0[] = { - /* 0 */ {0x5f5a3e7b, {{Pm4::VGT_GS_OUT_PRIM_TYPE, 0x00000002}}}, - /* 1 */ {0x105971c2, {{Pm4::GE_CNTL, 0}}}, - /* 2 */ {0x40d49ad1, {{Pm4::GE_USER_VGPR_EN, 0}}}, - /* 3 */ {0x9ebfab10, {{Pm4::PRIMITIVE_TYPE, 0}}}, - /* 4 */ {0x48531062, {{Pm4::SPI_PS_INPUT_CNTL_0, 0}}}, +struct Label +{ + volatile uint64_t m_value; + uint64_t m_reserved[3]; }; -static RegisterDefaultInfo g_reg_info1[] = { - /* 0 - DepthRenderTarget */ {0x67096014, - {{Pm4::DB_Z_INFO, 0}, - {Pm4::DB_STENCIL_INFO, 0}, - {Pm4::DB_Z_READ_BASE, 0}, - {Pm4::DB_STENCIL_READ_BASE, 0}, - {Pm4::DB_Z_WRITE_BASE, 0}, - {Pm4::DB_STENCIL_WRITE_BASE, 0}, - {Pm4::DB_Z_READ_BASE_HI, 0}, - {Pm4::DB_STENCIL_READ_BASE_HI, 0}, - {Pm4::DB_Z_WRITE_BASE_HI, 0}, - {Pm4::DB_STENCIL_WRITE_BASE_HI, 0}, - {Pm4::DB_HTILE_DATA_BASE_HI, 0}, - {Pm4::DB_DEPTH_VIEW, 0}, - {Pm4::DB_HTILE_DATA_BASE, 0}, - {Pm4::DB_DEPTH_SIZE_XY, 0}, - {Pm4::DB_DEPTH_CLEAR, 0}, - {Pm4::DB_STENCIL_CLEAR, 0}}}, - /* 1 - RenderTarget */ {0x38e92c91, - {{Pm4::CB_COLOR0_BASE, 0}, - {Pm4::CB_COLOR0_VIEW, 0}, - {Pm4::CB_COLOR0_INFO, 0}, - {Pm4::CB_COLOR0_ATTRIB, 0}, - {Pm4::CB_COLOR0_DCC_CONTROL, 0}, - {Pm4::CB_COLOR0_CMASK, 0}, - {Pm4::CB_COLOR0_FMASK, 0}, - {Pm4::CB_COLOR0_CLEAR_WORD0, 0}, - {Pm4::CB_COLOR0_CLEAR_WORD1, 0}, - {Pm4::CB_COLOR0_DCC_BASE, 0}, - {Pm4::CB_COLOR0_BASE_EXT, 0}, - {Pm4::CB_COLOR0_CMASK_BASE_EXT, 0}, - {Pm4::CB_COLOR0_FMASK_BASE_EXT, 0}, - {Pm4::CB_COLOR0_DCC_BASE_EXT, 0}, - {Pm4::CB_COLOR0_ATTRIB2, 0}, - {Pm4::CB_COLOR0_ATTRIB3, 0}}}}; +static RegisterDefaultInfo g_cx_reg_info1[] = { + /* 0 */ {0xE24F806D, {{Pm4::CB_COLOR_CONTROL, 0x00cc0010}}}, + /* 1 */ {0xF6C28182, {{Pm4::CB_DCC_CONTROL, 0x00000000}}}, + /* 2 */ {0x6F6E55A5, {{Pm4::CB_RMI_GL2_CACHE_CONTROL, 0x00000000}}}, + /* 3 */ {0x0BC65DA4, {{Pm4::CB_SHADER_MASK, 0x00000000}}}, + /* 4 */ {0x9E5AD592, {{Pm4::CB_TARGET_MASK, 0x00000000}}}, + /* 5 */ {0xBB513B98, {{Pm4::DB_ALPHA_TO_MASK, 0x0000aa00}}}, + /* 6 */ {0xAB64B23B, {{Pm4::DB_COUNT_CONTROL, 0x00000000}}}, + /* 7 */ {0x53C39964, {{Pm4::DB_DEPTH_CONTROL, 0x00000000}}}, + /* 8 */ {0x01396B11, {{Pm4::DB_EQAA, 0x00000000}}}, + /* 9 */ {0x7D42019A, {{Pm4::DB_RENDER_CONTROL, 0x00000000}}}, + /* 10 */ {0x3548F523, {{Pm4::PS_SHADER_SAMPLE_EXCLUSION_MASK, 0x00000000}}}, + /* 11 */ {0xF43AD28A, {{Pm4::DB_RMI_L2_CACHE_CONTROL, 0x00000000}}}, + /* 12 */ {0x6DE4C312, {{Pm4::DB_SHADER_CONTROL, 0x00000000}}}, + /* 13 */ {0x00A77AE0, {{Pm4::DB_SRESULTS_COMPARE_STATE0, 0x00000000}}}, + /* 14 */ {0x00A779B7, {{Pm4::DB_SRESULTS_COMPARE_STATE1, 0x00000000}}}, + /* 15 */ {0x5100100C, {{Pm4::DB_STENCILREFMASK, 0x00000000}}}, + /* 16 */ {0x59958BBA, {{Pm4::DB_STENCILREFMASK_BF, 0x00000000}}}, + /* 17 */ {0x0C06F17C, {{Pm4::DB_STENCIL_CONTROL, 0x00000000}}}, + /* 18 */ {0x6F104B72, {{Pm4::GE_MAX_OUTPUT_PER_SUBGROUP, 0x00000000}}}, + /* 19 */ {0x25C70D9C, {{Pm4::PA_CL_CLIP_CNTL, 0x00000000}}}, + /* 20 */ {0x3881201E, {{Pm4::PA_CL_OBJPRIM_ID_CNTL, 0x00000000}}}, + /* 21 */ {0x09AFDDAF, {{Pm4::PA_CL_VTE_CNTL, 0x0000043f}}}, + /* 22 */ {0x367D63CF, {{Pm4::PA_SC_AA_CONFIG, 0x00000000}}}, + /* 23 */ {0x43707DB8, {{Pm4::PA_SC_CLIPRECT_RULE, 0x0000ffff}}}, + /* 24 */ {0xF6AE26BA, {{Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL, 0x00000000}}}, + /* 25 */ {0x1B917652, {{Pm4::PA_SC_FSR_ENABLE, 0x00000000}}}, + /* 26 */ {0x94B1E4F7, {{Pm4::PA_SC_HORIZ_GRID, 0x00000000}}}, + /* 27 */ {0xE3661B6C, {{Pm4::PA_SC_LEFT_VERT_GRID, 0x00000000}}}, + /* 28 */ {0x1EB8D73A, {{Pm4::PA_SC_MODE_CNTL_0, 0x00000002}}}, + /* 29 */ {0x15051FA3, {{Pm4::PA_SC_MODE_CNTL_1, 0x00000000}}}, + /* 30 */ {0x9C51A7F1, {{Pm4::PA_SC_RIGHT_VERT_GRID, 0x00000000}}}, + /* 31 */ {0xA20EFC70, {{Pm4::PA_SC_WINDOW_OFFSET, 0x00000000}}}, + /* 32 */ {0x0EC09F6E, {{Pm4::PA_STATE_STEREO_X, 0x00000000}}}, + /* 33 */ {0x34A7D6D3, {{Pm4::PA_STEREO_CNTL, 0x00000000}}}, + /* 34 */ {0xCE831B94, {{Pm4::PA_SU_HARDWARE_SCREEN_OFFSET, 0x00000000}}}, + /* 35 */ {0x5CC72A74, {{Pm4::PA_SU_LINE_CNTL, 0x00000008}}}, + /* 36 */ {0x3B77713C, {{Pm4::PA_SU_POINT_MINMAX, 0xffff0000}}}, + /* 37 */ {0x40F64410, {{Pm4::PA_SU_POINT_SIZE, 0x00080008}}}, + /* 38 */ {0x69441268, {{Pm4::PA_SU_POLY_OFFSET_CLAMP, 0x00000000}}}, + /* 39 */ {0x2E418B83, {{Pm4::PA_SU_POLY_OFFSET_DB_FMT_CNTL, 0x000001e9}}}, + /* 40 */ {0xA00D0C8D, {{Pm4::PA_SU_SC_MODE_CNTL, 0x00000240}}}, + /* 41 */ {0xB1289FB3, {{Pm4::PA_SU_SMALL_PRIM_FILTER_CNTL, 0x00000001}}}, + /* 42 */ {0x144832FB, {{Pm4::PA_SU_VTX_CNTL, 0x0000002d}}}, + /* 43 */ {0x9890D9FA, {{Pm4::SPI_TMPRING_SIZE, 0x00000000}}}, + /* 44 */ {0x9016FAF1, {{Pm4::VGT_DRAW_PAYLOAD_CNTL, 0x00000000}}}, + /* 45 */ {0x4B73CE27, {{Pm4::VGT_GS_MAX_VERT_OUT, 0x00000400}}}, + /* 46 */ {0x5F5A3E7B, {{Pm4::VGT_GS_OUT_PRIM_TYPE, 0x00000002}}}, + /* 47 */ {0xD4AF3A51, {{Pm4::VGT_LS_HS_CONFIG, 0x00000000}}}, + /* 48 */ {0x6CF4F543, {{Pm4::VGT_PRIMITIVEID_RESET, 0xffffffff}}}, + /* 49 */ {0x5FB86CCB, {{Pm4::VGT_PRIMITIVEID_EN, 0x00000000}}}, + /* 50 */ {0xEDEFA188, {{Pm4::VGT_REUSE_OFF, 0x00000000}}}, + /* 51 */ {0xD0DE9EE6, {{Pm4::VGT_SHADER_STAGES_EN, 0x00000000}}}, + /* 52 */ {0xC5831803, {{Pm4::VGT_TESS_DISTRIBUTION, 0x88101000}}}, + /* 53 */ {0x8E6DE84B, {{Pm4::VGT_TF_PARAM, 0x00000000}}}, + /* 54 */ + {0xD0771662, + { + {Pm4::PA_SC_CENTROID_PRIORITY_0, 0x00000000}, + {Pm4::PA_SC_CENTROID_PRIORITY_1, 0x00000000}, + }}, + /* 55 */ {0x569F7444, {{Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0, 0x00000000}}}, + /* 56 */ + {0x5C6637CD, + { + {Pm4::PA_SC_AA_MASK_X0Y0_X1Y0, 0xffffffff}, + {Pm4::PA_SC_AA_MASK_X0Y1_X1Y1, 0xffffffff}, + }}, + /* 57 */ + {0xCAE3E690, + { + {Pm4::PA_SC_BINNER_CNTL_0, 0x00000002}, + {Pm4::PA_SC_BINNER_CNTL_1, 0x03ff0080}, + }}, + /* 58 */ + {0x43FBD769, + { + {Pm4::CB_BLEND_RED, 0x00000000}, + {Pm4::CB_BLEND_BLUE, 0x00000000}, + {Pm4::CB_BLEND_GREEN, 0x00000000}, + {Pm4::CB_BLEND_ALPHA, 0x00000000}, + }}, + /* 59 */ {0xEF550356, {{Pm4::CB_BLEND0_CONTROL, 0x20010001}}}, + /* 60 */ + {0x8F52E279, + { + {Pm4::TA_BC_BASE_ADDR, 0x00000000}, + {Pm4::TA_BC_BASE_ADDR_HI, 0x00000000}, + }}, + /* 61 */ + {0x1F2D8149, + { + {Pm4::PA_SC_CLIPRECT_0_TL, 0x00000000}, + {Pm4::PA_SC_CLIPRECT_0_BR, 0x20002000}, + }}, + /* 62 */ {0x853D0614, {{Pm4::CX_NOP, 0x00000000}}}, + /* 63 */ + {0x4413C6F9, + { + {Pm4::DB_DEPTH_BOUNDS_MIN, 0x00000000}, + {Pm4::DB_DEPTH_BOUNDS_MAX, 0x00000000}, + }}, + /* 64 */ + {0x67096014, + { + {Pm4::DB_Z_INFO, 0x80000000}, + {Pm4::DB_STENCIL_INFO, 0x20000000}, + {Pm4::DB_Z_READ_BASE, 0x00000000}, + {Pm4::DB_STENCIL_READ_BASE, 0x00000000}, + {Pm4::DB_Z_WRITE_BASE, 0x00000000}, + {Pm4::DB_STENCIL_WRITE_BASE, 0x00000000}, + {Pm4::DB_Z_READ_BASE_HI, 0x00000000}, + {Pm4::DB_STENCIL_READ_BASE_HI, 0x00000000}, + {Pm4::DB_Z_WRITE_BASE_HI, 0x00000000}, + {Pm4::DB_STENCIL_WRITE_BASE_HI, 0x00000000}, + {Pm4::DB_HTILE_DATA_BASE_HI, 0x00000000}, + {Pm4::DB_DEPTH_VIEW, 0x00000000}, + {Pm4::DB_HTILE_DATA_BASE, 0x00000000}, + {Pm4::DB_DEPTH_SIZE_XY, 0x00000000}, + {Pm4::DB_DEPTH_CLEAR, 0x00000000}, + {Pm4::DB_STENCIL_CLEAR, 0x00000000}, + }}, + /* 65 */ + {0x88F5E915, + { + {Pm4::PA_SC_FOV_WINDOW_LR, 0xff00ff00}, + {Pm4::PA_SC_FOV_WINDOW_TB, 0x00000000}, + }}, + /* 66 */ + {0x033F1EFF, + { + {Pm4::FSR_RECURSIONS0, 0x00000000}, + {Pm4::FSR_RECURSIONS1, 0x00000000}, + }}, + /* 67 */ + {0x918106BB, + { + {Pm4::PA_SC_GENERIC_SCISSOR_TL, 0x80000000}, + {Pm4::PA_SC_GENERIC_SCISSOR_BR, 0x40004000}, + }}, + /* 68 */ + {0x95F0E7AC, + { + {Pm4::PA_CL_GB_VERT_CLIP_ADJ, 0x4e7e0000}, + {Pm4::PA_CL_GB_VERT_DISC_ADJ, 0x4e7e0000}, + {Pm4::PA_CL_GB_HORZ_CLIP_ADJ, 0x4e7e0000}, + {Pm4::PA_CL_GB_HORZ_DISC_ADJ, 0x4e7e0000}, + }}, + /* 69 */ + {0xB48CBAB2, + { + {Pm4::PA_SU_POLY_OFFSET_BACK_SCALE, 0x00000000}, + {Pm4::PA_SU_POLY_OFFSET_BACK_OFFSET, 0x00000000}, + }}, + /* 70 */ + {0x05BB3BC6, + { + {Pm4::PA_SU_POLY_OFFSET_FRONT_SCALE, 0x00000000}, + {Pm4::PA_SU_POLY_OFFSET_FRONT_OFFSET, 0x00000000}, + }}, + /* 71 */ + {0x94FABA07, + { + {Pm4::DB_RENDER_OVERRIDE, 0x00000000}, + {Pm4::DB_RENDER_OVERRIDE2, 0x00000000}, + }}, + /* 72 */ + {0x38E92C91, + { + {Pm4::CB_COLOR0_BASE, 0x00000000}, + {Pm4::CB_COLOR0_VIEW, 0x00000000}, + {Pm4::CB_COLOR0_INFO, 0x00000000}, + {Pm4::CB_COLOR0_ATTRIB, 0x00000000}, + {Pm4::CB_COLOR0_DCC_CONTROL, 0x00000048}, + {Pm4::CB_COLOR0_CMASK, 0x00000000}, + {Pm4::CB_COLOR0_FMASK, 0x00000000}, + {Pm4::CB_COLOR0_CLEAR_WORD0, 0x00000000}, + {Pm4::CB_COLOR0_CLEAR_WORD1, 0x00000000}, + {Pm4::CB_COLOR0_DCC_BASE, 0x00000000}, + {Pm4::CB_COLOR0_BASE_EXT, 0x00000000}, + {Pm4::CB_COLOR0_CMASK_BASE_EXT, 0x00000000}, + {Pm4::CB_COLOR0_FMASK_BASE_EXT, 0x00000000}, + {Pm4::CB_COLOR0_DCC_BASE_EXT, 0x00000000}, + {Pm4::CB_COLOR0_ATTRIB2, 0x00000000}, + {Pm4::CB_COLOR0_ATTRIB3, 0x0006c000}, + }}, + /* 73 */ + {0x0B177B43, + { + {Pm4::PA_SC_SCREEN_SCISSOR_TL, 0x00000000}, + {Pm4::PA_SC_SCREEN_SCISSOR_BR, 0x40004000}, + }}, + /* 74 */ {0x48531062, {{Pm4::SPI_PS_INPUT_CNTL_0, 0x00000000}}}, + /* 75 */ + {0xAAA964B9, + { + {Pm4::PA_CL_UCP_0_X, 0x00000000}, + {Pm4::PA_CL_UCP_0_Y, 0x00000000}, + {Pm4::PA_CL_UCP_0_Z, 0x00000000}, + {Pm4::PA_CL_UCP_0_W, 0x00000000}, + }}, + /* 76 */ + {0x7690AF6F, + { + {Pm4::PA_CL_VPORT_XSCALE, 0x4e7e0000}, + {Pm4::PA_CL_VPORT_YSCALE, 0x4e7e0000}, + {Pm4::PA_CL_VPORT_ZSCALE, 0x4e7e0000}, + {Pm4::PA_CL_VPORT_XOFFSET, 0x00000000}, + {Pm4::PA_CL_VPORT_YOFFSET, 0x00000000}, + {Pm4::PA_CL_VPORT_ZOFFSET, 0x00000000}, + {Pm4::PA_SC_VPORT_SCISSOR_0_TL, 0x80000000}, + {Pm4::PA_SC_VPORT_SCISSOR_0_BR, 0x40004000}, + {Pm4::PA_SC_VPORT_ZMIN_0, 0x00000000}, + {Pm4::PA_SC_VPORT_ZMAX_0, 0x00000000}, + }}, + /* 77 */ + {0x078D7060, + { + {Pm4::PA_SC_WINDOW_SCISSOR_TL, 0x80000000}, + {Pm4::PA_SC_WINDOW_SCISSOR_BR, 0x40004000}, + }}, -#define KYTY_ID(id, tbl) ((id)*4 + (tbl)) -#define KYTY_INDEX0(id) g_reg_info0[id].type, KYTY_ID(id, 0), 0 -#define KYTY_INDEX1(id) g_reg_info1[id].type, KYTY_ID(id, 1), 0 -#define KYTY_REG0(id) &g_reg_info0[id].reg[0] -#define KYTY_REG1(id) &g_reg_info1[id].reg[0] +}; -static ShaderRegister* g_tbl0[] = {KYTY_REG0(0), KYTY_REG0(1), KYTY_REG0(2), KYTY_REG0(3), KYTY_REG0(4)}; -static ShaderRegister* g_tbl1[] = {KYTY_REG1(0), KYTY_REG1(1)}; -static uint32_t g_tbl_index[] = {KYTY_INDEX0(0), KYTY_INDEX0(1), KYTY_INDEX0(2), KYTY_INDEX0(3), - KYTY_INDEX0(4), KYTY_INDEX1(0), KYTY_INDEX1(1)}; +static RegisterDefaultInfo g_sh_reg_info1[] = { + /* 0 */ {0x5D6E3EC7, {{Pm4::COMPUTE_PGM_RSRC1, 0x00000000}}}, + /* 1 */ {0x57E7079A, {{Pm4::COMPUTE_PGM_RSRC2, 0x00000000}}}, + /* 2 */ {0x7467FAFD, {{Pm4::COMPUTE_PGM_RSRC3, 0x00000000}}}, + /* 3 */ {0x9E826B50, {{Pm4::COMPUTE_RESOURCE_LIMITS, 0x00000000}}}, + /* 4 */ {0xDC484F18, {{Pm4::COMPUTE_TMPRING_SIZE, 0x00000000}}}, + /* 5 */ {0x5DA8BCA3, {{Pm4::SPI_SHADER_PGM_RSRC1_GS, 0x00000000}}}, + /* 6 */ {0x5CA726D8, {{Pm4::SPI_SHADER_PGM_RSRC1_HS, 0x00000000}}}, + /* 7 */ {0x5DD28360, {{Pm4::SPI_SHADER_PGM_RSRC1_PS, 0x00000000}}}, + /* 8 */ {0x57EFA0BE, {{Pm4::SPI_SHADER_PGM_RSRC2_GS, 0x00000000}}}, + /* 9 */ {0x502363D5, {{Pm4::SPI_SHADER_PGM_RSRC2_HS, 0x00000000}}}, + /* 10 */ {0x506D14BD, {{Pm4::SPI_SHADER_PGM_RSRC2_PS, 0x00000000}}}, + /* 11 */ {0xB2609506, {{Pm4::COMPUTE_USER_ACCUM_0, 0x00000000}}}, + /* 12 */ + {0x9E5CFB8A, + { + {Pm4::SPI_SHADER_PGM_RSRC3_HS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_RSRC3_GS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_RSRC3_PS, 0x00000000}, + }}, + /* 13 */ + {0xC918DF3E, + { + {Pm4::COMPUTE_PGM_LO, 0x00000000}, + {Pm4::COMPUTE_PGM_HI, 0x00000000}, + }}, + /* 14 */ + {0xC9751C9C, + { + {Pm4::SPI_SHADER_PGM_LO_ES, 0x00000000}, + {Pm4::SPI_SHADER_PGM_HI_ES, 0x00000000}, + }}, + /* 15 */ + {0xC97EF77A, + { + {Pm4::SPI_SHADER_PGM_LO_GS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_HI_GS, 0x00000000}, + }}, + /* 16 */ + {0xC927C6B9, + { + {Pm4::SPI_SHADER_PGM_LO_HS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_HI_HS, 0x00000000}, + }}, + /* 17 */ + {0xC92A1EC5, + { + {Pm4::SPI_SHADER_PGM_LO_LS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_HI_LS, 0x00000000}, + }}, + /* 18 */ + {0xC9E01B31, + { + {Pm4::SPI_SHADER_PGM_LO_PS, 0x00000000}, + {Pm4::SPI_SHADER_PGM_HI_PS, 0x00000000}, + }}, + /* 19 */ {0x50685F29, {{Pm4::SH_NOP, 0x00000000}}}, + /* 20 */ {0xB26219CA, {{Pm4::SPI_SHADER_USER_ACCUM_ESGS_0, 0x00000000}}}, + /* 21 */ {0xB25B6CF9, {{Pm4::SPI_SHADER_USER_ACCUM_LSHS_0, 0x00000000}}}, + /* 22 */ {0xB2F86101, {{Pm4::SPI_SHADER_USER_ACCUM_PS_0, 0x00000000}}}, + /* 23 */ + {0x07E3B155, + { + {Pm4::SPI_SHADER_USER_DATA_ADDR_LO_GS, 0x00000000}, + {Pm4::SPI_SHADER_USER_DATA_ADDR_HI_GS, 0x00000000}, + }}, + /* 24 */ + {0x07E383C6, + { + {Pm4::SPI_SHADER_USER_DATA_ADDR_LO_HS, 0x00000000}, + {Pm4::SPI_SHADER_USER_DATA_ADDR_HI_HS, 0x00000000}, + }}, + /* 25 */ {0xBDA98653, {{Pm4::COMPUTE_USER_DATA_0, 0x00000000}}}, + /* 26 */ {0xBDBD1D0F, {{Pm4::SPI_SHADER_USER_DATA_GS_0, 0x00000000}}}, + /* 27 */ {0xBD946FD4, {{Pm4::SPI_SHADER_USER_DATA_HS_0, 0x00000000}}}, + /* 28 */ {0xBDF02A4C, {{Pm4::SPI_SHADER_USER_DATA_PS_0, 0x00000000}}}, +}; -static RegisterDefaults g_reg_defaults = { // @suppress("Invalid arguments") - g_tbl0, g_tbl1, nullptr, nullptr, {0, 0}, g_tbl_index, sizeof(g_tbl_index) / 12}; +static RegisterDefaultInfo g_uc_reg_info1[] = { + /* 0 */ {0x19E93E85, {{Pm4::GDS_OA_ADDRESS, 0x00000000}}}, + /* 1 */ {0x3B5C2AF3, {{Pm4::GDS_OA_CNTL, 0x00000000}}}, + /* 2 */ {0x47974A35, {{Pm4::GDS_OA_COUNTER, 0x00000000}}}, + /* 3 */ {0x105971C2, {{Pm4::GE_CNTL, 0x00000000}}}, + /* 4 */ {0x7D137765, {{Pm4::GE_INDX_OFFSET, 0x00000000}}}, + /* 5 */ {0xD187FEBC, {{Pm4::GE_MULTI_PRIM_IB_RESET_EN, 0x00000000}}}, + /* 6 */ {0x12F854AC, {{Pm4::GE_STEREO_CNTL, 0x00000000}}}, + /* 7 */ {0x40D49AD1, {{Pm4::GE_USER_VGPR_EN, 0x00000000}}}, + /* 8 */ {0x8C0923DA, {{Pm4::FSR_EXTEND_SUBPIXEL_ROUNDING, 0x00000000}}}, + /* 9 */ {0xBB8DF494, {{Pm4::TEXTURE_GRADIENT_CONTROL, 0x00000000}}}, + /* 10 */ {0xF6D8A76E, {{Pm4::TEXTURE_GRADIENT_FACTORS, 0x40000040}}}, + /* 11 */ {0x7620F1E9, {{Pm4::VGT_OBJECT_ID, 0x00000000}}}, + /* 12 */ {0x9EBFAB10, {{Pm4::VGT_PRIMITIVE_TYPE, 0x00000000}}}, + /* 13 */ + {0x98A09D0E, + { + {Pm4::TA_CS_BC_BASE_ADDR, 0x00000000}, + {Pm4::TA_CS_BC_BASE_ADDR_HI, 0x00000000}, + }}, + /* 14 */ + {0x195D37D2, + { + {Pm4::FSR_ALPHA_VALUE0, 0x00000000}, + {Pm4::FSR_ALPHA_VALUE1, 0x00000000}, + }}, + /* 15 */ + {0xF9EC4F85, + { + {Pm4::FSR_CONTROL_POINT0, 0x00000000}, + {Pm4::FSR_CONTROL_POINT1, 0x00000000}, + {Pm4::FSR_CONTROL_POINT2, 0x00000000}, + {Pm4::FSR_CONTROL_POINT3, 0x00000000}, + }}, + /* 16 */ + {0x4626B750, + { + {Pm4::FSR_WINDOW0, 0x00000000}, + {Pm4::FSR_WINDOW1, 0x00000000}, + }}, + /* 17 */ {0x4CC673A0, {{Pm4::MEMORY_MAPPING_MASK, 0x00000000}}}, + /* 18 */ {0xDE5B3431, {{Pm4::UC_NOP, 0x00000000}}}, + /* 19 */ {0x036AC8A6, {{Pm4::GE_USER_VGPR1, 0x00000000}}}}; + +static RegisterDefaultInfo g_cx_reg_info2[] = { + /* 0 */ {0x8FB4EDB5, {{Pm4::DB_DFSM_CONTROL, 0x00000000}}}, + /* 1 */ {0xB994AD29, {{Pm4::DB_HTILE_SURFACE, 0x00000000}}}, + /* 2 */ {0xD427322F, {{Pm4::PA_SC_NGG_MODE_CNTL, 0x00000000}}}, + /* 3 */ {0xF58FEA31, {{Pm4::SPI_INTERP_CONTROL_0, 0x00000000}}}, +}; + +static RegisterDefaultInfo g_sh_reg_info2[] = { + /* 0 */ {0x6AC156EF, {{Pm4::COMPUTE_DESTINATION_EN_SE0, 0x00000000}}}, + /* 1 */ {0x6AC15610, {{Pm4::COMPUTE_DESTINATION_EN_SE1, 0x00000000}}}, + /* 2 */ {0x6AC15009, {{Pm4::COMPUTE_DESTINATION_EN_SE2, 0x00000000}}}, + /* 3 */ {0x6AC153BA, {{Pm4::COMPUTE_DESTINATION_EN_SE3, 0x00000000}}}, + /* 4 */ {0xBE7DCD73, {{Pm4::COMPUTE_DISPATCH_TUNNEL, 0x00000000}}}, + /* 5 */ {0x0C4B1438, {{Pm4::COMPUTE_SHADER_CHKSUM, 0x00000000}}}, + /* 6 */ {0xDB00D71A, {{Pm4::COMPUTE_START_X, 0x00000000}}}, + /* 7 */ {0xDB00D249, {{Pm4::COMPUTE_START_Y, 0x00000000}}}, + /* 8 */ {0xDB00EC60, {{Pm4::COMPUTE_START_Z, 0x00000000}}}, + /* 9 */ {0x0C4D6FE4, {{Pm4::SPI_SHADER_PGM_CHKSUM_GS, 0x00000000}}}, + /* 10 */ {0x0C4A80EF, {{Pm4::SPI_SHADER_PGM_CHKSUM_HS, 0x00000000}}}, + /* 11 */ {0x0DD283E7, {{Pm4::SPI_SHADER_PGM_CHKSUM_PS, 0x00000000}}}, + /* 12 */ {0xC620E68C, {{Pm4::SPI_SHADER_PGM_RSRC4_GS, 0x00000000}}}, + /* 13 */ {0xC67EFACF, {{Pm4::SPI_SHADER_PGM_RSRC4_HS, 0x00000000}}}, + /* 14 */ {0xD9E6D9F7, {{Pm4::SPI_SHADER_PGM_RSRC4_PS, 0x00000000}}}, +}; + +static RegisterDefaultInfo g_uc_reg_info2[] = { + /* 0 */ {0x31F34B9F, {{Pm4::VGT_HS_OFFCHIP_PARAM, 0x00000000}}}, + /* 1 */ {0xAC0F9E76, {{Pm4::UC_NOP, 0x00000000}}}, + /* 2 */ {0x929FD95D, {{Pm4::VGT_TF_MEMORY_BASE, 0x00000000}}}, +}; + +#define KYTY_ID(id, tbl) ((id)*4 + (tbl)) +#define KYTY_INDEX_CX1(id) g_cx_reg_info1[id].type, KYTY_ID(id, 0), 0 +#define KYTY_INDEX_SH1(id) g_sh_reg_info1[id].type, KYTY_ID(id, 1), 0 +#define KYTY_INDEX_UC1(id) g_uc_reg_info1[id].type, KYTY_ID(id, 2), 0 +#define KYTY_INDEX_CX2(id) g_cx_reg_info2[id].type, KYTY_ID(id, 0), 0 +#define KYTY_INDEX_SH2(id) g_sh_reg_info2[id].type, KYTY_ID(id, 1), 0 +#define KYTY_INDEX_UC2(id) g_uc_reg_info2[id].type, KYTY_ID(id, 2), 0 +#define KYTY_REG_CX1(id) &g_cx_reg_info1[id].reg[0] +#define KYTY_REG_SH1(id) &g_sh_reg_info1[id].reg[0] +#define KYTY_REG_UC1(id) &g_uc_reg_info1[id].reg[0] +#define KYTY_REG_CX2(id) &g_cx_reg_info2[id].reg[0] +#define KYTY_REG_SH2(id) &g_sh_reg_info2[id].reg[0] +#define KYTY_REG_UC2(id) &g_uc_reg_info2[id].reg[0] + +static ShaderRegister* g_tbl_cx1[] = { + KYTY_REG_CX1(0), KYTY_REG_CX1(1), KYTY_REG_CX1(2), KYTY_REG_CX1(3), KYTY_REG_CX1(4), KYTY_REG_CX1(5), KYTY_REG_CX1(6), + KYTY_REG_CX1(7), KYTY_REG_CX1(8), KYTY_REG_CX1(9), KYTY_REG_CX1(10), KYTY_REG_CX1(11), KYTY_REG_CX1(12), KYTY_REG_CX1(13), + KYTY_REG_CX1(14), KYTY_REG_CX1(15), KYTY_REG_CX1(16), KYTY_REG_CX1(17), KYTY_REG_CX1(18), KYTY_REG_CX1(19), KYTY_REG_CX1(20), + KYTY_REG_CX1(21), KYTY_REG_CX1(22), KYTY_REG_CX1(23), KYTY_REG_CX1(24), KYTY_REG_CX1(25), KYTY_REG_CX1(26), KYTY_REG_CX1(27), + KYTY_REG_CX1(28), KYTY_REG_CX1(29), KYTY_REG_CX1(30), KYTY_REG_CX1(31), KYTY_REG_CX1(32), KYTY_REG_CX1(33), KYTY_REG_CX1(34), + KYTY_REG_CX1(35), KYTY_REG_CX1(36), KYTY_REG_CX1(37), KYTY_REG_CX1(38), KYTY_REG_CX1(39), KYTY_REG_CX1(40), KYTY_REG_CX1(41), + KYTY_REG_CX1(42), KYTY_REG_CX1(43), KYTY_REG_CX1(44), KYTY_REG_CX1(45), KYTY_REG_CX1(46), KYTY_REG_CX1(47), KYTY_REG_CX1(48), + KYTY_REG_CX1(49), KYTY_REG_CX1(50), KYTY_REG_CX1(51), KYTY_REG_CX1(52), KYTY_REG_CX1(53), KYTY_REG_CX1(54), KYTY_REG_CX1(55), + KYTY_REG_CX1(56), KYTY_REG_CX1(57), KYTY_REG_CX1(58), KYTY_REG_CX1(59), KYTY_REG_CX1(60), KYTY_REG_CX1(61), KYTY_REG_CX1(62), + KYTY_REG_CX1(63), KYTY_REG_CX1(64), KYTY_REG_CX1(65), KYTY_REG_CX1(66), KYTY_REG_CX1(67), KYTY_REG_CX1(68), KYTY_REG_CX1(69), + KYTY_REG_CX1(70), KYTY_REG_CX1(71), KYTY_REG_CX1(72), KYTY_REG_CX1(73), KYTY_REG_CX1(74), KYTY_REG_CX1(75), KYTY_REG_CX1(76), + KYTY_REG_CX1(77)}; + +static ShaderRegister* g_tbl_sh1[] = {KYTY_REG_SH1(0), KYTY_REG_SH1(1), KYTY_REG_SH1(2), KYTY_REG_SH1(3), KYTY_REG_SH1(4), + KYTY_REG_SH1(5), KYTY_REG_SH1(6), KYTY_REG_SH1(7), KYTY_REG_SH1(8), KYTY_REG_SH1(9), + KYTY_REG_SH1(10), KYTY_REG_SH1(11), KYTY_REG_SH1(12), KYTY_REG_SH1(13), KYTY_REG_SH1(14), + KYTY_REG_SH1(15), KYTY_REG_SH1(16), KYTY_REG_SH1(17), KYTY_REG_SH1(18), KYTY_REG_SH1(19), + KYTY_REG_SH1(20), KYTY_REG_SH1(21), KYTY_REG_SH1(22), KYTY_REG_SH1(23), KYTY_REG_SH1(24), + KYTY_REG_SH1(25), KYTY_REG_SH1(26), KYTY_REG_SH1(27), KYTY_REG_SH1(28)}; +static ShaderRegister* g_tbl_uc1[] = {KYTY_REG_UC1(0), KYTY_REG_UC1(1), KYTY_REG_UC1(2), KYTY_REG_UC1(3), KYTY_REG_UC1(4), + KYTY_REG_UC1(5), KYTY_REG_UC1(6), KYTY_REG_UC1(7), KYTY_REG_UC1(8), KYTY_REG_UC1(9), + KYTY_REG_UC1(10), KYTY_REG_UC1(11), KYTY_REG_UC1(12), KYTY_REG_UC1(13), KYTY_REG_UC1(14), + KYTY_REG_UC1(15), KYTY_REG_UC1(16), KYTY_REG_UC1(17), KYTY_REG_UC1(18), KYTY_REG_UC1(19)}; +static uint32_t g_tbl_index1[] = { + KYTY_INDEX_CX1(0), KYTY_INDEX_CX1(1), KYTY_INDEX_CX1(2), KYTY_INDEX_CX1(3), KYTY_INDEX_CX1(4), KYTY_INDEX_CX1(5), + KYTY_INDEX_CX1(6), KYTY_INDEX_CX1(7), KYTY_INDEX_CX1(8), KYTY_INDEX_CX1(9), KYTY_INDEX_CX1(10), KYTY_INDEX_CX1(11), + KYTY_INDEX_CX1(12), KYTY_INDEX_CX1(13), KYTY_INDEX_CX1(14), KYTY_INDEX_CX1(15), KYTY_INDEX_CX1(16), KYTY_INDEX_CX1(17), + KYTY_INDEX_CX1(18), KYTY_INDEX_CX1(19), KYTY_INDEX_CX1(20), KYTY_INDEX_CX1(21), KYTY_INDEX_CX1(22), KYTY_INDEX_CX1(23), + KYTY_INDEX_CX1(24), KYTY_INDEX_CX1(25), KYTY_INDEX_CX1(26), KYTY_INDEX_CX1(27), KYTY_INDEX_CX1(28), KYTY_INDEX_CX1(29), + KYTY_INDEX_CX1(30), KYTY_INDEX_CX1(31), KYTY_INDEX_CX1(32), KYTY_INDEX_CX1(33), KYTY_INDEX_CX1(34), KYTY_INDEX_CX1(35), + KYTY_INDEX_CX1(36), KYTY_INDEX_CX1(37), KYTY_INDEX_CX1(38), KYTY_INDEX_CX1(39), KYTY_INDEX_CX1(40), KYTY_INDEX_CX1(41), + KYTY_INDEX_CX1(42), KYTY_INDEX_CX1(43), KYTY_INDEX_CX1(44), KYTY_INDEX_CX1(45), KYTY_INDEX_CX1(46), KYTY_INDEX_CX1(47), + KYTY_INDEX_CX1(48), KYTY_INDEX_CX1(49), KYTY_INDEX_CX1(50), KYTY_INDEX_CX1(51), KYTY_INDEX_CX1(52), KYTY_INDEX_CX1(53), + KYTY_INDEX_CX1(54), KYTY_INDEX_CX1(55), KYTY_INDEX_CX1(56), KYTY_INDEX_CX1(57), KYTY_INDEX_CX1(58), KYTY_INDEX_CX1(59), + KYTY_INDEX_CX1(60), KYTY_INDEX_CX1(61), KYTY_INDEX_CX1(62), KYTY_INDEX_CX1(63), KYTY_INDEX_CX1(64), KYTY_INDEX_CX1(65), + KYTY_INDEX_CX1(66), KYTY_INDEX_CX1(67), KYTY_INDEX_CX1(68), KYTY_INDEX_CX1(69), KYTY_INDEX_CX1(70), KYTY_INDEX_CX1(71), + KYTY_INDEX_CX1(72), KYTY_INDEX_CX1(73), KYTY_INDEX_CX1(74), KYTY_INDEX_CX1(75), KYTY_INDEX_CX1(76), KYTY_INDEX_CX1(77), + KYTY_INDEX_SH1(0), KYTY_INDEX_SH1(1), KYTY_INDEX_SH1(2), KYTY_INDEX_SH1(3), KYTY_INDEX_SH1(4), KYTY_INDEX_SH1(5), + KYTY_INDEX_SH1(6), KYTY_INDEX_SH1(7), KYTY_INDEX_SH1(8), KYTY_INDEX_SH1(9), KYTY_INDEX_SH1(10), KYTY_INDEX_SH1(11), + KYTY_INDEX_SH1(12), KYTY_INDEX_SH1(13), KYTY_INDEX_SH1(14), KYTY_INDEX_SH1(15), KYTY_INDEX_SH1(16), KYTY_INDEX_SH1(17), + KYTY_INDEX_SH1(18), KYTY_INDEX_SH1(19), KYTY_INDEX_SH1(20), KYTY_INDEX_SH1(21), KYTY_INDEX_SH1(22), KYTY_INDEX_SH1(23), + KYTY_INDEX_SH1(24), KYTY_INDEX_SH1(25), KYTY_INDEX_SH1(26), KYTY_INDEX_SH1(27), KYTY_INDEX_SH1(28), KYTY_INDEX_UC1(0), + KYTY_INDEX_UC1(1), KYTY_INDEX_UC1(2), KYTY_INDEX_UC1(3), KYTY_INDEX_UC1(4), KYTY_INDEX_UC1(5), KYTY_INDEX_UC1(6), + KYTY_INDEX_UC1(7), KYTY_INDEX_UC1(8), KYTY_INDEX_UC1(9), KYTY_INDEX_UC1(10), KYTY_INDEX_UC1(11), KYTY_INDEX_UC1(12), + KYTY_INDEX_UC1(13), KYTY_INDEX_UC1(14), KYTY_INDEX_UC1(15), KYTY_INDEX_UC1(16), KYTY_INDEX_UC1(17), KYTY_INDEX_UC1(18), + KYTY_INDEX_UC1(19)}; + +static ShaderRegister* g_tbl_cx2[] = {KYTY_REG_CX2(0), KYTY_REG_CX2(1), KYTY_REG_CX2(2), KYTY_REG_CX2(3)}; +static ShaderRegister* g_tbl_sh2[] = {KYTY_REG_SH2(0), KYTY_REG_SH2(1), KYTY_REG_SH2(2), KYTY_REG_SH2(3), KYTY_REG_SH2(4), + KYTY_REG_SH2(5), KYTY_REG_SH2(6), KYTY_REG_SH2(7), KYTY_REG_SH2(8), KYTY_REG_SH2(9), + KYTY_REG_SH2(10), KYTY_REG_SH2(11), KYTY_REG_SH2(12), KYTY_REG_SH2(13), KYTY_REG_SH2(14)}; +static ShaderRegister* g_tbl_uc2[] = {KYTY_REG_UC2(0), KYTY_REG_UC2(1), KYTY_REG_UC2(2)}; +static uint32_t g_tbl_index2[] = {KYTY_INDEX_CX2(0), KYTY_INDEX_CX2(1), KYTY_INDEX_CX2(2), KYTY_INDEX_CX2(3), KYTY_INDEX_SH2(0), + KYTY_INDEX_SH2(1), KYTY_INDEX_SH2(2), KYTY_INDEX_SH2(3), KYTY_INDEX_SH2(4), KYTY_INDEX_SH2(5), + KYTY_INDEX_SH2(6), KYTY_INDEX_SH2(7), KYTY_INDEX_SH2(8), KYTY_INDEX_SH2(9), KYTY_INDEX_SH2(10), + KYTY_INDEX_SH2(11), KYTY_INDEX_SH2(12), KYTY_INDEX_SH2(13), KYTY_INDEX_SH2(14), KYTY_INDEX_UC2(0), + KYTY_INDEX_UC2(1), KYTY_INDEX_UC2(2)}; + +static RegisterDefaults g_reg_defaults1 = { // @suppress("Invalid arguments") + g_tbl_cx1, g_tbl_sh1, g_tbl_uc1, nullptr, {0, 0}, g_tbl_index1, sizeof(g_tbl_index1) / 12}; +static RegisterDefaults g_reg_defaults2 = { // @suppress("Invalid arguments") + g_tbl_cx2, g_tbl_sh2, g_tbl_uc2, nullptr, {0, 0}, g_tbl_index2, sizeof(g_tbl_index2) / 12}; int KYTY_SYSV_ABI GraphicsInit(uint32_t* state, uint32_t ver) { @@ -999,9 +1402,7 @@ void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2(uint32_t ver) EXIT_NOT_IMPLEMENTED(ver != 8); EXIT_NOT_IMPLEMENTED(offsetof(RegisterDefaults, count) != 0x38); - // g_reg_defaults.count = 0; - - return &g_reg_defaults; + return &g_reg_defaults1; } void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver) @@ -1011,9 +1412,7 @@ void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver) EXIT_NOT_IMPLEMENTED(ver != 8); EXIT_NOT_IMPLEMENTED(offsetof(RegisterDefaults, count) != 0x38); - g_reg_defaults.count = 0; - - return &g_reg_defaults; + return &g_reg_defaults2; } static void dbg_dump_shader(const Shader* h) @@ -1167,173 +1566,6 @@ int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatil return OK; } -uint32_t* KYTY_SYSV_ABI GraphicsDcbResetQueue(CommandBuffer* buf, uint32_t op, uint32_t state) -{ - PRINT_NAME(); - - printf("\t op = 0x%08" PRIx32 "\n", op); - printf("\t state = 0x%08" PRIx32 "\n", state); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - EXIT_NOT_IMPLEMENTED(op != 0x3ff); - EXIT_NOT_IMPLEMENTED(state != 0); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(2); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); - cmd[1] = 0; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf, uint32_t video_out_handle, uint32_t display_buffer_index) -{ - PRINT_NAME(); - - printf("\t video_out_handle = %" PRIu32 "\n", video_out_handle); - printf("\t display_buffer_index = %" PRIu32 "\n", display_buffer_index); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(3); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - cmd[0] = KYTY_PM4(3, Pm4::IT_NOP, Pm4::R_WAIT_FLIP_DONE); - cmd[1] = video_out_handle; - cmd[2] = display_buffer_index; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) -{ - PRINT_NAME(); - - printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); - printf("\t num_regs = %" PRIu32 "\n", num_regs); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(4); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - auto vaddr = reinterpret_cast(regs); - - cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_CX_REGS); - cmd[1] = num_regs; - cmd[2] = vaddr & 0xffffffffu; - cmd[3] = (vaddr >> 32u) & 0xffffffffu; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) -{ - PRINT_NAME(); - - printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); - printf("\t num_regs = %" PRIu32 "\n", num_regs); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(4); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - auto vaddr = reinterpret_cast(regs); - - cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_SH_REGS); - cmd[1] = num_regs; - cmd[2] = vaddr & 0xffffffffu; - cmd[3] = (vaddr >> 32u) & 0xffffffffu; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) -{ - PRINT_NAME(); - - printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); - printf("\t num_regs = %" PRIu32 "\n", num_regs); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(4); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - auto vaddr = reinterpret_cast(regs); - - cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_UC_REGS); - cmd[1] = num_regs; - cmd[2] = vaddr & 0xffffffffu; - cmd[3] = (vaddr >> 32u) & 0xffffffffu; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbSetIndexSize(CommandBuffer* buf, uint8_t index_size, uint8_t cache_policy) -{ - PRINT_NAME(); - - printf("\t index_size = 0x%" PRIx8 "\n", index_size); - printf("\t cache_policy = 0x%" PRIx8 "\n", cache_policy); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - EXIT_NOT_IMPLEMENTED(cache_policy != 0); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(2); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - cmd[0] = KYTY_PM4(2, Pm4::IT_INDEX_TYPE, 0u); - cmd[1] = index_size; - - return cmd; -} - -uint32_t* KYTY_SYSV_ABI GraphicsDcbDrawIndexAuto(CommandBuffer* buf, uint32_t index_count, uint64_t modifier) -{ - PRINT_NAME(); - - printf("\t index_count = 0x%" PRIx32 "\n", index_count); - printf("\t modifier = 0x%016" PRIx64 "\n", modifier); - - EXIT_NOT_IMPLEMENTED(buf == nullptr); - EXIT_NOT_IMPLEMENTED(modifier != 0x40000000); - - // auto *m = reinterpret_cast(&modifier); - - buf->DbgDump(); - - auto* cmd = buf->AllocateDW(7); - - EXIT_NOT_IMPLEMENTED(cmd == nullptr); - - cmd[0] = KYTY_PM4(7, Pm4::IT_NOP, Pm4::R_DRAW_INDEX_AUTO); - cmd[1] = index_count; - cmd[2] = 0; - - return cmd; -} - int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs) { PRINT_NAME(); @@ -1457,8 +1689,8 @@ int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegiste uc_regs[0] = gs->specials->ge_cntl; uc_regs[1] = gs->specials->ge_user_vgpr_en; - uc_regs[2].offset = Pm4::PRIMITIVE_TYPE; - uc_regs[2].value = 0; + uc_regs[2].offset = Pm4::VGT_PRIMITIVE_TYPE; + uc_regs[2].value = prim_type; return OK; } @@ -1500,6 +1732,32 @@ int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const S return OK; } +int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type) +{ + PRINT_NAME(); + + printf("\t addr = 0x%016" PRIx64 "\n", reinterpret_cast(addr)); + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t type = %d\n", type); + + EXIT_NOT_IMPLEMENTED(addr == nullptr); + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + EXIT_NOT_IMPLEMENTED(type != 1); + + *addr = cmd + 2; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSuspendPoint() +{ + PRINT_NAME(); + + GraphicsRunDone(); + + return OK; +} + uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset, const uint32_t* values, uint32_t num_values) { PRINT_NAME(); @@ -1534,25 +1792,422 @@ uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, u return cmd; } -int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type) +uint32_t* KYTY_SYSV_ABI GraphicsCbReleaseMem(CommandBuffer* buf, uint8_t action, uint16_t gcr_cntl, uint8_t dst, uint8_t cache_policy, + const volatile Label* address, uint8_t data_sel, uint64_t data, uint16_t gds_offset, + uint16_t gds_size, uint8_t interrupt, uint32_t interrupt_ctx_id) { PRINT_NAME(); - printf("\t addr = 0x%016" PRIx64 "\n", reinterpret_cast(addr)); - printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); - printf("\t type = %d\n", type); + printf("\t action = 0x%02" PRIx8 "\n", action); + printf("\t gcr_cntl = 0x%04" PRIx16 "\n", gcr_cntl); + printf("\t dst = %" PRIu8 "\n", dst); + printf("\t cache_policy = 0x%02" PRIx8 "\n", cache_policy); + printf("\t address = 0x%016" PRIx64 "\n", reinterpret_cast(address)); + printf("\t data_sel = 0x%02" PRIx8 "\n", data_sel); + printf("\t data = 0x%016" PRIx64 "\n", data); + printf("\t gds_offset = %" PRIu16 "\n", gds_offset); + printf("\t gds_size = %" PRIu16 "\n", gds_size); + printf("\t interrupt = 0x%02" PRIx8 "\n", interrupt); + printf("\t interrupt_ctx_id = %" PRIu32 "\n", interrupt_ctx_id); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(dst != 1); + EXIT_NOT_IMPLEMENTED(data_sel != 2); + EXIT_NOT_IMPLEMENTED(gds_offset != 0); + EXIT_NOT_IMPLEMENTED(gds_size != 1); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(10); - EXIT_NOT_IMPLEMENTED(addr == nullptr); EXIT_NOT_IMPLEMENTED(cmd == nullptr); - EXIT_NOT_IMPLEMENTED(type != 1); - *addr = cmd + 2; + cmd[0] = KYTY_PM4(10, Pm4::IT_NOP, Pm4::R_RELEASE_MEM); + cmd[1] = action; + cmd[2] = gcr_cntl; + cmd[3] = cache_policy; + cmd[4] = static_cast(reinterpret_cast(address) & 0xffffffffu); + cmd[5] = static_cast((reinterpret_cast(address) >> 32u) & 0xffffffffu); + cmd[6] = static_cast(data & 0xffffffffu); + cmd[7] = static_cast((data >> 32u) & 0xffffffffu); + cmd[8] = interrupt; + cmd[9] = interrupt_ctx_id; - return OK; + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbResetQueue(CommandBuffer* buf, uint32_t op, uint32_t state) +{ + PRINT_NAME(); + + printf("\t op = 0x%08" PRIx32 "\n", op); + printf("\t state = 0x%08" PRIx32 "\n", state); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(op != 0x3ff); + EXIT_NOT_IMPLEMENTED(state != 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); + cmd[1] = 0; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf, uint32_t video_out_handle, uint32_t display_buffer_index) +{ + PRINT_NAME(); + + printf("\t video_out_handle = %" PRIu32 "\n", video_out_handle); + printf("\t display_buffer_index = %" PRIu32 "\n", display_buffer_index); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(7); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(7, Pm4::IT_NOP, Pm4::R_WAIT_FLIP_DONE); + cmd[1] = video_out_handle; + cmd[2] = display_buffer_index; + cmd[3] = 0; + cmd[4] = 0; + cmd[5] = 0; + cmd[6] = 0; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_CX_REGS_INDIRECT); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_SH_REGS_INDIRECT); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_UC_REGS_INDIRECT); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetIndexSize(CommandBuffer* buf, uint8_t index_size, uint8_t cache_policy) +{ + PRINT_NAME(); + + printf("\t index_size = 0x%" PRIx8 "\n", index_size); + printf("\t cache_policy = 0x%" PRIx8 "\n", cache_policy); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(cache_policy != 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(2, Pm4::IT_INDEX_TYPE, 0u); + cmd[1] = index_size; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbDrawIndexAuto(CommandBuffer* buf, uint32_t index_count, uint64_t modifier) +{ + PRINT_NAME(); + + printf("\t index_count = 0x%" PRIx32 "\n", index_count); + printf("\t modifier = 0x%016" PRIx64 "\n", modifier); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(modifier != 0x40000000); + + // auto *m = reinterpret_cast(&modifier); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(7); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(7, Pm4::IT_NOP, Pm4::R_DRAW_INDEX_AUTO); + cmd[1] = index_count; + cmd[2] = 0; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbEventWrite(CommandBuffer* buf, uint8_t event_type, const volatile void* address) +{ + PRINT_NAME(); + + printf("\t event_type = 0x%02" PRIx8 "\n", event_type); + printf("\t address = 0x%016" PRIx64 "\n", reinterpret_cast(address)); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(address != nullptr); + EXIT_NOT_IMPLEMENTED(event_type > 0x3fu); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + uint32_t event_index = 0; + + cmd[0] = KYTY_PM4(2, Pm4::IT_EVENT_WRITE, 0u); + cmd[1] = (event_index << 8u) | event_type; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbAcquireMem(CommandBuffer* buf, uint8_t engine, uint32_t cb_db_op, uint32_t gcr_cntl, + const volatile void* base, uint64_t size_bytes, uint32_t poll_cycles) +{ + PRINT_NAME(); + + printf("\t engine = 0x%02" PRIx8 "\n", engine); + printf("\t cb_db_op = 0x%08" PRIx32 "\n", cb_db_op); + printf("\t gcr_cntl = 0x%08" PRIx32 "\n", gcr_cntl); + printf("\t base = 0x%016" PRIx64 "\n", reinterpret_cast(base)); + printf("\t size_bytes = 0x%016" PRIx64 "\n", size_bytes); + printf("\t poll_cycles = %" PRIu32 "\n", poll_cycles); + + bool no_size = (static_cast(size_bytes) == -1); + auto vaddr = reinterpret_cast(base); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(!no_size && (size_bytes && 0xffu) != 0); + EXIT_NOT_IMPLEMENTED(!no_size && (size_bytes >> 40u) != 0); + EXIT_NOT_IMPLEMENTED((vaddr && 0xffu) != 0); + EXIT_NOT_IMPLEMENTED((vaddr >> 40u) != 0); + EXIT_NOT_IMPLEMENTED(engine > 1); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(8); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(8, Pm4::IT_NOP, Pm4::R_ACQUIRE_MEM); + cmd[1] = (static_cast(engine) << 31u) | cb_db_op; + cmd[2] = (no_size ? 0 : size_bytes >> 8u); + cmd[3] = 0; + cmd[4] = vaddr >> 8u; + cmd[5] = 0; + cmd[6] = poll_cycles / 40; + cmd[7] = gcr_cntl; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbWriteData(CommandBuffer* buf, uint8_t dst, uint8_t cache_policy, uint64_t address_or_offset, + const void* data, uint32_t num_dwords, uint8_t increment, uint8_t write_confirm) +{ + PRINT_NAME(); + + printf("\t dst = 0x%02" PRIx8 "\n", dst); + printf("\t cache_policy = 0x%02" PRIx8 "\n", cache_policy); + printf("\t address_or_offset = 0x%016" PRIx64 "\n", address_or_offset); + printf("\t data = 0x%016" PRIx64 "\n", reinterpret_cast(data)); + printf("\t num_dwords = %" PRIu32 "\n", num_dwords); + printf("\t increment = 0x%02" PRIx8 "\n", increment); + printf("\t write_confirm = 0x%02" PRIx8 "\n", write_confirm); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED((8 + num_dwords - 2u) > 0x3fffu); + EXIT_NOT_IMPLEMENTED(data == nullptr); + EXIT_NOT_IMPLEMENTED(address_or_offset == 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(8 + num_dwords); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(8 + num_dwords, Pm4::IT_NOP, Pm4::R_WRITE_DATA); + cmd[1] = dst; + cmd[2] = cache_policy; + cmd[3] = address_or_offset & 0xffffffffu; + cmd[4] = (address_or_offset >> 32u) & 0xffffffffu; + cmd[5] = num_dwords; + cmd[6] = increment; + cmd[7] = write_confirm; + + memcpy(cmd + 8, data, static_cast(num_dwords) * 4); + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitRegMem(CommandBuffer* buf, uint8_t size, uint8_t compare_function, uint8_t op, uint8_t cache_policy, + const volatile void* address, uint64_t reference, uint64_t mask, uint32_t poll_cycles) +{ + PRINT_NAME(); + + printf("\t size = 0x%02" PRIx8 "\n", size); + printf("\t compare_function = 0x%02" PRIx8 "\n", compare_function); + printf("\t op = 0x%02" PRIx8 "\n", op); + printf("\t cache_policy = 0x%02" PRIx8 "\n", cache_policy); + printf("\t address = 0x%016" PRIx64 "\n", reinterpret_cast(address)); + printf("\t reference = 0x%016" PRIx64 "\n", reference); + printf("\t mask = 0x%016" PRIx64 "\n", mask); + printf("\t poll_cycles = %" PRIu32 "\n", poll_cycles); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(size != 1); + EXIT_NOT_IMPLEMENTED(op != 1); + EXIT_NOT_IMPLEMENTED(cache_policy != 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(9); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(9, Pm4::IT_NOP, Pm4::R_WAIT_MEM_64); + cmd[1] = static_cast(reinterpret_cast(address) & 0xffffffffu); + cmd[2] = static_cast((reinterpret_cast(address) >> 32u) & 0xffffffffu); + cmd[3] = static_cast(reinterpret_cast(mask) & 0xffffffffu); + cmd[4] = static_cast((reinterpret_cast(mask) >> 32u) & 0xffffffffu); + cmd[5] = static_cast(reinterpret_cast(reference) & 0xffffffffu); + cmd[6] = static_cast((reinterpret_cast(reference) >> 32u) & 0xffffffffu); + cmd[7] = compare_function; + cmd[8] = poll_cycles / 40; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetFlip(CommandBuffer* buf, uint32_t video_out_handle, int32_t display_buffer_index, uint32_t flip_mode, + int64_t flip_arg) +{ + PRINT_NAME(); + + printf("\t video_out_handle = %" PRIu32 "\n", video_out_handle); + printf("\t display_buffer_index = %" PRId32 "\n", display_buffer_index); + printf("\t flip_mode = %" PRIu32 "\n", flip_mode); + printf("\t flip_arg = %" PRId64 "\n", flip_arg); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(6); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(6, Pm4::IT_NOP, Pm4::R_FLIP); + cmd[1] = video_out_handle; + cmd[2] = display_buffer_index; + cmd[3] = flip_mode; + cmd[4] = static_cast(static_cast(flip_arg) & 0xffffffffu); + cmd[5] = static_cast((static_cast(flip_arg) >> 32u) & 0xffffffffu); + + return cmd; } } // namespace Gen5 +namespace Gen5Driver { + +LIB_NAME("Graphics5Driver", "Graphics5Driver"); + +struct Packet +{ + uint32_t* addr; + uint32_t dw_num; + uint8_t pad[4]; +}; + +int KYTY_SYSV_ABI GraphicsDriverSubmitDcb(const Packet* packet) +{ + PRINT_NAME(); + + EXIT_NOT_IMPLEMENTED(packet == nullptr); + EXIT_NOT_IMPLEMENTED(packet->pad[0] != 0); + + printf("\t addr = 0x%016" PRIx64 "\n", reinterpret_cast(packet->addr)); + printf("\t dw_num = 0x%08" PRIx32 "\n", packet->dw_num); + + GraphicsDbgDumpDcb("d", packet->dw_num, packet->addr); + + GraphicsRunSubmit(packet->addr, packet->dw_num, nullptr, 0); + + return OK; +} + +} // namespace Gen5Driver + } // namespace Kyty::Libs::Graphics #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/src/Graphics/GraphicsRender.cpp b/source/emulator/src/Graphics/GraphicsRender.cpp index fb9f5da..50586a9 100644 --- a/source/emulator/src/Graphics/GraphicsRender.cpp +++ b/source/emulator/src/Graphics/GraphicsRender.cpp @@ -138,9 +138,10 @@ public: KYTY_CLASS_NO_COPY(PipelineCache); VulkanPipeline* CreatePipeline(VulkanFramebuffer* framebuffer, RenderColorInfo* color, RenderDepthInfo* depth, - const ShaderVertexInputInfo* vs_input_info, HW::HardwareContext* ctx, + const ShaderVertexInputInfo* vs_input_info, HW::Context* ctx, HW::Shader* sh_ctx, const ShaderPixelInputInfo* ps_input_info, VkPrimitiveTopology topology); - VulkanPipeline* CreatePipeline(const ShaderComputeInputInfo* input_info, const HW::ComputeShaderInfo* cs_regs); + VulkanPipeline* CreatePipeline(const ShaderComputeInputInfo* input_info, const HW::ComputeShaderInfo* cs_regs, + const HW::ShaderRegisters* sh_regs); void DeletePipeline(VulkanPipeline* pipeline); void DeletePipelines(VulkanFramebuffer* framebuffer); void DeleteAllPipelines(); @@ -468,10 +469,14 @@ static void uc_print(const char* func, const HW::UserConfig& uc) printf("\t GetPrimType() = 0x%08" PRIx32 "\n", uc.GetPrimType()); } -// void uc_check(const UserConfig& uc) -//{ -// EXIT_NOT_IMPLEMENTED(uc.GetPrimType() != 4); -//} +static void uc_check(const HW::UserConfig& /*uc*/) {} + +static void sh_print(const char* func, const HW::Shader& /*uc*/) +{ + printf("%s\n", func); +} + +static void sh_check(const HW::Shader& /*uc*/) {} static Core::StringList rt_print(const char* func, const HW::RenderTarget& rt) { @@ -679,14 +684,14 @@ static void clip_print(const char* func, const HW::ClipControl& c) { printf("%s\n", func); - printf("\t user_clip_planes = 0x%08" PRIx32 "\n", c.user_clip_planes); - printf("\t user_clip_plane_mode = 0x%08" PRIx32 "\n", c.user_clip_plane_mode); - printf("\t clip_space = 0x%08" PRIx32 "\n", c.clip_space); - printf("\t vertex_kill_mode = 0x%08" PRIx32 "\n", c.vertex_kill_mode); - printf("\t min_z_clip_enable = 0x%08" PRIx32 "\n", c.min_z_clip_enable); - printf("\t max_z_clip_enable = 0x%08" PRIx32 "\n", c.max_z_clip_enable); + printf("\t user_clip_planes = 0x%02" PRIx8 "\n", c.user_clip_planes); + printf("\t user_clip_plane_mode = 0x%02" PRIx8 "\n", c.user_clip_plane_mode); + printf("\t dx_clip_space = %s\n", c.dx_clip_space ? "true" : "false"); + printf("\t vertex_kill_any = %s\n", c.vertex_kill_any ? "true" : "false"); + printf("\t min_z_clip_disable = %s\n", c.min_z_clip_disable ? "true" : "false"); + printf("\t max_z_clip_disable = %s\n", c.max_z_clip_disable ? "true" : "false"); printf("\t user_clip_plane_negate_y = %s\n", c.user_clip_plane_negate_y ? "true" : "false"); - printf("\t clip_enable = %s\n", c.clip_enable ? "true" : "false"); + printf("\t clip_disable = %s\n", c.clip_disable ? "true" : "false"); printf("\t user_clip_plane_cull_only = %s\n", c.user_clip_plane_cull_only ? "true" : "false"); printf("\t cull_on_clipping_error_disable = %s\n", c.cull_on_clipping_error_disable ? "true" : "false"); printf("\t linear_attribute_clip_enable = %s\n", c.linear_attribute_clip_enable ? "true" : "false"); @@ -697,12 +702,12 @@ static void clip_check(const HW::ClipControl& c) { EXIT_NOT_IMPLEMENTED(c.user_clip_planes != 0); EXIT_NOT_IMPLEMENTED(c.user_clip_plane_mode != 0); - EXIT_NOT_IMPLEMENTED(c.clip_space != 0); - EXIT_NOT_IMPLEMENTED(c.vertex_kill_mode != 0); - EXIT_NOT_IMPLEMENTED(c.min_z_clip_enable != 0); - EXIT_NOT_IMPLEMENTED(c.max_z_clip_enable != 0); + EXIT_NOT_IMPLEMENTED(c.dx_clip_space != false); + EXIT_NOT_IMPLEMENTED(c.vertex_kill_any != false); + EXIT_NOT_IMPLEMENTED(c.min_z_clip_disable != false); + EXIT_NOT_IMPLEMENTED(c.max_z_clip_disable != false); EXIT_NOT_IMPLEMENTED(c.user_clip_plane_negate_y != false); - EXIT_NOT_IMPLEMENTED(c.clip_enable != false); + EXIT_NOT_IMPLEMENTED(c.clip_disable != false); EXIT_NOT_IMPLEMENTED(c.user_clip_plane_cull_only != false); EXIT_NOT_IMPLEMENTED(c.cull_on_clipping_error_disable != false); EXIT_NOT_IMPLEMENTED(c.linear_attribute_clip_enable != false); @@ -986,7 +991,7 @@ static void vp_check(const HW::ScreenViewport& vp, const HW::ScanModeControl& sm EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_window_offset_enable != false); } -static void hw_check(const HW::HardwareContext& hw) +static void hw_check(const HW::Context& hw) { const auto& rt = hw.GetRenderTarget(0); const auto& bc = hw.GetBlendControl(0); @@ -1021,7 +1026,7 @@ static void hw_check(const HW::HardwareContext& hw) // EXIT_NOT_IMPLEMENTED(hw.GetStencilClearValue() != 0); } -static void hw_print(const HW::HardwareContext& hw) +static void hw_print(const HW::Context& hw) { const auto& rt = hw.GetRenderTarget(0); const auto& bc = hw.GetBlendControl(0); @@ -1042,7 +1047,7 @@ static void hw_print(const HW::HardwareContext& hw) if (Kyty::Log::GetDirection() != Kyty::Log::Direction::Silent) { - printf("HardwareContext\n"); + printf("Context\n"); printf("\t GetRenderTargetMask() = 0x%08" PRIx32 "\n", hw.GetRenderTargetMask()); printf("\t GetDepthClearValue() = %f\n", hw.GetDepthClearValue()); printf("\t GetStencilClearValue() = %" PRIu8 "\n", hw.GetStencilClearValue()); @@ -2345,7 +2350,7 @@ VulkanPipeline* PipelineCache::Find(const Pipeline& p) const } VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, RenderColorInfo* color, RenderDepthInfo* depth, - const ShaderVertexInputInfo* vs_input_info, HW::HardwareContext* ctx, + const ShaderVertexInputInfo* vs_input_info, HW::Context* ctx, HW::Shader* sh_ctx, const ShaderPixelInputInfo* ps_input_info, VkPrimitiveTopology topology) { KYTY_PROFILER_BLOCK("PipelineCache::CreatePipeline(Gfx)", profiler::colors::DeepOrangeA200); @@ -2356,8 +2361,9 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re Core::LockGuard lock(m_mutex); - const auto& vs_regs = ctx->GetVs(); - const auto& ps_regs = ctx->GetPs(); + const auto& vs_regs = sh_ctx->GetVs(); + const auto& ps_regs = sh_ctx->GetPs(); + const auto& sh_regs = ctx->GetShaderRegisters(); const HW::BlendColor& bclr = ctx->GetBlendColor(); const HW::ScreenViewport& vp = ctx->GetScreenViewport(); const auto& bc = ctx->GetBlendControl(0); @@ -2445,8 +2451,8 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re return found; } - auto vs_code = ShaderParseVS(&vs_regs); - auto ps_code = ShaderParsePS(&ps_regs); + auto vs_code = ShaderParseVS(&vs_regs, &sh_regs); + auto ps_code = ShaderParsePS(&ps_regs, &sh_regs); auto vs_shader = ShaderRecompileVS(vs_code, vs_input_info); auto ps_shader = ShaderRecompilePS(ps_code, ps_input_info); @@ -2497,11 +2503,13 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re return p.pipeline; } -VulkanPipeline* PipelineCache::CreatePipeline(const ShaderComputeInputInfo* input_info, const HW::ComputeShaderInfo* cs_regs) +VulkanPipeline* PipelineCache::CreatePipeline(const ShaderComputeInputInfo* input_info, const HW::ComputeShaderInfo* cs_regs, + const HW::ShaderRegisters* sh_regs) { KYTY_PROFILER_BLOCK("PipelineCache::CreatePipeline(Compute)", profiler::colors::RedA100); EXIT_IF(cs_regs == nullptr); + EXIT_IF(sh_regs == nullptr); Core::LockGuard lock(m_mutex); @@ -2530,7 +2538,7 @@ VulkanPipeline* PipelineCache::CreatePipeline(const ShaderComputeInputInfo* inpu return found; } - auto cs_code = ShaderParseCS(cs_regs); + auto cs_code = ShaderParseCS(cs_regs, sh_regs); auto cs_shader = ShaderRecompileCS(cs_code, input_info); EXIT_IF(cs_shader.IsEmpty()); @@ -3612,7 +3620,7 @@ void GraphicsRenderDepthStencilBarrier(CommandBuffer* buffer, uint64_t vaddr, ui } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, const HW::HardwareContext& hw, RenderDepthInfo* r) +static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, const HW::Context& hw, RenderDepthInfo* r) { KYTY_PROFILER_FUNCTION(); @@ -3772,7 +3780,7 @@ static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, c } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -static void FindRenderColorInfo(uint64_t submit_id, CommandBuffer* buffer, const HW::HardwareContext& hw, RenderColorInfo* r) +static void FindRenderColorInfo(uint64_t submit_id, CommandBuffer* buffer, const HW::Context& hw, RenderColorInfo* r) { KYTY_PROFILER_FUNCTION(); @@ -4313,7 +4321,7 @@ static void SetDynamicParams(VkCommandBuffer vk_buffer, VulkanPipeline* pipeline } } -void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, HW::UserConfig* ucfg, +void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::UserConfig* ucfg, HW::Shader* sh_ctx, uint32_t index_type_and_size, uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type) { KYTY_PROFILER_FUNCTION(); @@ -4326,17 +4334,21 @@ void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Hard Core::LockGuard lock(g_render_ctx->GetMutex()); - if (const auto& vs = ctx->GetVs(); !vs.vs_embedded && ShaderIsDisabled(vs.vs_regs.GetGpuAddress())) + if (const auto& vs = sh_ctx->GetVs(); !vs.vs_embedded && ShaderIsDisabled(vs.vs_regs.GetGpuAddress())) { return; } - if (const auto& ps = ctx->GetPs(); !ps.ps_embedded && ShaderIsDisabled(ps.ps_regs.data_addr)) + if (const auto& ps = sh_ctx->GetPs(); !ps.ps_embedded && ShaderIsDisabled(ps.ps_regs.data_addr)) { return; } + sh_print("GraphicsRenderDrawIndex():Shader:", *sh_ctx); + sh_check(*sh_ctx); + uc_print("GraphicsRenderDrawIndex():UserConfig:", *ucfg); + uc_check(*ucfg); hw_print(*ctx); hw_check(*ctx); @@ -4394,12 +4406,12 @@ void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Hard auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()]; ShaderVertexInputInfo vs_input_info; - ShaderGetInputInfoVS(&ctx->GetVs(), &vs_input_info); + ShaderGetInputInfoVS(&sh_ctx->GetVs(), &ctx->GetShaderRegisters(), &vs_input_info); ShaderPixelInputInfo ps_input_info; - ShaderGetInputInfoPS(&ctx->GetPs(), &vs_input_info, &ps_input_info); + ShaderGetInputInfoPS(&sh_ctx->GetPs(), &ctx->GetShaderRegisters(), &vs_input_info, &ps_input_info); - auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(framebuffer, &color_info, &depth_info, &vs_input_info, ctx, + auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(framebuffer, &color_info, &depth_info, &vs_input_info, ctx, sh_ctx, &ps_input_info, topology); // EXIT_NOT_IMPLEMENTED(vs_input_info.buffers_num > 1); @@ -4459,7 +4471,7 @@ void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Hard } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, HW::UserConfig* ucfg, +void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::UserConfig* ucfg, HW::Shader* sh_ctx, uint32_t index_count, uint32_t flags) { KYTY_PROFILER_FUNCTION(); @@ -4470,17 +4482,21 @@ void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW:: Core::LockGuard lock(g_render_ctx->GetMutex()); - if (const auto& vs = ctx->GetVs(); !vs.vs_embedded && ShaderIsDisabled(vs.vs_regs.GetGpuAddress())) + if (const auto& vs = sh_ctx->GetVs(); !vs.vs_embedded && ShaderIsDisabled(vs.vs_regs.GetGpuAddress())) { return; } - if (const auto& ps = ctx->GetPs(); !ps.ps_embedded && ShaderIsDisabled(ps.ps_regs.data_addr)) + if (const auto& ps = sh_ctx->GetPs(); !ps.ps_embedded && ShaderIsDisabled(ps.ps_regs.data_addr)) { return; } + sh_print("GraphicsRenderDrawIndexAuto():Shader:", *sh_ctx); + sh_check(*sh_ctx); + uc_print("GraphicsRenderDrawIndexAuto():UserConfig:", *ucfg); + uc_check(*ucfg); hw_print(*ctx); hw_check(*ctx); @@ -4515,16 +4531,17 @@ void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW:: default: EXIT("unknown primitive type: %u\n", ucfg->GetPrimType()); } - const auto& vertex_shader_info = ctx->GetVs(); - const auto& pixel_shader_info = ctx->GetPs(); + const auto& vertex_shader_info = sh_ctx->GetVs(); + const auto& pixel_shader_info = sh_ctx->GetPs(); + const auto& shader_regs = ctx->GetShaderRegisters(); ShaderVertexInputInfo vs_input_info; - ShaderGetInputInfoVS(&vertex_shader_info, &vs_input_info); + ShaderGetInputInfoVS(&vertex_shader_info, &shader_regs, &vs_input_info); ShaderPixelInputInfo ps_input_info; - ShaderGetInputInfoPS(&pixel_shader_info, &vs_input_info, &ps_input_info); + ShaderGetInputInfoPS(&pixel_shader_info, &shader_regs, &vs_input_info, &ps_input_info); - auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(framebuffer, &color_info, &depth_info, &vs_input_info, ctx, + auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(framebuffer, &color_info, &depth_info, &vs_input_info, ctx, sh_ctx, &ps_input_info, topology); // EXIT_NOT_IMPLEMENTED(vs_input_info.buffers_num > 1); @@ -4578,7 +4595,7 @@ void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW:: InvalidateMemoryObject(depth_info); } -void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW::HardwareContext* ctx, uint32_t thread_group_x, +void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW::Context* ctx, HW::Shader* sh_ctx, uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode) { EXIT_IF(ctx == nullptr); @@ -4588,21 +4605,22 @@ void GraphicsRenderDispatchDirect(uint64_t submit_id, CommandBuffer* buffer, HW: Core::LockGuard lock(g_render_ctx->GetMutex()); - if (ShaderIsDisabled(ctx->GetCs().cs_regs.data_addr)) + if (ShaderIsDisabled(sh_ctx->GetCs().cs_regs.data_addr)) { return; } EXIT_NOT_IMPLEMENTED(mode != 0); - const auto& cs_regs = ctx->GetCs(); + const auto& cs_regs = sh_ctx->GetCs(); + const auto& sh_regs = ctx->GetShaderRegisters(); ShaderComputeInputInfo input_info; - ShaderGetInputInfoCS(&cs_regs, &input_info); + ShaderGetInputInfoCS(&cs_regs, &sh_regs, &input_info); auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()]; - auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(&input_info, &ctx->GetCs()); + auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(&input_info, &sh_ctx->GetCs(), &ctx->GetShaderRegisters()); vkCmdBindPipeline(vk_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->pipeline); diff --git a/source/emulator/src/Graphics/GraphicsRun.cpp b/source/emulator/src/Graphics/GraphicsRun.cpp index 458b069..7407760 100644 --- a/source/emulator/src/Graphics/GraphicsRun.cpp +++ b/source/emulator/src/Graphics/GraphicsRun.cpp @@ -23,7 +23,15 @@ #define KYTY_HW_CTX_PARSER_ARGS \ [[maybe_unused]] CommandProcessor *cp, uint32_t cmd_id, [[maybe_unused]] uint32_t cmd_offset, const uint32_t *buffer, \ [[maybe_unused]] uint32_t dw +#define KYTY_HW_UC_PARSER_ARGS \ + [[maybe_unused]] CommandProcessor *cp, uint32_t cmd_id, [[maybe_unused]] uint32_t cmd_offset, const uint32_t *buffer, \ + [[maybe_unused]] uint32_t dw +#define KYTY_HW_SH_PARSER_ARGS \ + [[maybe_unused]] CommandProcessor *cp, uint32_t cmd_id, [[maybe_unused]] uint32_t cmd_offset, const uint32_t *buffer, \ + [[maybe_unused]] uint32_t dw #define KYTY_HW_CTX_PARSER(f) static uint32_t f(KYTY_HW_CTX_PARSER_ARGS) +#define KYTY_HW_UC_PARSER(f) static uint32_t f(KYTY_HW_UC_PARSER_ARGS) +#define KYTY_HW_SH_PARSER(f) static uint32_t f(KYTY_HW_SH_PARSER_ARGS) #define KYTY_CP_OP_PARSER_ARGS \ [[maybe_unused]] CommandProcessor *cp, [[maybe_unused]] uint32_t cmd_id, [[maybe_unused]] const uint32_t *buffer, \ @@ -59,8 +67,9 @@ public: void Lock() { m_mutex.Lock(); } void Unlock() { m_mutex.Unlock(); } - HW::HardwareContext* GetCtx() { return &m_ctx; } - HW::UserConfig* GetUcfg() { return &m_ucfg; } + HW::Context* GetCtx() { return &m_ctx; } + HW::UserConfig* GetUcfg() { return &m_ucfg; } + HW::Shader* GetShCtx() { return &m_sh_ctx; } void SetIndexType(uint32_t index_type_and_size); void SetNumInstances(uint32_t num_instances); @@ -125,11 +134,12 @@ private: uint32_t value = 0; }; - HW::HardwareContext m_ctx; - HW::UserConfig m_ucfg; - HW::UserSgprType m_user_data_marker = HW::UserSgprType::Unknown; - uint32_t m_index_type_and_size = 0; - uint32_t m_num_instances = 1; + HW::Context m_ctx; + HW::UserConfig m_ucfg; + HW::Shader m_sh_ctx; + HW::UserSgprType m_user_data_marker = HW::UserSgprType::Unknown; + uint32_t m_index_type_and_size = 0; + uint32_t m_num_instances = 1; Core::Mutex m_mutex; Core::Mutex m_run_mutex; @@ -297,13 +307,19 @@ private: int m_done_num = 0; }; -using hw_ctx_parser_func_t = uint32_t (*)(KYTY_HW_CTX_PARSER_ARGS); -using cp_op_ctx_parser_func_t = uint32_t (*)(KYTY_CP_OP_PARSER_ARGS); +using hw_ctx_parser_func_t = uint32_t (*)(KYTY_HW_CTX_PARSER_ARGS); +using hw_uc_parser_func_t = uint32_t (*)(KYTY_HW_UC_PARSER_ARGS); +using hw_sh_parser_func_t = uint32_t (*)(KYTY_HW_SH_PARSER_ARGS); +using cp_op_parser_func_t = uint32_t (*)(KYTY_CP_OP_PARSER_ARGS); -static hw_ctx_parser_func_t g_hw_ctx_func[1024] = {}; -// static uint32_t g_hw_ctx_param[1024] = {}; -static cp_op_ctx_parser_func_t g_cp_op_func[256] = {}; -static Gpu* g_gpu = nullptr; +static hw_ctx_parser_func_t g_hw_ctx_func[Pm4::CX_NUM] = {}; +static hw_sh_parser_func_t g_hw_sh_func[Pm4::SH_NUM] = {}; +static hw_sh_parser_func_t g_hw_uc_func[Pm4::UC_NUM] = {}; +static hw_sh_parser_func_t g_hw_sh_custom_func[Pm4::R_NUM] = {}; +static cp_op_parser_func_t g_cp_op_func[256] = {}; +static cp_op_parser_func_t g_cp_op_custom_func[Pm4::R_NUM] = {}; + +static Gpu* g_gpu = nullptr; static void graphics_init_jmp_tables(); @@ -496,6 +512,7 @@ void CommandProcessor::Reset() GraphicsRenderDeleteIndexBuffers(); + m_sh_ctx.Reset(); m_ucfg.Reset(); m_ctx.Reset(); m_index_type_and_size = 0; @@ -1013,8 +1030,8 @@ void CommandProcessor::DrawIndex(uint32_t index_count, const void* index_addr, u EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM); - GraphicsRenderDrawIndex(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, m_index_type_and_size, index_count, index_addr, flags, - type); + GraphicsRenderDrawIndex(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, &m_sh_ctx, m_index_type_and_size, index_count, + index_addr, flags, type); } void CommandProcessor::DispatchDirect(uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode) @@ -1023,7 +1040,8 @@ void CommandProcessor::DispatchDirect(uint32_t thread_group_x, uint32_t thread_g EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM); - GraphicsRenderDispatchDirect(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, thread_group_x, thread_group_y, thread_group_z, mode); + GraphicsRenderDispatchDirect(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_sh_ctx, thread_group_x, thread_group_y, thread_group_z, + mode); } void CommandProcessor::DrawIndexAuto(uint32_t index_count, uint32_t flags) @@ -1032,7 +1050,7 @@ void CommandProcessor::DrawIndexAuto(uint32_t index_count, uint32_t flags) EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM); - GraphicsRenderDrawIndexAuto(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, index_count, flags); + GraphicsRenderDrawIndexAuto(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, &m_sh_ctx, index_count, flags); } void CommandProcessor::ClearGds(uint64_t dw_offset, uint32_t dw_num, uint32_t clear_value) @@ -1366,6 +1384,197 @@ void GraphicsRunCommandProcessorUnlock(CommandProcessor* cp) cp->Unlock(); } +KYTY_HW_CTX_PARSER(hw_ctx_set_aa_config) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_CONFIG); + + HW::AaConfig r; + + r.msaa_num_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_NUM_SAMPLES); + r.aa_mask_centroid_dtmn = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, AA_MASK_CENTROID_DTMN) != 0; + r.max_sample_dist = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MAX_SAMPLE_DIST); + r.msaa_exposed_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_EXPOSED_SAMPLES); + + cp->GetCtx()->SetAaConfig(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_aa_sample_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0106900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0); + + uint32_t count = 1; + + if (dw >= 20 && buffer[16] == 0xc0026900 && buffer[17] == Pm4::PA_SC_CENTROID_PRIORITY_0) + { + count = 20; + + HW::AaSampleControl r; + + memcpy(r.locations, buffer, static_cast(16) * 4); + + r.centroid_priority = static_cast(buffer[18]) | (static_cast(buffer[19]) << 32u); + + cp->GetCtx()->SetAaSampleControl(r); + } else + { + KYTY_NOT_IMPLEMENTED; + } + + return count; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_blend_color) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0046900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_BLEND_RED); + + HW::BlendColor r; + + r.red = *reinterpret_cast(&buffer[0]); + r.green = *reinterpret_cast(&buffer[1]); + r.blue = *reinterpret_cast(&buffer[2]); + r.alpha = *reinterpret_cast(&buffer[3]); + + cp->GetCtx()->SetBlendColor(r); + + return 4; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_blend_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + + uint32_t param = (cmd_offset - Pm4::CB_BLEND0_CONTROL) / 1; + + HW::BlendControl r; + + r.color_srcblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_SRCBLEND_MASK; + r.color_comb_fcn = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_COMB_FCN_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_COMB_FCN_MASK; + r.color_destblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_DESTBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_DESTBLEND_MASK; + r.alpha_srcblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_SRCBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_SRCBLEND_MASK; + r.alpha_comb_fcn = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_COMB_FCN_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_COMB_FCN_MASK; + r.alpha_destblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_DESTBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_DESTBLEND_MASK; + r.separate_alpha_blend = + ((buffer[0] >> Pm4::CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_MASK) != 0; + r.enable = ((buffer[0] >> Pm4::CB_BLEND0_CONTROL_ENABLE_SHIFT) & Pm4::CB_BLEND0_CONTROL_ENABLE_MASK) != 0; + + cp->GetCtx()->SetBlendControl(param, r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_clip_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_CL_CLIP_CNTL); + + HW::ClipControl r; + + // r.user_clip_planes = buffer[0] & 0x3fu; + // r.user_clip_plane_mode = (buffer[0] >> 14u) & 0x3u; + // r.clip_space = (buffer[0] >> 19u) & 0x1u; + // r.vertex_kill_mode = (buffer[0] >> 21u) & 0x1u; + // r.min_z_clip_enable = (buffer[0] >> 26u) & 0x1u; + // r.max_z_clip_enable = (buffer[0] >> 27u) & 0x1u; + // r.user_clip_plane_negate_y = (buffer[0] & 0x00002000u) != 0; + // r.clip_enable = (buffer[0] & 0x00010000u) != 0; + // r.user_clip_plane_cull_only = (buffer[0] & 0x00020000u) != 0; + // r.cull_on_clipping_error_disable = (buffer[0] & 0x00100000u) != 0; + // r.linear_attribute_clip_enable = (buffer[0] & 0x01000000u) != 0; + // r.force_viewport_index_from_vs_enable = (buffer[0] & 0x02000000u) != 0; + + r.user_clip_planes = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, UCP_ENA); + r.user_clip_plane_mode = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, PS_UCP_MODE); + r.dx_clip_space = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, DX_CLIP_SPACE_DEF) != 0; + r.vertex_kill_any = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, VTX_KILL_OR) != 0; + r.min_z_clip_disable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, ZCLIP_NEAR_DISABLE) != 0; + r.max_z_clip_disable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, ZCLIP_FAR_DISABLE) != 0; + r.user_clip_plane_negate_y = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, PS_UCP_Y_SCALE_NEG) != 0; + r.clip_disable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, CLIP_DISABLE) != 0; + r.user_clip_plane_cull_only = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, UCP_CULL_ONLY_ENA) != 0; + r.cull_on_clipping_error_disable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, DIS_CLIP_ERR_DETECT) != 0; + r.linear_attribute_clip_enable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, DX_LINEAR_ATTR_CLIP_ENA) != 0; + r.force_viewport_index_from_vs_enable = KYTY_PM4_GET(buffer[0], PA_CL_CLIP_CNTL, VTE_VPORT_PROVOKE_DISABLE) != 0; + + cp->GetCtx()->SetClipControl(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_color_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_COLOR_CONTROL); + + HW::ColorControl r; + + r.mode = KYTY_PM4_GET(buffer[0], CB_COLOR_CONTROL, MODE); + r.op = KYTY_PM4_GET(buffer[0], CB_COLOR_CONTROL, ROP3); + + cp->GetCtx()->SetColorControl(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_color_info) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); + + uint32_t param = (cmd_offset - Pm4::CB_COLOR0_INFO) / 15; + + HW::ColorInfo r; + + r.fmask_compression_enable = (buffer[4] & 0x4000u) != 0; + r.fmask_compression_mode = (buffer[4] >> 26u) & 0x3u; + r.cmask_fast_clear_enable = (buffer[4] & 0x2000u) != 0; + r.dcc_compression_enable = (buffer[4] & 0x10000000u) != 0; + r.neo_mode = (buffer[4] & 0x80000000u) != 0; + r.cmask_tile_mode = (buffer[4] >> 19u) & 0x1u; + r.cmask_tile_mode_neo = (buffer[4] >> 29u) & 0x3u; + r.format = (buffer[4] >> 2u) & 0x1fu; + r.channel_type = (buffer[4] >> 8u) & 0x7u; + r.channel_order = (buffer[4] >> 11u) & 0x3u; + + cp->GetCtx()->SetColorInfo(param, r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_depth_clear) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_DEPTH_CLEAR); + + cp->GetCtx()->SetDepthClearValue(*reinterpret_cast(buffer)); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_depth_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_DEPTH_CONTROL); + + HW::DepthControl r; + + r.stencil_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCIL_ENABLE) != 0; + r.z_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, Z_ENABLE) != 0; + r.z_write_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, Z_WRITE_ENABLE) != 0; + r.depth_bounds_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, DEPTH_BOUNDS_ENABLE) != 0; + r.zfunc = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, ZFUNC); + r.backface_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, BACKFACE_ENABLE) != 0; + r.stencilfunc = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCILFUNC); + r.stencilfunc_bf = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCILFUNC_BF); + + cp->GetCtx()->SetDepthControl(r); + + return 1; +} + KYTY_HW_CTX_PARSER(hw_ctx_set_depth_render_target) { EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_Z_INFO); @@ -1454,59 +1663,89 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_depth_render_target) return count; } -KYTY_HW_CTX_PARSER(hw_ctx_set_ps_input) -{ - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::SPI_PS_INPUT_CNTL_0); - - uint32_t count = (cmd_id >> 16u) & 0x3fffu; - - EXIT_NOT_IMPLEMENTED(count == 0); - EXIT_NOT_IMPLEMENTED(count > 32); - - for (uint32_t i = 0; i < count; i++) - { - cp->GetCtx()->SetPsInputSettings(i, buffer[i]); - } - - return count; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_info) +KYTY_HW_CTX_PARSER(hw_ctx_set_eqaa_control) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_INFO); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_EQAA); - HW::DepthRenderTargetStencilInfo r; + HW::EqaaControl r; - r.expclear_enabled = (buffer[0] & 0x08000000u) != 0; - r.tile_split = (buffer[0] >> 13u) & 0x7u; + r.max_anchor_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MAX_ANCHOR_SAMPLES); + r.ps_iter_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, PS_ITER_SAMPLES); + r.mask_export_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MASK_EXPORT_NUM_SAMPLES); + r.alpha_to_mask_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, ALPHA_TO_MASK_NUM_SAMPLES); + r.high_quality_intersections = KYTY_PM4_GET(buffer[0], DB_EQAA, HIGH_QUALITY_INTERSECTIONS) != 0; + r.incoherent_eqaa_reads = KYTY_PM4_GET(buffer[0], DB_EQAA, INCOHERENT_EQAA_READS) != 0; + r.interpolate_comp_z = KYTY_PM4_GET(buffer[0], DB_EQAA, INTERPOLATE_COMP_Z) != 0; + r.static_anchor_associations = KYTY_PM4_GET(buffer[0], DB_EQAA, STATIC_ANCHOR_ASSOCIATIONS) != 0; - r.format = (buffer[0] >> Pm4::DB_STENCIL_INFO_FORMAT_SHIFT) & Pm4::DB_STENCIL_INFO_FORMAT_MASK; - r.tile_mode_index = (buffer[0] >> Pm4::DB_STENCIL_INFO_TILE_MODE_INDEX_SHIFT) & Pm4::DB_STENCIL_INFO_TILE_MODE_INDEX_MASK; - r.tile_stencil_disable = - ((buffer[0] >> Pm4::DB_STENCIL_INFO_TILE_STENCIL_DISABLE_SHIFT) & Pm4::DB_STENCIL_INFO_TILE_STENCIL_DISABLE_MASK) != 0; - - cp->GetCtx()->SetDepthRenderTargetStencilInfo(r); + cp->GetCtx()->SetEqaaControl(r); return 1; } -KYTY_HW_CTX_PARSER(hw_ctx_set_render_control) +KYTY_HW_CTX_PARSER(hw_ctx_set_generic_scissor) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0026900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_GENERIC_SCISSOR_TL); + + int left = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, TL_X))); + int top = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, TL_Y))); + int right = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_GENERIC_SCISSOR_BR, BR_X))); + int bottom = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_GENERIC_SCISSOR_BR, BR_Y))); + + bool window_offset_disable = KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, WINDOW_OFFSET_DISABLE) != 0; + + cp->GetCtx()->SetGenericScissor(left, top, right, bottom, !window_offset_disable); + + return 2; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_guard_bands) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0046900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_CL_GB_VERT_CLIP_ADJ); + + auto vert_clip = *reinterpret_cast(&buffer[0]); // PA_CL_GB_VERT_CLIP_ADJ + auto vert_discard = *reinterpret_cast(&buffer[1]); // PA_CL_GB_VERT_DISC_ADJ + auto horz_clip = *reinterpret_cast(&buffer[2]); // PA_CL_GB_HORZ_CLIP_ADJ + auto horz_discard = *reinterpret_cast(&buffer[3]); // PA_CL_GB_HORZ_DISC_ADJ + + cp->GetCtx()->SetGuardBands(horz_clip, vert_clip, horz_discard, vert_discard); + + return 4; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_hardware_screen_offset) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_RENDER_CONTROL); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SU_HARDWARE_SCREEN_OFFSET); - HW::RenderControl r; + // uint32_t x = static_cast(buffer[0] & 0xffffu); + // uint32_t y = static_cast((buffer[0] >> 16u) & 0xffffu); - r.depth_clear_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, DEPTH_CLEAR_ENABLE) != 0; - r.stencil_clear_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, STENCIL_CLEAR_ENABLE) != 0; - r.resummarize_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, RESUMMARIZE_ENABLE) != 0; - r.stencil_compress_disable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, STENCIL_COMPRESS_DISABLE) != 0; - r.depth_compress_disable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, DEPTH_COMPRESS_DISABLE) != 0; - r.copy_centroid = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, COPY_CENTROID) != 0; - r.copy_sample = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, COPY_SAMPLE); + uint32_t x = KYTY_PM4_GET(buffer[0], PA_SU_HARDWARE_SCREEN_OFFSET, HW_SCREEN_OFFSET_X); + uint32_t y = KYTY_PM4_GET(buffer[0], PA_SU_HARDWARE_SCREEN_OFFSET, HW_SCREEN_OFFSET_Y); - cp->GetCtx()->SetRenderControl(r); + cp->GetCtx()->SetHardwareScreenOffset(x, y); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_line_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SU_LINE_CNTL); + + auto line_width = KYTY_PM4_GET(buffer[0], PA_SU_LINE_CNTL, WIDTH); + + if (line_width == 8) + { + cp->GetCtx()->SetLineWidth(1.0f); + } else + { + cp->GetCtx()->SetLineWidth(static_cast(line_width) / 8.0f); + } return 1; } @@ -1535,229 +1774,39 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_mode_control) return 1; } -KYTY_HW_CTX_PARSER(hw_ctx_set_line_control) +KYTY_HW_CTX_PARSER(hw_ctx_set_ps_input) { - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SU_LINE_CNTL); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::SPI_PS_INPUT_CNTL_0); - auto line_width = KYTY_PM4_GET(buffer[0], PA_SU_LINE_CNTL, WIDTH); + uint32_t count = (cmd_id >> 16u) & 0x3fffu; - if (line_width == 8) + EXIT_NOT_IMPLEMENTED(count == 0); + EXIT_NOT_IMPLEMENTED(count > 32); + + for (uint32_t i = 0; i < count; i++) { - cp->GetCtx()->SetLineWidth(1.0f); - } else - { - cp->GetCtx()->SetLineWidth(static_cast(line_width) / 8.0f); - } - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_scan_mode_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_MODE_CNTL_0); - - HW::ScanModeControl r; - - r.msaa_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, MSAA_ENABLE) != 0; - r.vport_scissor_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, VPORT_SCISSOR_ENABLE) != 0; - r.line_stipple_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, LINE_STIPPLE_ENABLE) != 0; - - cp->GetCtx()->SetScanModeControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_aa_config) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_CONFIG); - - HW::AaConfig r; - - r.msaa_num_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_NUM_SAMPLES); - r.aa_mask_centroid_dtmn = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, AA_MASK_CENTROID_DTMN) != 0; - r.max_sample_dist = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MAX_SAMPLE_DIST); - r.msaa_exposed_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_EXPOSED_SAMPLES); - - cp->GetCtx()->SetAaConfig(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_aa_sample_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0106900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0); - - uint32_t count = 1; - - if (dw >= 20 && buffer[16] == 0xc0026900 && buffer[17] == Pm4::PA_SC_CENTROID_PRIORITY_0) - { - count = 20; - - HW::AaSampleControl r; - - memcpy(r.locations, buffer, static_cast(16) * 4); - - r.centroid_priority = static_cast(buffer[18]) | (static_cast(buffer[19]) << 32u); - - cp->GetCtx()->SetAaSampleControl(r); - } else - { - KYTY_NOT_IMPLEMENTED; + cp->GetCtx()->SetPsInputSettings(i, buffer[i]); } return count; } -KYTY_HW_CTX_PARSER(hw_ctx_set_depth_control) +KYTY_HW_CTX_PARSER(hw_ctx_set_render_control) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_DEPTH_CONTROL); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_RENDER_CONTROL); - HW::DepthControl r; + HW::RenderControl r; - r.stencil_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCIL_ENABLE) != 0; - r.z_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, Z_ENABLE) != 0; - r.z_write_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, Z_WRITE_ENABLE) != 0; - r.depth_bounds_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, DEPTH_BOUNDS_ENABLE) != 0; - r.zfunc = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, ZFUNC); - r.backface_enable = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, BACKFACE_ENABLE) != 0; - r.stencilfunc = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCILFUNC); - r.stencilfunc_bf = KYTY_PM4_GET(buffer[0], DB_DEPTH_CONTROL, STENCILFUNC_BF); + r.depth_clear_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, DEPTH_CLEAR_ENABLE) != 0; + r.stencil_clear_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, STENCIL_CLEAR_ENABLE) != 0; + r.resummarize_enable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, RESUMMARIZE_ENABLE) != 0; + r.stencil_compress_disable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, STENCIL_COMPRESS_DISABLE) != 0; + r.depth_compress_disable = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, DEPTH_COMPRESS_DISABLE) != 0; + r.copy_centroid = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, COPY_CENTROID) != 0; + r.copy_sample = KYTY_PM4_GET(buffer[0], DB_RENDER_CONTROL, COPY_SAMPLE); - cp->GetCtx()->SetDepthControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CONTROL); - - HW::StencilControl r; - - r.stencil_fail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL); - r.stencil_zpass = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS); - r.stencil_zfail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL); - r.stencil_fail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL_BF); - r.stencil_zpass_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS_BF); - r.stencil_zfail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL_BF); - - cp->GetCtx()->SetStencilControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_mask) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0026900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCILREFMASK); - - HW::StencilMask r; - - r.stencil_testval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILTESTVAL); - r.stencil_mask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILMASK); - r.stencil_writemask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILWRITEMASK); - r.stencil_opval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILOPVAL); - r.stencil_testval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILTESTVAL_BF); - r.stencil_mask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILMASK_BF); - r.stencil_writemask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILWRITEMASK_BF); - r.stencil_opval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILOPVAL_BF); - - cp->GetCtx()->SetStencilMask(r); - - return 2; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_eqaa_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_EQAA); - - HW::EqaaControl r; - - r.max_anchor_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MAX_ANCHOR_SAMPLES); - r.ps_iter_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, PS_ITER_SAMPLES); - r.mask_export_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MASK_EXPORT_NUM_SAMPLES); - r.alpha_to_mask_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, ALPHA_TO_MASK_NUM_SAMPLES); - r.high_quality_intersections = KYTY_PM4_GET(buffer[0], DB_EQAA, HIGH_QUALITY_INTERSECTIONS) != 0; - r.incoherent_eqaa_reads = KYTY_PM4_GET(buffer[0], DB_EQAA, INCOHERENT_EQAA_READS) != 0; - r.interpolate_comp_z = KYTY_PM4_GET(buffer[0], DB_EQAA, INTERPOLATE_COMP_Z) != 0; - r.static_anchor_associations = KYTY_PM4_GET(buffer[0], DB_EQAA, STATIC_ANCHOR_ASSOCIATIONS) != 0; - - cp->GetCtx()->SetEqaaControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_color_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_COLOR_CONTROL); - - HW::ColorControl r; - - r.mode = KYTY_PM4_GET(buffer[0], CB_COLOR_CONTROL, MODE); - r.op = KYTY_PM4_GET(buffer[0], CB_COLOR_CONTROL, ROP3); - - cp->GetCtx()->SetColorControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_clear) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CLEAR); - - cp->GetCtx()->SetStencilClearValue(KYTY_PM4_GET(buffer[0], DB_STENCIL_CLEAR, CLEAR)); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_depth_clear) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_DEPTH_CLEAR); - - cp->GetCtx()->SetDepthClearValue(*reinterpret_cast(buffer)); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_shader_stages) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::VGT_SHADER_STAGES_EN); - - cp->GetCtx()->SetShaderStages(buffer[0]); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_blend_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - - uint32_t param = (cmd_offset - Pm4::CB_BLEND0_CONTROL) / 1; - - HW::BlendControl r; - - r.color_srcblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_SRCBLEND_MASK; - r.color_comb_fcn = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_COMB_FCN_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_COMB_FCN_MASK; - r.color_destblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_COLOR_DESTBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_COLOR_DESTBLEND_MASK; - r.alpha_srcblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_SRCBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_SRCBLEND_MASK; - r.alpha_comb_fcn = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_COMB_FCN_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_COMB_FCN_MASK; - r.alpha_destblend = (buffer[0] >> Pm4::CB_BLEND0_CONTROL_ALPHA_DESTBLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_ALPHA_DESTBLEND_MASK; - r.separate_alpha_blend = - ((buffer[0] >> Pm4::CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_SHIFT) & Pm4::CB_BLEND0_CONTROL_SEPARATE_ALPHA_BLEND_MASK) != 0; - r.enable = ((buffer[0] >> Pm4::CB_BLEND0_CONTROL_ENABLE_SHIFT) & Pm4::CB_BLEND0_CONTROL_ENABLE_MASK) != 0; - - cp->GetCtx()->SetBlendControl(param, r); + cp->GetCtx()->SetRenderControl(r); return 1; } @@ -1860,49 +1909,123 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_render_target) return count; } -KYTY_HW_CTX_PARSER(hw_ctx_set_color_info) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); - - uint32_t param = (cmd_offset - Pm4::CB_COLOR0_INFO) / 15; - - HW::ColorInfo r; - - r.fmask_compression_enable = (buffer[4] & 0x4000u) != 0; - r.fmask_compression_mode = (buffer[4] >> 26u) & 0x3u; - r.cmask_fast_clear_enable = (buffer[4] & 0x2000u) != 0; - r.dcc_compression_enable = (buffer[4] & 0x10000000u) != 0; - r.neo_mode = (buffer[4] & 0x80000000u) != 0; - r.cmask_tile_mode = (buffer[4] >> 19u) & 0x1u; - r.cmask_tile_mode_neo = (buffer[4] >> 29u) & 0x3u; - r.format = (buffer[4] >> 2u) & 0x1fu; - r.channel_type = (buffer[4] >> 8u) & 0x7u; - r.channel_order = (buffer[4] >> 11u) & 0x3u; - - cp->GetCtx()->SetColorInfo(param, r); - - return 1; -} - KYTY_HW_CTX_PARSER(hw_ctx_set_render_target_mask) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != 0x0000008E); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_TARGET_MASK); cp->GetCtx()->SetRenderTargetMask(*buffer); return 1; } -KYTY_HW_CTX_PARSER(hw_ctx_set_viewport_z) +KYTY_HW_CTX_PARSER(hw_ctx_set_scan_mode_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_MODE_CNTL_0); + + HW::ScanModeControl r; + + r.msaa_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, MSAA_ENABLE) != 0; + r.vport_scissor_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, VPORT_SCISSOR_ENABLE) != 0; + r.line_stipple_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, LINE_STIPPLE_ENABLE) != 0; + + cp->GetCtx()->SetScanModeControl(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_screen_scissor) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0026900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_SCREEN_SCISSOR_TL); - uint32_t param = (cmd_offset - Pm4::PA_SC_VPORT_ZMIN_0) / 2; + int left = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_SCREEN_SCISSOR_TL, TL_X))); + int top = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_SCREEN_SCISSOR_TL, TL_Y))); + int right = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_SCREEN_SCISSOR_BR, BR_X))); + int bottom = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_SCREEN_SCISSOR_BR, BR_Y))); - EXIT_NOT_IMPLEMENTED(param != 0); + cp->GetCtx()->SetScreenScissor(left, top, right, bottom); - cp->GetCtx()->SetViewportZ(param, *reinterpret_cast(buffer), *reinterpret_cast(buffer + 1)); + return 2; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_shader_stages) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::VGT_SHADER_STAGES_EN); + + cp->GetCtx()->SetShaderStages(buffer[0]); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_clear) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CLEAR); + + cp->GetCtx()->SetStencilClearValue(KYTY_PM4_GET(buffer[0], DB_STENCIL_CLEAR, CLEAR)); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_control) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_CONTROL); + + HW::StencilControl r; + + r.stencil_fail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL); + r.stencil_zpass = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS); + r.stencil_zfail = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL); + r.stencil_fail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILFAIL_BF); + r.stencil_zpass_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZPASS_BF); + r.stencil_zfail_bf = KYTY_PM4_GET(buffer[0], DB_STENCIL_CONTROL, STENCILZFAIL_BF); + + cp->GetCtx()->SetStencilControl(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_info) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCIL_INFO); + + HW::DepthRenderTargetStencilInfo r; + + r.expclear_enabled = (buffer[0] & 0x08000000u) != 0; + r.tile_split = (buffer[0] >> 13u) & 0x7u; + + r.format = (buffer[0] >> Pm4::DB_STENCIL_INFO_FORMAT_SHIFT) & Pm4::DB_STENCIL_INFO_FORMAT_MASK; + r.tile_mode_index = (buffer[0] >> Pm4::DB_STENCIL_INFO_TILE_MODE_INDEX_SHIFT) & Pm4::DB_STENCIL_INFO_TILE_MODE_INDEX_MASK; + r.tile_stencil_disable = + ((buffer[0] >> Pm4::DB_STENCIL_INFO_TILE_STENCIL_DISABLE_SHIFT) & Pm4::DB_STENCIL_INFO_TILE_STENCIL_DISABLE_MASK) != 0; + + cp->GetCtx()->SetDepthRenderTargetStencilInfo(r); + + return 1; +} + +KYTY_HW_CTX_PARSER(hw_ctx_set_stencil_mask) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0026900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_STENCILREFMASK); + + HW::StencilMask r; + + r.stencil_testval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILTESTVAL); + r.stencil_mask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILMASK); + r.stencil_writemask = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILWRITEMASK); + r.stencil_opval = KYTY_PM4_GET(buffer[0], DB_STENCILREFMASK, STENCILOPVAL); + r.stencil_testval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILTESTVAL_BF); + r.stencil_mask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILMASK_BF); + r.stencil_writemask_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILWRITEMASK_BF); + r.stencil_opval_bf = KYTY_PM4_GET(buffer[1], DB_STENCILREFMASK_BF, STENCILOPVAL_BF); + + cp->GetCtx()->SetStencilMask(r); return 2; } @@ -1925,216 +2048,27 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_viewport_scale_offset) KYTY_HW_CTX_PARSER(hw_ctx_set_viewport_transform_control) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != 0x00000206); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_CL_VTE_CNTL); cp->GetCtx()->SetViewportTransformControl(*buffer); return 1; } -KYTY_HW_CTX_PARSER(hw_ctx_set_clip_control) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != 0x00000204); - - HW::ClipControl r; - - r.user_clip_planes = buffer[0] & 0x3fu; - r.user_clip_plane_mode = (buffer[0] >> 14u) & 0x3u; - r.clip_space = (buffer[0] >> 19u) & 0x1u; - r.vertex_kill_mode = (buffer[0] >> 21u) & 0x1u; - r.min_z_clip_enable = (buffer[0] >> 26u) & 0x1u; - r.max_z_clip_enable = (buffer[0] >> 27u) & 0x1u; - r.user_clip_plane_negate_y = (buffer[0] & 0x00002000u) != 0; - r.clip_enable = (buffer[0] & 0x00010000u) != 0; - r.user_clip_plane_cull_only = (buffer[0] & 0x00020000u) != 0; - r.cull_on_clipping_error_disable = (buffer[0] & 0x00100000u) != 0; - r.linear_attribute_clip_enable = (buffer[0] & 0x01000000u) != 0; - r.force_viewport_index_from_vs_enable = (buffer[0] & 0x02000000u) != 0; - - cp->GetCtx()->SetClipControl(r); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_screen_scissor) +KYTY_HW_CTX_PARSER(hw_ctx_set_viewport_z) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0026900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_SCREEN_SCISSOR_TL); - int left = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_SCREEN_SCISSOR_TL, TL_X))); - int top = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_SCREEN_SCISSOR_TL, TL_Y))); - int right = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_SCREEN_SCISSOR_BR, BR_X))); - int bottom = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_SCREEN_SCISSOR_BR, BR_Y))); + uint32_t param = (cmd_offset - Pm4::PA_SC_VPORT_ZMIN_0) / 2; - cp->GetCtx()->SetScreenScissor(left, top, right, bottom); + EXIT_NOT_IMPLEMENTED(param != 0); + + cp->GetCtx()->SetViewportZ(param, *reinterpret_cast(buffer), *reinterpret_cast(buffer + 1)); return 2; } -KYTY_HW_CTX_PARSER(hw_ctx_set_generic_scissor) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0026900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_GENERIC_SCISSOR_TL); - - int left = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, TL_X))); - int top = static_cast(static_cast(KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, TL_Y))); - int right = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_GENERIC_SCISSOR_BR, BR_X))); - int bottom = static_cast(static_cast(KYTY_PM4_GET(buffer[1], PA_SC_GENERIC_SCISSOR_BR, BR_Y))); - - bool window_offset_disable = KYTY_PM4_GET(buffer[0], PA_SC_GENERIC_SCISSOR_TL, WINDOW_OFFSET_DISABLE) != 0; - - cp->GetCtx()->SetGenericScissor(left, top, right, bottom, !window_offset_disable); - - return 2; -} - -KYTY_HW_CTX_PARSER(hw_ctx_hardware_screen_offset) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900); - EXIT_NOT_IMPLEMENTED(cmd_offset != 0x0000008D); - - uint32_t x = static_cast(buffer[0] & 0xffffu); - uint32_t y = static_cast((buffer[0] >> 16u) & 0xffffu); - - cp->GetCtx()->SetHardwareScreenOffset(x, y); - - return 1; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_guard_bands) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0046900); - EXIT_NOT_IMPLEMENTED(cmd_offset != 0x000002FA); - - auto vert_clip = *reinterpret_cast(&buffer[0]); - auto vert_discard = *reinterpret_cast(&buffer[1]); - auto horz_clip = *reinterpret_cast(&buffer[2]); - auto horz_discard = *reinterpret_cast(&buffer[3]); - - cp->GetCtx()->SetGuardBands(horz_clip, vert_clip, horz_discard, vert_discard); - - return 4; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_blend_color) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0046900); - EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_BLEND_RED); - - HW::BlendColor r; - - r.red = *reinterpret_cast(&buffer[0]); - r.green = *reinterpret_cast(&buffer[1]); - r.blue = *reinterpret_cast(&buffer[2]); - r.alpha = *reinterpret_cast(&buffer[3]); - - cp->GetCtx()->SetBlendColor(r); - - return 4; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_vs_shader) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC01B1004); - - auto shader_modifier = buffer[0]; - - cp->GetCtx()->SetVsShader(reinterpret_cast(buffer + 1), shader_modifier); - - return 28; -} - -KYTY_HW_CTX_PARSER(hw_ctx_update_vs_shader) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc01b103c); - - auto shader_modifier = buffer[0]; - - cp->GetCtx()->UpdateVsShader(reinterpret_cast(buffer + 1), shader_modifier); - - return 28; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_vs_embedded) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc01b1034); - - auto shader_modifier = buffer[0]; - auto id = buffer[1]; - - cp->GetCtx()->SetVsEmbedded(id, shader_modifier); - - return 28; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_ps_embedded) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0261038); - - auto id = buffer[0]; - - cp->GetCtx()->SetPsEmbedded(id); - - return 39; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_ps_shader) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0261008); - - HW::PsStageRegisters r {}; - - r.data_addr = (static_cast(buffer[0]) << 8u) | (static_cast(buffer[1]) << 40u); - r.vgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK; - r.sgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK; - r.scratch_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_MASK; - r.user_sgpr = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK; - r.wave_cnt_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK; - r.shader_z_format = buffer[4]; - - for (uint32_t i = 0; i < 8; i++) - { - r.target_output_mode[i] = (buffer[5] >> (i * 4)) & 0xFu; - } - - r.ps_input_ena = buffer[6]; - r.ps_input_addr = buffer[7]; - r.ps_in_control = buffer[8]; - r.baryc_cntl = buffer[9]; - r.conservative_z_export_value = (buffer[10] >> 13u) & 0x3u; - r.shader_z_behavior = (buffer[10] >> 4u) & 0x3u; - r.shader_kill_enable = (buffer[10] & 0x40u) != 0; - r.shader_z_export_enable = (buffer[10] & 0x1u) != 0; - r.shader_execute_on_noop = (buffer[10] & 0x400u) != 0; - - r.m_cbShaderMask = buffer[11]; - - cp->GetCtx()->SetPsShader(&r); - - return 39; -} - -KYTY_HW_CTX_PARSER(hw_ctx_update_ps_shader) -{ - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0261040); - - HW::PsStageRegisters r {}; - - r.data_addr = (static_cast(buffer[0]) << 8u) | (static_cast(buffer[1]) << 40u); - r.vgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK; - r.sgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK; - r.scratch_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_MASK; - r.user_sgpr = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK; - r.wave_cnt_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK; - r.shader_z_format = buffer[4]; - - cp->GetCtx()->UpdatePsShader(&r); - - return 39; -} - -KYTY_HW_CTX_PARSER(hw_ctx_set_cs_shader) +KYTY_HW_SH_PARSER(hw_sh_set_cs_shader) { EXIT_NOT_IMPLEMENTED(cmd_id != 0xC017101C); @@ -2158,476 +2092,205 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_cs_shader) r.num_thread_y = buffer[6]; r.num_thread_z = buffer[7]; - cp->GetCtx()->SetCsShader(&r, shader_modifier); + cp->GetShCtx()->SetCsShader(r, shader_modifier); return 24; } -KYTY_CP_OP_PARSER(cp_op_set_context_reg) +KYTY_HW_SH_PARSER(hw_sh_set_cs_user_sgpr) { - KYTY_PROFILER_FUNCTION(); + EXIT_NOT_IMPLEMENTED(!(cmd_offset >= Pm4::COMPUTE_USER_DATA_0 && cmd_offset <= Pm4::COMPUTE_USER_DATA_15)); - auto cmd_offset = buffer[0]; - - auto pfunc = g_hw_ctx_func[cmd_offset & 0x3ffu]; - - if (pfunc == nullptr) - { - EXIT("unknown command\n\t%05" PRIx32 ":\n\tcmd_id = %08" PRIx32 "\n\tcmd_offset = %08" PRIx32 "\n", num_dw - dw, cmd_id, - cmd_offset); - } - - auto s = pfunc(cp, cmd_id, cmd_offset, buffer + 1, dw); - - EXIT_IF(s == 0); - - return s + 1; -} - -KYTY_CP_OP_PARSER(cp_op_set_uconfig_reg) -{ - KYTY_PROFILER_FUNCTION(); - - auto cmd_offset = buffer[0]; - - switch (cmd_offset & 0x1fffu) - { - case Pm4::PRIMITIVE_TYPE: - cp->GetUcfg()->SetPrimitiveType(buffer[1]); - return 2; - break; - default: - EXIT("unknown command\n\t%05" PRIx32 ":\n\tcmd_id = %08" PRIx32 "\n\tcmd_offset = %08" PRIx32 "\n", num_dw - dw, cmd_id, - cmd_offset); - } - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_index_type) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0002A00); - - cp->SetIndexType(buffer[0]); - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_num_instances) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0002f00); - - cp->SetNumInstances(buffer[0]); - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_push_marker) -{ - KYTY_PROFILER_FUNCTION(); - - auto dw_num = (cmd_id >> 16u) & 0x3fffu; - - const char* str = reinterpret_cast(buffer); - - printf("Push marker: %s\n", str); - - cp->PushMarker(str); - - return dw_num + 1; -} - -KYTY_CP_OP_PARSER(cp_op_pop_marker) -{ - KYTY_PROFILER_FUNCTION(); - - auto dw_num = (cmd_id >> 16u) & 0x3fffu; - - printf("Pop marker\n"); - - cp->PopMarker(); - - return dw_num + 1; -} - -KYTY_CP_OP_PARSER(cp_op_draw_index) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC008100C && cmd_id != 0xc0042700); - - if (cmd_id == 0xC008100C) - { - uint32_t index_count = buffer[0]; - auto* index_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); - uint32_t flags = buffer[3]; - uint32_t type = buffer[4]; - - cp->DrawIndex(index_count, index_addr, flags, type); - - return 9; - } - - if (cmd_id == 0xc0042700) - { - uint32_t index_count = buffer[0]; - auto* index_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); - - EXIT_NOT_IMPLEMENTED(buffer[3] != index_count); - EXIT_NOT_IMPLEMENTED(buffer[4] != 0); - - cp->DrawIndex(index_count, index_addr, 0, 1); - - EXIT_NOT_IMPLEMENTED(!(dw >= 7)); - - if (buffer[5] == 0xc0001000) - { - EXIT_NOT_IMPLEMENTED(buffer[6] != 0); - - return 7; - } - - if (buffer[5] == 0xc0021000) - { - EXIT_NOT_IMPLEMENTED(buffer[6] != 0); - - return 9; - } - - EXIT("invalid draw_index\n"); - } - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_indirect_buffer) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0023f02); - - EXIT_NOT_IMPLEMENTED((buffer[2] & 0xff00000u) != 0x1800000u); - - auto* indirect_buffer = reinterpret_cast(buffer[0] | (static_cast(buffer[1] & 0xffffu) << 32u)); - uint32_t indirect_num_dw = buffer[2] & 0xfffffu; - - EXIT_NOT_IMPLEMENTED(indirect_buffer == nullptr); - EXIT_NOT_IMPLEMENTED(indirect_num_dw == 0); - - GraphicsDbgDumpDcb("ci", indirect_num_dw, indirect_buffer); - - cp->Run(indirect_buffer, indirect_num_dw); - - return 3; -} - -KYTY_CP_OP_PARSER(cp_op_draw_index_auto) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0051010 && cmd_id != 0xc0012d00); - - if (cmd_id == 0xC0051010) - { - uint32_t index_count = buffer[0]; - uint32_t flags = buffer[1]; - - cp->DrawIndexAuto(index_count, flags); - - return 6; - } - - if (cmd_id == 0xc0012d00) - { - uint32_t index_count = buffer[0]; - uint32_t flags = 0; - - EXIT_NOT_IMPLEMENTED(buffer[1] != 2); - - cp->DrawIndexAuto(index_count, flags); - - EXIT_NOT_IMPLEMENTED(!(dw >= 4)); - - if (buffer[2] == 0xc0001000) - { - EXIT_NOT_IMPLEMENTED(buffer[3] != 0); - - return 4; - } - - if (buffer[2] == 0xc0021000) - { - EXIT_NOT_IMPLEMENTED(buffer[3] != 0); - - return 6; - } - - EXIT("invalid draw_index_auto\n"); - } - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_dispatch_direct) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0071020); - - uint32_t thread_group_x = buffer[0]; - uint32_t thread_group_y = buffer[1]; - uint32_t thread_group_z = buffer[2]; - uint32_t mode = buffer[3]; - - cp->DispatchDirect(thread_group_x, thread_group_y, thread_group_z, mode); - - return 8; -} - -KYTY_CP_OP_PARSER(cp_op_event_write) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0004600); - - uint32_t event_index = (buffer[0] >> 8u) & 0x7u; - uint32_t event_type = (buffer[0]) & 0x3fu; - - cp->TriggerEvent(event_type, event_index); - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_event_write_eop) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0044700); - - uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; - uint32_t event_write_dest = ((buffer[0] >> 23u) & 0x10u) | ((buffer[2] >> 16u) & 0x01u); - uint32_t eop_event_type = (buffer[0]) & 0x3fu; - uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; - uint32_t event_index = (buffer[0] >> 8u) & 0x7u; - uint32_t event_write_source = ((buffer[2] >> 29u) & 0x7u); - uint32_t interrupt_selector = (buffer[2] >> 24u) & 0x7u; - auto* dst_gpu_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2] & 0xffffu) << 32u)); - uint64_t value = (buffer[3] | (static_cast(buffer[4]) << 32u)); - - cp->WriteAtEndOfPipe64(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, - value, interrupt_selector); - - return 5; -} - -KYTY_CP_OP_PARSER(cp_op_event_write_eos) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0034802); - - uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; - uint32_t event_write_dest = 0; - uint32_t eop_event_type = (buffer[0]) & 0x3fu; - uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; - uint32_t event_index = (buffer[0] >> 8u) & 0x7u; - uint32_t event_write_source = ((buffer[2] >> 29u) & 0x7u); - uint32_t interrupt_selector = (buffer[2] >> 24u) & 0x7u; - - auto* dst_gpu_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2] & 0xffffu) << 32u)); - uint32_t value = buffer[3]; - - cp->WriteAtEndOfPipe32(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, - value, interrupt_selector); - - return 4; -} - -KYTY_CP_OP_PARSER(cp_op_release_mem) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0054902); - - uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; - uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; - uint32_t eop_event_type = (buffer[0]) & 0x3fu; - uint32_t event_index = (buffer[0] >> 8u) & 0x7u; - uint32_t event_write_dest = ((buffer[0] >> 23u) & 0x10u) | ((buffer[1] >> 16u) & 0x01u); - uint32_t event_write_source = (buffer[1] >> 29u) & 0x7u; - uint32_t interrupt_selector = (buffer[1] >> 24u) & 0x7u; - auto* dst_gpu_addr = reinterpret_cast(buffer[2] | (static_cast(buffer[3]) << 32u)); - uint64_t value = (buffer[4] | (static_cast(buffer[5]) << 32u)); - - cp->WriteAtEndOfPipe64(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, - value, interrupt_selector); - - return 6; -} - -KYTY_CP_OP_PARSER(cp_op_set_shader_reg) -{ - KYTY_PROFILER_FUNCTION(); + uint32_t slot = (cmd_offset - Pm4::COMPUTE_USER_DATA_0) / 1; auto reg_num = (cmd_id >> 16u) & 0x3fffu; - uint32_t reg = buffer[0]; - - if (reg >= Pm4::SPI_SHADER_USER_DATA_VS_0 && reg <= Pm4::SPI_SHADER_USER_DATA_VS_15) + for (uint32_t i = 0; i < reg_num; i++) { - for (uint32_t i = 0; i < reg_num; i++) - { - cp->GetCtx()->SetVsUserSgpr(reg - Pm4::SPI_SHADER_USER_DATA_VS_0 + i, buffer[i + 1], cp->GetUserDataMarker()); - } - } else if (reg >= Pm4::SPI_SHADER_USER_DATA_PS_0 && reg <= Pm4::SPI_SHADER_USER_DATA_PS_15) - { - for (uint32_t i = 0; i < reg_num; i++) - { - cp->GetCtx()->SetPsUserSgpr(reg - Pm4::SPI_SHADER_USER_DATA_PS_0 + i, buffer[i + 1], cp->GetUserDataMarker()); - } - } else if (reg >= Pm4::COMPUTE_USER_DATA_0 && reg <= Pm4::COMPUTE_USER_DATA_15) - { - for (uint32_t i = 0; i < reg_num; i++) - { - cp->GetCtx()->SetCsUserSgpr(reg - Pm4::COMPUTE_USER_DATA_0 + i, buffer[i + 1], cp->GetUserDataMarker()); - } - } else - { - EXIT("unknown reg: %u\n", reg); + cp->GetShCtx()->SetCsUserSgpr(slot + i, buffer[i], cp->GetUserDataMarker()); } - cp->SetUserDataMarker(HW::UserSgprType::Unknown); - return 1 + reg_num; + return reg_num; } -KYTY_CP_OP_PARSER(cp_op_write_data) +KYTY_HW_SH_PARSER(hw_sh_set_ps_embedded) { - KYTY_PROFILER_FUNCTION(); + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0261038); - auto dw_num = (cmd_id >> 16u) & 0x3fffu; + auto id = buffer[0]; - auto write_control = buffer[0]; - auto* dst = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + cp->GetShCtx()->SetPsEmbedded(id); - cp->WriteData(dst, buffer + 3, dw_num - 2, write_control); - - return 1 + dw_num; + return 39; } -KYTY_CP_OP_PARSER(cp_op_dispatch_reset) +KYTY_HW_SH_PARSER(hw_sh_set_ps_shader) { - KYTY_PROFILER_FUNCTION(); + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0261008); - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0001024); + HW::PsStageRegisters r {}; - cp->Reset(); + r.data_addr = (static_cast(buffer[0]) << 8u) | (static_cast(buffer[1]) << 40u); + r.vgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK; + r.sgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK; + r.scratch_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_MASK; + r.user_sgpr = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK; + r.wave_cnt_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK; + + cp->GetCtx()->SetShaderZFormat(buffer[4]); + + for (uint32_t i = 0; i < 8; i++) + { + cp->GetCtx()->SetTargetOutputMode(i, (buffer[5] >> (i * 4)) & 0xFu); + } + + cp->GetCtx()->SetPsInputEna(buffer[6]); + cp->GetCtx()->SetPsInputAddr(buffer[7]); + cp->GetCtx()->SetPsInControl(buffer[8]); + cp->GetCtx()->SetBarycCntl(buffer[9]); + + HW::DepthShaderControl db_shader_control {}; + + // db_shader_control.conservative_z_export_value = (buffer[10] >> 13u) & 0x3u; + // db_shader_control.shader_z_behavior = (buffer[10] >> 4u) & 0x3u; + // db_shader_control.shader_kill_enable = (buffer[10] & 0x40u) != 0; + // db_shader_control.shader_z_export_enable = (buffer[10] & 0x1u) != 0; + // db_shader_control.shader_execute_on_noop = (buffer[10] & 0x400u) != 0; + db_shader_control.other_bits = buffer[10] & 0xFFFF9B8Eu; + db_shader_control.conservative_z_export_value = KYTY_PM4_GET(buffer[10], DB_SHADER_CONTROL, CONSERVATIVE_Z_EXPORT); + db_shader_control.shader_z_behavior = KYTY_PM4_GET(buffer[10], DB_SHADER_CONTROL, Z_ORDER); + db_shader_control.shader_kill_enable = KYTY_PM4_GET(buffer[10], DB_SHADER_CONTROL, KILL_ENABLE) != 0; + db_shader_control.shader_z_export_enable = KYTY_PM4_GET(buffer[10], DB_SHADER_CONTROL, Z_EXPORT_ENABLE) != 0; + db_shader_control.shader_execute_on_noop = KYTY_PM4_GET(buffer[10], DB_SHADER_CONTROL, EXEC_ON_NOOP) != 0; + + cp->GetCtx()->SetDepthShaderControl(db_shader_control); + cp->GetCtx()->SetShaderMask(buffer[11]); + + cp->GetShCtx()->SetPsShader(r); + + return 39; +} + +KYTY_HW_SH_PARSER(hw_sh_set_ps_user_sgpr) +{ + EXIT_NOT_IMPLEMENTED(!(cmd_offset >= Pm4::SPI_SHADER_USER_DATA_PS_0 && cmd_offset <= Pm4::SPI_SHADER_USER_DATA_PS_15)); + + uint32_t slot = (cmd_offset - Pm4::SPI_SHADER_USER_DATA_PS_0) / 1; + + auto reg_num = (cmd_id >> 16u) & 0x3fffu; + + for (uint32_t i = 0; i < reg_num; i++) + { + cp->GetShCtx()->SetPsUserSgpr(slot + i, buffer[i], cp->GetUserDataMarker()); + } + cp->SetUserDataMarker(HW::UserSgprType::Unknown); + + return reg_num; +} + +KYTY_HW_SH_PARSER(hw_sh_set_vs_embedded) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc01b1034); + + auto shader_modifier = buffer[0]; + auto id = buffer[1]; + + cp->GetShCtx()->SetVsEmbedded(id, shader_modifier); + + return 28; +} + +KYTY_HW_SH_PARSER(hw_sh_set_vs_shader) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC01B1004); + + auto shader_modifier = buffer[0]; + + HW::VsStageRegisters r {}; + + r.m_spiShaderPgmLoVs = buffer[1]; + r.m_spiShaderPgmHiVs = buffer[2]; + r.m_spiShaderPgmRsrc1Vs = buffer[3]; + r.m_spiShaderPgmRsrc2Vs = buffer[4]; + + uint32_t m_spi_vs_out_config = buffer[5]; + uint32_t m_spi_shader_pos_format = buffer[6]; + uint32_t m_pa_cl_vs_out_cntl = buffer[7]; + + cp->GetShCtx()->SetVsShader(r, shader_modifier); + cp->GetCtx()->SetVsOutConfig(m_spi_vs_out_config); + cp->GetCtx()->SetShaderPosFormat(m_spi_shader_pos_format); + cp->GetCtx()->SetClVsOutCntl(m_pa_cl_vs_out_cntl); + + return 28; +} + +KYTY_HW_SH_PARSER(hw_sh_set_vs_user_sgpr) +{ + EXIT_NOT_IMPLEMENTED(!(cmd_offset >= Pm4::SPI_SHADER_USER_DATA_VS_0 && cmd_offset <= Pm4::SPI_SHADER_USER_DATA_VS_15)); + + uint32_t slot = (cmd_offset - Pm4::SPI_SHADER_USER_DATA_VS_0) / 1; + + auto reg_num = (cmd_id >> 16u) & 0x3fffu; + + for (uint32_t i = 0; i < reg_num; i++) + { + cp->GetShCtx()->SetVsUserSgpr(slot + i, buffer[i], cp->GetUserDataMarker()); + } + cp->SetUserDataMarker(HW::UserSgprType::Unknown); + + return reg_num; +} + +KYTY_HW_SH_PARSER(hw_sh_update_ps_shader) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0261040); + + HW::PsStageRegisters r {}; + + r.data_addr = (static_cast(buffer[0]) << 8u) | (static_cast(buffer[1]) << 40u); + r.vgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_VGPRS_MASK; + r.sgprs = (buffer[2] >> Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC1_PS_SGPRS_MASK; + r.scratch_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_SCRATCH_EN_MASK; + r.user_sgpr = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_USER_SGPR_MASK; + r.wave_cnt_en = (buffer[3] >> Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_SHIFT) & Pm4::SPI_SHADER_PGM_RSRC2_PS_WAVE_CNT_EN_MASK; + + cp->GetCtx()->SetShaderZFormat(buffer[4]); + + cp->GetShCtx()->UpdatePsShader(r); + + return 39; +} + +KYTY_HW_SH_PARSER(hw_sh_update_vs_shader) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc01b103c); + + auto shader_modifier = buffer[0]; + + HW::VsStageRegisters r {}; + + r.m_spiShaderPgmLoVs = buffer[1]; + r.m_spiShaderPgmHiVs = buffer[2]; + r.m_spiShaderPgmRsrc1Vs = buffer[3]; + r.m_spiShaderPgmRsrc2Vs = buffer[4]; + + cp->GetShCtx()->UpdateVsShader(r, shader_modifier); + + return 28; +} + +KYTY_HW_UC_PARSER(hw_uc_set_primitive_type) +{ + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0017900); + EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::VGT_PRIMITIVE_TYPE); + + cp->GetUcfg()->SetPrimitiveType(buffer[0]); return 1; } -KYTY_CP_OP_PARSER(cp_op_draw_reset) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0001014); - - cp->Reset(); - - return 1; -} - -KYTY_CP_OP_PARSER(cp_op_wait_flip_done) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0051018); - - auto video_out_handle = buffer[0]; - auto display_buffer_index = buffer[1]; - - cp->WaitFlipDone(video_out_handle, display_buffer_index); - - return 6; -} - -KYTY_CP_OP_PARSER(cp_op_write_const_ram) -{ - KYTY_PROFILER_FUNCTION(); - - auto dw_num = (cmd_id >> 16u) & 0x3fffu; - auto offset = buffer[0]; - - EXIT_NOT_IMPLEMENTED(dw_num >= 0x3000); - EXIT_NOT_IMPLEMENTED(offset > 0xbffc); - EXIT_NOT_IMPLEMENTED((offset & 0x3u) != 0); - - cp->WriteConstRam(offset, buffer + 1, dw_num); - - return 1 + dw_num; -} - -KYTY_CP_OP_PARSER(cp_op_dump_const_ram) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0038300); - - auto offset = buffer[0]; - auto dw_num = buffer[1]; - auto* dst = reinterpret_cast(buffer[2] | (static_cast(buffer[3]) << 32u)); - - EXIT_NOT_IMPLEMENTED(dw_num >= 0x3000); - EXIT_NOT_IMPLEMENTED(offset > 0xbffc); - EXIT_NOT_IMPLEMENTED((offset & 0x3u) != 0); - - cp->DumpConstRam(dst, offset, dw_num); - - return 4; -} - -KYTY_CP_OP_PARSER(cp_op_wait_reg_mem) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0053C00); - - auto func = buffer[0] & 0x7u; - bool me = (buffer[0] & 0x100u) == 0; - bool mem = (buffer[0] & 0x10u) != 0; - auto* addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); - auto ref = buffer[3]; - auto mask = buffer[4]; - auto poll = buffer[5]; - - cp->WaitRegMem(func, me, mem, addr, ref, mask, poll); - - return 6; -} - -KYTY_CP_OP_PARSER(cp_op_wait_on_address) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC00C1028); - - auto* addr = reinterpret_cast(buffer[0] | (static_cast(buffer[1]) << 32u)); - bool me = true; - bool mem = true; - auto mask = buffer[2]; - auto func = buffer[3]; - auto ref = buffer[4]; - auto poll = 10; - - cp->WaitRegMem(func, me, mem, addr, ref, mask, poll); - - return 13; -} - // NOLINTNEXTLINE(readability-function-cognitive-complexity) KYTY_CP_OP_PARSER(cp_op_acquire_mem) { @@ -2741,25 +2404,266 @@ KYTY_CP_OP_PARSER(cp_op_acquire_mem) return 6; } -KYTY_CP_OP_PARSER(cp_op_wait_on_de_counter_diff) +KYTY_CP_OP_PARSER(cp_op_dispatch_direct) { KYTY_PROFILER_FUNCTION(); - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008800); + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0071020); - cp->WaitDeDiff(buffer[0]); + uint32_t thread_group_x = buffer[0]; + uint32_t thread_group_y = buffer[1]; + uint32_t thread_group_z = buffer[2]; + uint32_t mode = buffer[3]; + + cp->DispatchDirect(thread_group_x, thread_group_y, thread_group_z, mode); + + return 8; +} + +KYTY_CP_OP_PARSER(cp_op_dispatch_reset) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0001024); + + cp->Reset(); return 1; } -KYTY_CP_OP_PARSER(cp_op_wait_on_ce_counter) +KYTY_CP_OP_PARSER(cp_op_dma_data) { KYTY_PROFILER_FUNCTION(); - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008600); + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0055000); + + uint32_t type = buffer[0]; + uint32_t type2 = (buffer[5] >> 21u); + uint64_t src = (buffer[1] | (static_cast(buffer[2]) << 32u)); + uint64_t dst = (buffer[3] | (static_cast(buffer[4]) << 32u)); + uint32_t size = buffer[5] & 0x1fffffu; + + if (type == 0x60000000 && dst == 0x0003022C && type2 == 0x141u) + { + auto* addr = reinterpret_cast(src); + + cp->PrefetchL2(addr, size); + } else if (type == 0xc4104000 && type2 == 0x0u) + { + EXIT_NOT_IMPLEMENTED((dst & 0x3u) != 0); + EXIT_NOT_IMPLEMENTED((size & 0x3u) != 0); + + cp->ClearGds(dst / 4, size / 4, static_cast(src)); + } else if (type == 0xa4004000 && type2 == 0x0u) + { + EXIT_NOT_IMPLEMENTED((src & 0x3u) != 0); + EXIT_NOT_IMPLEMENTED((size & 0x3u) != 0); + + auto* addr = reinterpret_cast(dst); + + cp->ReadGds(addr, src / 4, size / 4); + } else + { + EXIT("unknown dma\n"); + } + + return 6; +} + +KYTY_CP_OP_PARSER(cp_op_draw_index) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC008100C && cmd_id != 0xc0042700); + + if (cmd_id == 0xC008100C) + { + uint32_t index_count = buffer[0]; + auto* index_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + uint32_t flags = buffer[3]; + uint32_t type = buffer[4]; + + cp->DrawIndex(index_count, index_addr, flags, type); + + return 9; + } + + if (cmd_id == 0xc0042700) + { + uint32_t index_count = buffer[0]; + auto* index_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + + EXIT_NOT_IMPLEMENTED(buffer[3] != index_count); + EXIT_NOT_IMPLEMENTED(buffer[4] != 0); + + cp->DrawIndex(index_count, index_addr, 0, 1); + + EXIT_NOT_IMPLEMENTED(!(dw >= 7)); + + if (buffer[5] == 0xc0001000) + { + EXIT_NOT_IMPLEMENTED(buffer[6] != 0); + + return 7; + } + + if (buffer[5] == 0xc0021000) + { + EXIT_NOT_IMPLEMENTED(buffer[6] != 0); + + return 9; + } + + EXIT("invalid draw_index\n"); + } + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_draw_index_auto) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0051010 && cmd_id != 0xc0012d00); + + if (cmd_id == 0xC0051010) + { + uint32_t index_count = buffer[0]; + uint32_t flags = buffer[1]; + + cp->DrawIndexAuto(index_count, flags); + + return 6; + } + + if (cmd_id == 0xc0012d00) + { + uint32_t index_count = buffer[0]; + uint32_t flags = 0; + + EXIT_NOT_IMPLEMENTED(buffer[1] != 2); + + cp->DrawIndexAuto(index_count, flags); + + EXIT_NOT_IMPLEMENTED(!(dw >= 4)); + + if (buffer[2] == 0xc0001000) + { + EXIT_NOT_IMPLEMENTED(buffer[3] != 0); + + return 4; + } + + if (buffer[2] == 0xc0021000) + { + EXIT_NOT_IMPLEMENTED(buffer[3] != 0); + + return 6; + } + + EXIT("invalid draw_index_auto\n"); + } + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_draw_reset) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0001014); + + cp->Reset(); + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_dump_const_ram) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0038300); + + auto offset = buffer[0]; + auto dw_num = buffer[1]; + auto* dst = reinterpret_cast(buffer[2] | (static_cast(buffer[3]) << 32u)); + + EXIT_NOT_IMPLEMENTED(dw_num >= 0x3000); + EXIT_NOT_IMPLEMENTED(offset > 0xbffc); + EXIT_NOT_IMPLEMENTED((offset & 0x3u) != 0); + + cp->DumpConstRam(dst, offset, dw_num); + + return 4; +} + +KYTY_CP_OP_PARSER(cp_op_event_write) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0004600); + + uint32_t event_index = (buffer[0] >> 8u) & 0x7u; + uint32_t event_type = (buffer[0]) & 0x3fu; + + cp->TriggerEvent(event_type, event_index); + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_event_write_eop) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0044700); + + uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; + uint32_t event_write_dest = ((buffer[0] >> 23u) & 0x10u) | ((buffer[2] >> 16u) & 0x01u); + uint32_t eop_event_type = (buffer[0]) & 0x3fu; + uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; + uint32_t event_index = (buffer[0] >> 8u) & 0x7u; + uint32_t event_write_source = ((buffer[2] >> 29u) & 0x7u); + uint32_t interrupt_selector = (buffer[2] >> 24u) & 0x7u; + auto* dst_gpu_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2] & 0xffffu) << 32u)); + uint64_t value = (buffer[3] | (static_cast(buffer[4]) << 32u)); + + cp->WriteAtEndOfPipe64(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, + value, interrupt_selector); + + return 5; +} + +KYTY_CP_OP_PARSER(cp_op_event_write_eos) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0034802); + + uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; + uint32_t event_write_dest = 0; + uint32_t eop_event_type = (buffer[0]) & 0x3fu; + uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; + uint32_t event_index = (buffer[0] >> 8u) & 0x7u; + uint32_t event_write_source = ((buffer[2] >> 29u) & 0x7u); + uint32_t interrupt_selector = (buffer[2] >> 24u) & 0x7u; + + auto* dst_gpu_addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2] & 0xffffu) << 32u)); + uint32_t value = buffer[3]; + + cp->WriteAtEndOfPipe32(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, + value, interrupt_selector); + + return 4; +} + +KYTY_CP_OP_PARSER(cp_op_increment_ce_counter) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008400); EXIT_NOT_IMPLEMENTED(buffer[0] != 1); - cp->WaitCe(); + cp->IncremenetCe(); return 1; } @@ -2776,18 +2680,109 @@ KYTY_CP_OP_PARSER(cp_op_increment_de_counter) return 1; } -KYTY_CP_OP_PARSER(cp_op_increment_ce_counter) +KYTY_CP_OP_PARSER(cp_op_index_type) { KYTY_PROFILER_FUNCTION(); - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008400); - EXIT_NOT_IMPLEMENTED(buffer[0] != 1); + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0002A00); - cp->IncremenetCe(); + cp->SetIndexType(buffer[0]); return 1; } +KYTY_CP_OP_PARSER(cp_op_indirect_buffer) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0023f02); + + EXIT_NOT_IMPLEMENTED((buffer[2] & 0xff00000u) != 0x1800000u); + + auto* indirect_buffer = reinterpret_cast(buffer[0] | (static_cast(buffer[1] & 0xffffu) << 32u)); + uint32_t indirect_num_dw = buffer[2] & 0xfffffu; + + EXIT_NOT_IMPLEMENTED(indirect_buffer == nullptr); + EXIT_NOT_IMPLEMENTED(indirect_num_dw == 0); + + GraphicsDbgDumpDcb("ci", indirect_num_dw, indirect_buffer); + + cp->Run(indirect_buffer, indirect_num_dw); + + return 3; +} + +KYTY_CP_OP_PARSER(cp_op_indirect_cx_regs) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0021048); + + auto* indirect_buffer = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + uint32_t indirect_num_dw = buffer[0]; + + EXIT_NOT_IMPLEMENTED(indirect_buffer == nullptr); + EXIT_NOT_IMPLEMENTED(indirect_num_dw == 0); + + for (uint32_t i = 0; i < indirect_num_dw; i++, indirect_buffer += 2) + { + auto cmd_offset = indirect_buffer[0]; + auto value = indirect_buffer[1]; + + if (cmd_offset >= Pm4::SPI_PS_INPUT_CNTL_0 && cmd_offset <= Pm4::SPI_PS_INPUT_CNTL_31) + { + uint32_t slot = cmd_offset - Pm4::SPI_PS_INPUT_CNTL_0; + cp->GetCtx()->SetPsInputSettings(slot, value); + continue; + } + + switch (cmd_offset) + { + case Pm4::SPI_VS_OUT_CONFIG: cp->GetCtx()->SetVsOutConfig(value); break; + case Pm4::SPI_SHADER_POS_FORMAT: cp->GetCtx()->SetShaderPosFormat(value); break; + case Pm4::SPI_SHADER_IDX_FORMAT: cp->GetCtx()->SetShaderIdxFormat(value); break; + case Pm4::PA_CL_VS_OUT_CNTL: cp->GetCtx()->SetClVsOutCntl(value); break; + case Pm4::GE_NGG_SUBGRP_CNTL: cp->GetCtx()->SetNggSubgrpCntl(value); break; + case Pm4::VGT_GS_INSTANCE_CNT: cp->GetCtx()->SetGsInstanceCnt(value); break; + case Pm4::VGT_GS_ONCHIP_CNTL: cp->GetCtx()->SetGsOnchipCntl(value); break; + case Pm4::GE_MAX_OUTPUT_PER_SUBGROUP: cp->GetCtx()->SetMaxOutputPerSubgroup(value); break; + case Pm4::VGT_ESGS_RING_ITEMSIZE: cp->GetCtx()->SetEsgsRingItemsize(value); break; + case Pm4::VGT_GS_MAX_VERT_OUT: cp->GetCtx()->SetGsMaxVertOut(value); break; + case Pm4::VGT_SHADER_STAGES_EN: cp->GetCtx()->SetShaderStages(value); break; + case Pm4::VGT_GS_OUT_PRIM_TYPE: cp->GetCtx()->SetGsOutPrimType(value); break; + case Pm4::SPI_SHADER_Z_FORMAT: cp->GetCtx()->SetShaderZFormat(value); break; + case Pm4::SPI_SHADER_COL_FORMAT: + for (uint32_t i = 0; i < 8; i++) + { + cp->GetCtx()->SetTargetOutputMode(i, (value >> (i * 4)) & 0xFu); + } + break; + case Pm4::SPI_PS_INPUT_ENA: cp->GetCtx()->SetPsInputEna(value); break; + case Pm4::SPI_PS_INPUT_ADDR: cp->GetCtx()->SetPsInputAddr(value); break; + case Pm4::SPI_PS_IN_CONTROL: cp->GetCtx()->SetPsInControl(value); break; + case Pm4::SPI_BARYC_CNTL: cp->GetCtx()->SetBarycCntl(value); break; + case Pm4::DB_SHADER_CONTROL: + { + HW::DepthShaderControl db_shader_control {}; + db_shader_control.other_bits = value & 0xFFFF9B8Eu; + db_shader_control.conservative_z_export_value = KYTY_PM4_GET(value, DB_SHADER_CONTROL, CONSERVATIVE_Z_EXPORT); + db_shader_control.shader_z_behavior = KYTY_PM4_GET(value, DB_SHADER_CONTROL, Z_ORDER); + db_shader_control.shader_kill_enable = KYTY_PM4_GET(value, DB_SHADER_CONTROL, KILL_ENABLE) != 0; + db_shader_control.shader_z_export_enable = KYTY_PM4_GET(value, DB_SHADER_CONTROL, Z_EXPORT_ENABLE) != 0; + db_shader_control.shader_execute_on_noop = KYTY_PM4_GET(value, DB_SHADER_CONTROL, EXEC_ON_NOOP) != 0; + cp->GetCtx()->SetDepthShaderControl(db_shader_control); + break; + } + case Pm4::CB_SHADER_MASK: cp->GetCtx()->SetShaderMask(value); break; + case Pm4::PA_SC_SHADER_CONTROL: cp->GetCtx()->SetScShaderControl(value); break; + + default: EXIT("unknown cx reg at %05" PRIx32 ": 0x%" PRIx32 "\n", num_dw - dw, cmd_offset); + } + } + + return 3; +} + KYTY_CP_OP_PARSER(cp_op_marker) { KYTY_PROFILER_FUNCTION(); @@ -2830,83 +2825,269 @@ KYTY_CP_OP_PARSER(cp_op_marker) return len_dw + 1; } -KYTY_CP_OP_PARSER(cp_op_dma_data) -{ - KYTY_PROFILER_FUNCTION(); - - EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0055000); - - uint32_t type = buffer[0]; - uint32_t type2 = (buffer[5] >> 21u); - uint64_t src = (buffer[1] | (static_cast(buffer[2]) << 32u)); - uint64_t dst = (buffer[3] | (static_cast(buffer[4]) << 32u)); - uint32_t size = buffer[5] & 0x1fffffu; - - if (type == 0x60000000 && dst == 0x0003022C && type2 == 0x141u) - { - auto* addr = reinterpret_cast(src); - - cp->PrefetchL2(addr, size); - } else if (type == 0xc4104000 && type2 == 0x0u) - { - EXIT_NOT_IMPLEMENTED((dst & 0x3u) != 0); - EXIT_NOT_IMPLEMENTED((size & 0x3u) != 0); - - cp->ClearGds(dst / 4, size / 4, static_cast(src)); - } else if (type == 0xa4004000 && type2 == 0x0u) - { - EXIT_NOT_IMPLEMENTED((src & 0x3u) != 0); - EXIT_NOT_IMPLEMENTED((size & 0x3u) != 0); - - auto* addr = reinterpret_cast(dst); - - cp->ReadGds(addr, src / 4, size / 4); - } else - { - EXIT("unknown dma\n"); - } - - return 6; -} - KYTY_CP_OP_PARSER(cp_op_nop) { KYTY_PROFILER_FUNCTION(); - auto r = (cmd_id >> 2u) & 0x3fu; + auto r = KYTY_PM4_R(cmd_id); - switch (r) + if (r == Pm4::R_ZERO) { - case Pm4::R_ZERO: - if ((buffer[0] & 0xffff0000u) == 0x68750000u) - { - return cp_op_marker(cp, cmd_id, buffer, dw, num_dw); - } - break; - case Pm4::R_VS: return hw_ctx_set_vs_shader(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_PS: return hw_ctx_set_ps_shader(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_CS: return hw_ctx_set_cs_shader(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_DRAW_INDEX: return cp_op_draw_index(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_DRAW_INDEX_AUTO: return cp_op_draw_index_auto(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_DISPATCH_DIRECT: return cp_op_dispatch_direct(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_DISPATCH_RESET: return cp_op_dispatch_reset(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_DISPATCH_WAIT_MEM: return cp_op_wait_on_address(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_DRAW_RESET: return cp_op_draw_reset(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_WAIT_FLIP_DONE: return cp_op_wait_flip_done(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_PUSH_MARKER: return cp_op_push_marker(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_POP_MARKER: return cp_op_pop_marker(cp, cmd_id, buffer, dw, num_dw); break; - case Pm4::R_VS_EMBEDDED: return hw_ctx_set_vs_embedded(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_PS_EMBEDDED: return hw_ctx_set_ps_embedded(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_VS_UPDATE: return hw_ctx_update_vs_shader(cp, cmd_id, 0, buffer, dw); break; - case Pm4::R_PS_UPDATE: return hw_ctx_update_ps_shader(cp, cmd_id, 0, buffer, dw); break; - default: break; + if ((buffer[0] & 0xffff0000u) == 0x68750000u) + { + return cp_op_marker(cp, cmd_id, buffer, dw, num_dw); + } } - EXIT("unknown r at %05" PRIx32 ": %u\n", num_dw - dw, r); + auto hw_ctx = g_hw_sh_custom_func[r]; + auto cp_op = g_cp_op_custom_func[r]; + + if (hw_ctx != nullptr && cp_op == nullptr) + { + return hw_ctx(cp, cmd_id, 0, buffer, dw); + } + + if (hw_ctx == nullptr && cp_op != nullptr) + { + return cp_op(cp, cmd_id, buffer, dw, num_dw); + } + + EXIT("unknown custom code at 0x%05" PRIx32 ": 0x%02" PRIx32 "\n", num_dw - dw, r); return 0; } +KYTY_CP_OP_PARSER(cp_op_num_instances) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0002f00); + + cp->SetNumInstances(buffer[0]); + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_pop_marker) +{ + KYTY_PROFILER_FUNCTION(); + + auto dw_num = (cmd_id >> 16u) & 0x3fffu; + + printf("Pop marker\n"); + + cp->PopMarker(); + + return dw_num + 1; +} + +KYTY_CP_OP_PARSER(cp_op_push_marker) +{ + KYTY_PROFILER_FUNCTION(); + + auto dw_num = (cmd_id >> 16u) & 0x3fffu; + + const char* str = reinterpret_cast(buffer); + + printf("Push marker: %s\n", str); + + cp->PushMarker(str); + + return dw_num + 1; +} + +KYTY_CP_OP_PARSER(cp_op_release_mem) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0054902); + + uint32_t cache_policy = (buffer[0] >> 25u) & 0x3u; + uint32_t cache_action = (buffer[0] >> 12u) & 0x3fu; + uint32_t eop_event_type = (buffer[0]) & 0x3fu; + uint32_t event_index = (buffer[0] >> 8u) & 0x7u; + uint32_t event_write_dest = ((buffer[0] >> 23u) & 0x10u) | ((buffer[1] >> 16u) & 0x01u); + uint32_t event_write_source = (buffer[1] >> 29u) & 0x7u; + uint32_t interrupt_selector = (buffer[1] >> 24u) & 0x7u; + auto* dst_gpu_addr = reinterpret_cast(buffer[2] | (static_cast(buffer[3]) << 32u)); + uint64_t value = (buffer[4] | (static_cast(buffer[5]) << 32u)); + + cp->WriteAtEndOfPipe64(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr, + value, interrupt_selector); + + return 6; +} + +KYTY_CP_OP_PARSER(cp_op_set_context_reg) +{ + KYTY_PROFILER_FUNCTION(); + + auto cmd_offset = buffer[0]; + + EXIT_NOT_IMPLEMENTED(cmd_offset >= Pm4::CX_NUM); + + auto pfunc = g_hw_ctx_func[cmd_offset & (Pm4::CX_NUM - 1)]; + + if (pfunc == nullptr) + { + EXIT("unknown context register\n\t%05" PRIx32 ":\n\tcmd_id = %08" PRIx32 "\n\tcmd_offset = %08" PRIx32 "\n", num_dw - dw, cmd_id, + cmd_offset); + } + + auto s = pfunc(cp, cmd_id, cmd_offset, buffer + 1, dw); + + EXIT_IF(s == 0); + + return s + 1; +} + +KYTY_CP_OP_PARSER(cp_op_set_shader_reg) +{ + KYTY_PROFILER_FUNCTION(); + + auto cmd_offset = buffer[0]; + + EXIT_NOT_IMPLEMENTED(cmd_offset >= Pm4::SH_NUM); + + auto pfunc = g_hw_sh_func[cmd_offset & (Pm4::SH_NUM - 1)]; + + if (pfunc == nullptr) + { + EXIT("unknown shader register\n\t%05" PRIx32 ":\n\tcmd_id = %08" PRIx32 "\n\tcmd_offset = %08" PRIx32 "\n", num_dw - dw, cmd_id, + cmd_offset); + } + + auto s = pfunc(cp, cmd_id, cmd_offset, buffer + 1, dw); + EXIT_IF(s == 0); + return s + 1; +} + +KYTY_CP_OP_PARSER(cp_op_set_uconfig_reg) +{ + KYTY_PROFILER_FUNCTION(); + + auto cmd_offset = buffer[0] & 0xEFFFFFFFu; // ignore neo bit + + EXIT_NOT_IMPLEMENTED(cmd_offset >= Pm4::UC_NUM); + + auto pfunc = g_hw_uc_func[cmd_offset & (Pm4::UC_NUM - 1)]; + + if (pfunc == nullptr) + { + EXIT("unknown user config register\n\t%05" PRIx32 ":\n\tcmd_id = %08" PRIx32 "\n\tcmd_offset = %08" PRIx32 "\n", num_dw - dw, + cmd_id, cmd_offset); + } + + auto s = pfunc(cp, cmd_id, cmd_offset, buffer + 1, dw); + EXIT_IF(s == 0); + return s + 1; +} + +KYTY_CP_OP_PARSER(cp_op_wait_flip_done) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0051018); + + auto video_out_handle = buffer[0]; + auto display_buffer_index = buffer[1]; + + cp->WaitFlipDone(video_out_handle, display_buffer_index); + + return 6; +} + +KYTY_CP_OP_PARSER(cp_op_wait_on_address) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC00C1028); + + auto* addr = reinterpret_cast(buffer[0] | (static_cast(buffer[1]) << 32u)); + bool me = true; + bool mem = true; + auto mask = buffer[2]; + auto func = buffer[3]; + auto ref = buffer[4]; + auto poll = 10; + + cp->WaitRegMem(func, me, mem, addr, ref, mask, poll); + + return 13; +} + +KYTY_CP_OP_PARSER(cp_op_wait_on_ce_counter) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008600); + EXIT_NOT_IMPLEMENTED(buffer[0] != 1); + + cp->WaitCe(); + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_wait_on_de_counter_diff) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0008800); + + cp->WaitDeDiff(buffer[0]); + + return 1; +} + +KYTY_CP_OP_PARSER(cp_op_wait_reg_mem) +{ + KYTY_PROFILER_FUNCTION(); + + EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0053C00); + + auto func = buffer[0] & 0x7u; + bool me = (buffer[0] & 0x100u) == 0; + bool mem = (buffer[0] & 0x10u) != 0; + auto* addr = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + auto ref = buffer[3]; + auto mask = buffer[4]; + auto poll = buffer[5]; + + cp->WaitRegMem(func, me, mem, addr, ref, mask, poll); + + return 6; +} + +KYTY_CP_OP_PARSER(cp_op_write_const_ram) +{ + KYTY_PROFILER_FUNCTION(); + + auto dw_num = (cmd_id >> 16u) & 0x3fffu; + auto offset = buffer[0]; + + EXIT_NOT_IMPLEMENTED(dw_num >= 0x3000); + EXIT_NOT_IMPLEMENTED(offset > 0xbffc); + EXIT_NOT_IMPLEMENTED((offset & 0x3u) != 0); + + cp->WriteConstRam(offset, buffer + 1, dw_num); + + return 1 + dw_num; +} + +KYTY_CP_OP_PARSER(cp_op_write_data) +{ + KYTY_PROFILER_FUNCTION(); + + auto dw_num = (cmd_id >> 16u) & 0x3fffu; + + auto write_control = buffer[0]; + auto* dst = reinterpret_cast(buffer[1] | (static_cast(buffer[2]) << 32u)); + + cp->WriteData(dst, buffer + 3, dw_num - 2, write_control); + + return 1 + dw_num; +} + static void graphics_init_jmp_tables() { for (auto& func: g_hw_ctx_func) @@ -2920,8 +3101,8 @@ static void graphics_init_jmp_tables() g_hw_ctx_func[Pm4::PA_SC_SCREEN_SCISSOR_TL] = hw_ctx_set_screen_scissor; g_hw_ctx_func[Pm4::DB_Z_INFO] = hw_ctx_set_depth_render_target; g_hw_ctx_func[Pm4::DB_STENCIL_INFO] = hw_ctx_set_stencil_info; - g_hw_ctx_func[0x08d] = hw_ctx_hardware_screen_offset; - g_hw_ctx_func[0x08e] = hw_ctx_set_render_target_mask; + g_hw_ctx_func[Pm4::PA_SU_HARDWARE_SCREEN_OFFSET] = hw_ctx_set_hardware_screen_offset; + g_hw_ctx_func[Pm4::CB_TARGET_MASK] = hw_ctx_set_render_target_mask; g_hw_ctx_func[Pm4::PA_SC_GENERIC_SCISSOR_TL] = hw_ctx_set_generic_scissor; g_hw_ctx_func[Pm4::CB_BLEND_RED] = hw_ctx_set_blend_color; g_hw_ctx_func[Pm4::DB_STENCIL_CONTROL] = hw_ctx_set_stencil_control; @@ -2930,15 +3111,15 @@ static void graphics_init_jmp_tables() g_hw_ctx_func[Pm4::DB_DEPTH_CONTROL] = hw_ctx_set_depth_control; g_hw_ctx_func[Pm4::DB_EQAA] = hw_ctx_set_eqaa_control; g_hw_ctx_func[Pm4::CB_COLOR_CONTROL] = hw_ctx_set_color_control; - g_hw_ctx_func[0x204] = hw_ctx_set_clip_control; + g_hw_ctx_func[Pm4::PA_CL_CLIP_CNTL] = hw_ctx_set_clip_control; g_hw_ctx_func[Pm4::PA_SU_SC_MODE_CNTL] = hw_ctx_set_mode_control; - g_hw_ctx_func[0x206] = hw_ctx_set_viewport_transform_control; + g_hw_ctx_func[Pm4::PA_CL_VTE_CNTL] = hw_ctx_set_viewport_transform_control; g_hw_ctx_func[Pm4::PA_SU_LINE_CNTL] = hw_ctx_set_line_control; g_hw_ctx_func[Pm4::PA_SC_MODE_CNTL_0] = hw_ctx_set_scan_mode_control; g_hw_ctx_func[Pm4::PA_SC_AA_CONFIG] = hw_ctx_set_aa_config; g_hw_ctx_func[Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0] = hw_ctx_set_aa_sample_control; g_hw_ctx_func[Pm4::VGT_SHADER_STAGES_EN] = hw_ctx_set_shader_stages; - g_hw_ctx_func[0x2fa] = hw_ctx_set_guard_bands; + g_hw_ctx_func[Pm4::PA_CL_GB_VERT_CLIP_ADJ] = hw_ctx_set_guard_bands; for (uint32_t slot = 0; slot < 8; slot++) { @@ -2954,6 +3135,38 @@ static void graphics_init_jmp_tables() g_hw_ctx_func[Pm4::PA_CL_VPORT_XSCALE + viewport * 6] = hw_ctx_set_viewport_scale_offset; } + for (auto& func: g_hw_sh_func) + { + func = nullptr; + } + + for (uint32_t slot = 0; slot < 16; slot++) + { + g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_VS_0 + slot * 1] = hw_sh_set_vs_user_sgpr; + g_hw_sh_func[Pm4::SPI_SHADER_USER_DATA_PS_0 + slot * 1] = hw_sh_set_ps_user_sgpr; + g_hw_sh_func[Pm4::COMPUTE_USER_DATA_0 + slot * 1] = hw_sh_set_cs_user_sgpr; + } + + for (auto& func: g_hw_uc_func) + { + func = nullptr; + } + + g_hw_uc_func[Pm4::VGT_PRIMITIVE_TYPE] = hw_uc_set_primitive_type; + + for (auto& func: g_hw_sh_custom_func) + { + func = nullptr; + } + + g_hw_sh_custom_func[Pm4::R_VS] = hw_sh_set_vs_shader; + g_hw_sh_custom_func[Pm4::R_PS] = hw_sh_set_ps_shader; + g_hw_sh_custom_func[Pm4::R_CS] = hw_sh_set_cs_shader; + g_hw_sh_custom_func[Pm4::R_VS_EMBEDDED] = hw_sh_set_vs_embedded; + g_hw_sh_custom_func[Pm4::R_PS_EMBEDDED] = hw_sh_set_ps_embedded; + g_hw_sh_custom_func[Pm4::R_VS_UPDATE] = hw_sh_update_vs_shader; + g_hw_sh_custom_func[Pm4::R_PS_UPDATE] = hw_sh_update_ps_shader; + for (auto& func: g_cp_op_func) { func = nullptr; @@ -2982,6 +3195,22 @@ static void graphics_init_jmp_tables() g_cp_op_func[Pm4::IT_INCREMENT_DE_COUNTER] = cp_op_increment_de_counter; g_cp_op_func[Pm4::IT_WAIT_ON_CE_COUNTER] = cp_op_wait_on_ce_counter; g_cp_op_func[Pm4::IT_WAIT_ON_DE_COUNTER_DIFF] = cp_op_wait_on_de_counter_diff; + + for (auto& func: g_cp_op_custom_func) + { + func = nullptr; + } + + g_cp_op_custom_func[Pm4::R_DRAW_INDEX] = cp_op_draw_index; + g_cp_op_custom_func[Pm4::R_DRAW_INDEX_AUTO] = cp_op_draw_index_auto; + g_cp_op_custom_func[Pm4::R_DISPATCH_DIRECT] = cp_op_dispatch_direct; + g_cp_op_custom_func[Pm4::R_DISPATCH_RESET] = cp_op_dispatch_reset; + g_cp_op_custom_func[Pm4::R_WAIT_MEM_32] = cp_op_wait_on_address; + g_cp_op_custom_func[Pm4::R_DRAW_RESET] = cp_op_draw_reset; + g_cp_op_custom_func[Pm4::R_WAIT_FLIP_DONE] = cp_op_wait_flip_done; + g_cp_op_custom_func[Pm4::R_PUSH_MARKER] = cp_op_push_marker; + g_cp_op_custom_func[Pm4::R_POP_MARKER] = cp_op_pop_marker; + g_cp_op_custom_func[Pm4::R_CX_REGS_INDIRECT] = cp_op_indirect_cx_regs; } } // namespace Kyty::Libs::Graphics diff --git a/source/emulator/src/Graphics/Pm4.cpp b/source/emulator/src/Graphics/Pm4.cpp index 9cb4ea0..a4005f6 100644 --- a/source/emulator/src/Graphics/Pm4.cpp +++ b/source/emulator/src/Graphics/Pm4.cpp @@ -7,9 +7,9 @@ namespace Kyty::Libs::Graphics::Pm4 { -static const char* g_names[256] = {}; -static const char* g_r_names[64] = {}; -static bool g_names_initialized = false; +static const char* g_names[256] = {}; +static const char* g_r_names[Pm4::R_NUM] = {}; +static bool g_names_initialized = false; static void init_names() { @@ -25,26 +25,31 @@ static void init_names() n = ""; } - g_r_names[R_ZERO] = "R_ZERO"; - g_r_names[R_VS] = "R_VS"; - g_r_names[R_PS] = "R_PS"; - g_r_names[R_DRAW_INDEX] = "R_DRAW_INDEX"; - g_r_names[R_DRAW_INDEX_AUTO] = "R_DRAW_INDEX_AUTO"; - g_r_names[R_DRAW_RESET] = "R_DRAW_RESET"; - g_r_names[R_WAIT_FLIP_DONE] = "R_WAIT_FLIP_DONE"; - g_r_names[R_CS] = "R_CS"; - g_r_names[R_DISPATCH_DIRECT] = "R_DISPATCH_DIRECT"; - g_r_names[R_DISPATCH_RESET] = "R_DISPATCH_RESET"; - g_r_names[R_DISPATCH_WAIT_MEM] = "R_DISPATCH_WAIT_MEM"; - g_r_names[R_PUSH_MARKER] = "R_PUSH_MARKER"; - g_r_names[R_POP_MARKER] = "R_POP_MARKER"; - g_r_names[R_VS_EMBEDDED] = "R_VS_EMBEDDED"; - g_r_names[R_PS_EMBEDDED] = "R_PS_EMBEDDED"; - g_r_names[R_VS_UPDATE] = "R_VS_UPDATE"; - g_r_names[R_PS_UPDATE] = "R_PS_UPDATE"; - g_r_names[R_CX_REGS] = "R_CX_REGS"; - g_r_names[R_SH_REGS] = "R_SH_REGS"; - g_r_names[R_UC_REGS] = "R_UC_REGS"; + g_r_names[R_ZERO] = "R_ZERO"; + g_r_names[R_VS] = "R_VS"; + g_r_names[R_PS] = "R_PS"; + g_r_names[R_DRAW_INDEX] = "R_DRAW_INDEX"; + g_r_names[R_DRAW_INDEX_AUTO] = "R_DRAW_INDEX_AUTO"; + g_r_names[R_DRAW_RESET] = "R_DRAW_RESET"; + g_r_names[R_WAIT_FLIP_DONE] = "R_WAIT_FLIP_DONE"; + g_r_names[R_CS] = "R_CS"; + g_r_names[R_DISPATCH_DIRECT] = "R_DISPATCH_DIRECT"; + g_r_names[R_DISPATCH_RESET] = "R_DISPATCH_RESET"; + g_r_names[R_WAIT_MEM_32] = "R_WAIT_MEM_32"; + g_r_names[R_PUSH_MARKER] = "R_PUSH_MARKER"; + g_r_names[R_POP_MARKER] = "R_POP_MARKER"; + g_r_names[R_VS_EMBEDDED] = "R_VS_EMBEDDED"; + g_r_names[R_PS_EMBEDDED] = "R_PS_EMBEDDED"; + g_r_names[R_VS_UPDATE] = "R_VS_UPDATE"; + g_r_names[R_PS_UPDATE] = "R_PS_UPDATE"; + g_r_names[R_CX_REGS_INDIRECT] = "R_CX_REGS_INDIRECT"; + g_r_names[R_SH_REGS_INDIRECT] = "R_SH_REGS_INDIRECT"; + g_r_names[R_UC_REGS_INDIRECT] = "R_UC_REGS_INDIRECT"; + g_r_names[R_ACQUIRE_MEM] = "R_ACQUIRE_MEM"; + g_r_names[R_WRITE_DATA] = "R_WRITE_DATA"; + g_r_names[R_WAIT_MEM_64] = "R_WAIT_MEM_64"; + g_r_names[R_FLIP] = "R_FLIP"; + g_r_names[R_RELEASE_MEM] = "R_RELEASE_MEM"; g_names[IT_NOP] = "IT_NOP"; g_names[IT_SET_BASE] = "IT_SET_BASE"; @@ -131,7 +136,7 @@ void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_ bool sh_gx = (cmd_id & 0x2u) == 0; len = ((cmd_id >> 16u) & 0x3fffu) + 1; uint8_t op = ((cmd_id >> 8u) & 0xffu); - auto r = ((cmd_id >> 2u) & 0x3fu); + auto r = KYTY_PM4_R(cmd_id); file->Printf("%s %s(OP:0x%02" PRIx8 ") SH:%s CNT:%u\n", g_names[op], (op == IT_NOP ? g_r_names[r] : ""), op, sh_gx ? "GX" : "CX", len); @@ -140,6 +145,18 @@ void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_ { file->Printf(" | 0x%08" PRIx32 " | \n", cmd[i]); } + + if (op == IT_NOP && (r == R_CX_REGS_INDIRECT || r == R_SH_REGS_INDIRECT || r == R_UC_REGS_INDIRECT) && len == 3) + { + auto* indirect_buffer = reinterpret_cast(cmd[1] | (static_cast(cmd[2]) << 32u)); + uint32_t indirect_num_dw = cmd[0]; + + for (uint32_t i = 0; i < indirect_num_dw; i++, indirect_buffer += 2) + { + file->Printf(" | | offset = 0x%08" PRIx32 ", value = 0x%08" PRIx32 "\n", indirect_buffer[0], + indirect_buffer[1]); + } + } } else { file->Printf("?????\n"); diff --git a/source/emulator/src/Graphics/Shader.cpp b/source/emulator/src/Graphics/Shader.cpp index 9e10d79..13760df 100644 --- a/source/emulator/src/Graphics/Shader.cpp +++ b/source/emulator/src/Graphics/Shader.cpp @@ -2088,7 +2088,7 @@ KYTY_SHADER_PARSER(shader_parse) return ptr - src; } -static void vs_print(const char* func, const HW::VsStageRegisters& vs) +static void vs_print(const char* func, const HW::VsStageRegisters& vs, const HW::ShaderRegisters& sh) { printf("%s\n", func); @@ -2098,12 +2098,23 @@ static void vs_print(const char* func, const HW::VsStageRegisters& vs) printf("\t GetInputComponentsCount() = 0x%08" PRIx32 "\n", vs.GetInputComponentsCount()); printf("\t GetUnknown1() = 0x%08" PRIx32 "\n", vs.GetUnknown1()); printf("\t GetUnknown2() = 0x%08" PRIx32 "\n", vs.GetUnknown2()); - printf("\t m_spiVsOutConfig = 0x%08" PRIx32 "\n", vs.m_spiVsOutConfig); - printf("\t m_spiShaderPosFormat = 0x%08" PRIx32 "\n", vs.m_spiShaderPosFormat); - printf("\t m_paClVsOutCntl = 0x%08" PRIx32 "\n", vs.m_paClVsOutCntl); + printf("\t m_spiVsOutConfig = 0x%08" PRIx32 "\n", sh.m_spiVsOutConfig); + printf("\t m_spiShaderPosFormat = 0x%08" PRIx32 "\n", sh.m_spiShaderPosFormat); + printf("\t m_paClVsOutCntl = 0x%08" PRIx32 "\n", sh.m_paClVsOutCntl); + + printf("\t m_spiShaderIdxFormat = 0x%08" PRIx32 "\n", sh.m_spiShaderIdxFormat); + printf("\t m_geNggSubgrpCntl = 0x%08" PRIx32 "\n", sh.m_geNggSubgrpCntl); + printf("\t m_vgtGsInstanceCnt = 0x%08" PRIx32 "\n", sh.m_vgtGsInstanceCnt); + printf("\t GetEsVertsPerSubgrp() = 0x%08" PRIx32 "\n", sh.GetEsVertsPerSubgrp()); + printf("\t GetGsPrimsPerSubgrp() = 0x%08" PRIx32 "\n", sh.GetGsPrimsPerSubgrp()); + printf("\t GetGsInstPrimsInSubgrp() = 0x%08" PRIx32 "\n", sh.GetGsInstPrimsInSubgrp()); + printf("\t m_geMaxOutputPerSubgroup = 0x%08" PRIx32 "\n", sh.m_geMaxOutputPerSubgroup); + printf("\t m_vgtEsgsRingItemsize = 0x%08" PRIx32 "\n", sh.m_vgtEsgsRingItemsize); + printf("\t m_vgtGsMaxVertOut = 0x%08" PRIx32 "\n", sh.m_vgtGsMaxVertOut); + printf("\t m_vgtGsOutPrimType = 0x%08" PRIx32 "\n", sh.m_vgtGsOutPrimType); } -static void ps_print(const char* func, const HW::PsStageRegisters& ps) +static void ps_print(const char* func, const HW::PsStageRegisters& ps, const HW::ShaderRegisters& sh) { printf("%s\n", func); @@ -2112,26 +2123,28 @@ static void ps_print(const char* func, const HW::PsStageRegisters& ps) // printf("\t m_spiShaderPgmRsrc2Ps = 0x%08" PRIx32 "\n", ps.m_spiShaderPgmRsrc2Ps); // printf("\t GetTargetOutputMode(0) = 0x%08" PRIx32 "\n", ps.GetTargetOutputMode(0)); printf("\t data_addr = 0x%016" PRIx64 "\n", ps.data_addr); - printf("\t conservative_z_export_value = 0x%08" PRIx32 "\n", ps.conservative_z_export_value); - printf("\t shader_z_behavior = 0x%08" PRIx32 "\n", ps.shader_z_behavior); - printf("\t shader_kill_enable = %s\n", ps.shader_kill_enable ? "true" : "false"); - printf("\t shader_z_export_enable = %s\n", ps.shader_z_export_enable ? "true" : "false"); - printf("\t shader_execute_on_noop = %s\n", ps.shader_execute_on_noop ? "true" : "false"); + printf("\t conservative_z_export_value = 0x%08" PRIx32 "\n", sh.db_shader_control.conservative_z_export_value); + printf("\t shader_z_behavior = 0x%08" PRIx32 "\n", sh.db_shader_control.shader_z_behavior); + printf("\t shader_kill_enable = %s\n", sh.db_shader_control.shader_kill_enable ? "true" : "false"); + printf("\t shader_z_export_enable = %s\n", sh.db_shader_control.shader_z_export_enable ? "true" : "false"); + printf("\t shader_execute_on_noop = %s\n", sh.db_shader_control.shader_execute_on_noop ? "true" : "false"); printf("\t vgprs = 0x%02" PRIx8 "\n", ps.vgprs); printf("\t sgprs = 0x%02" PRIx8 "\n", ps.sgprs); printf("\t scratch_en = 0x%02" PRIx8 "\n", ps.scratch_en); printf("\t user_sgpr = 0x%02" PRIx8 "\n", ps.user_sgpr); printf("\t wave_cnt_en = 0x%02" PRIx8 "\n", ps.wave_cnt_en); - printf("\t shader_z_format = 0x%08" PRIx32 "\n", ps.shader_z_format); - printf("\t target_output_mode[0] = 0x%02" PRIx8 "\n", ps.target_output_mode[0]); - printf("\t ps_input_ena = 0x%08" PRIx32 "\n", ps.ps_input_ena); - printf("\t ps_input_addr = 0x%08" PRIx32 "\n", ps.ps_input_addr); - printf("\t ps_in_control = 0x%08" PRIx32 "\n", ps.ps_in_control); - printf("\t baryc_cntl = 0x%08" PRIx32 "\n", ps.baryc_cntl); - printf("\t m_cbShaderMask = 0x%08" PRIx32 "\n", ps.m_cbShaderMask); + printf("\t shader_z_format = 0x%08" PRIx32 "\n", sh.shader_z_format); + printf("\t target_output_mode[0] = 0x%02" PRIx8 "\n", sh.target_output_mode[0]); + printf("\t ps_input_ena = 0x%08" PRIx32 "\n", sh.ps_input_ena); + printf("\t ps_input_addr = 0x%08" PRIx32 "\n", sh.ps_input_addr); + printf("\t ps_in_control = 0x%08" PRIx32 "\n", sh.ps_in_control); + printf("\t baryc_cntl = 0x%08" PRIx32 "\n", sh.baryc_cntl); + printf("\t m_cbShaderMask = 0x%08" PRIx32 "\n", sh.m_cbShaderMask); + + printf("\t m_paScShaderControl = 0x%08" PRIx32 "\n", sh.m_paScShaderControl); } -static void cs_print(const char* func, const HW::CsStageRegisters& cs) +static void cs_print(const char* func, const HW::CsStageRegisters& cs, const HW::ShaderRegisters& /*sh*/) { printf("%s\n", func); @@ -2183,7 +2196,7 @@ static void bi_print(const char* func, const ShaderBinaryInfo& bi) printf("\t crc32 = 0x%08" PRIx32 "\n", bi.crc32); } -static void vs_check(const HW::VsStageRegisters& vs) +static void vs_check(const HW::VsStageRegisters& vs, const HW::ShaderRegisters& sh) { EXIT_NOT_IMPLEMENTED(vs.GetStreamoutEnabled() != false); // EXIT_NOT_IMPLEMENTED(vs.GetSgprCount() != 0x00000000); @@ -2191,17 +2204,28 @@ static void vs_check(const HW::VsStageRegisters& vs) // EXIT_NOT_IMPLEMENTED(vs.GetUnknown1() != 0x002c0000); // EXIT_NOT_IMPLEMENTED(vs.GetUnknown2() != 0x00000000); // EXIT_NOT_IMPLEMENTED(vs.m_spiVsOutConfig != 0x00000000); - EXIT_NOT_IMPLEMENTED(vs.m_spiShaderPosFormat != 0x00000004); - EXIT_NOT_IMPLEMENTED(vs.m_paClVsOutCntl != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_spiShaderPosFormat != 0x00000004); + EXIT_NOT_IMPLEMENTED(sh.m_paClVsOutCntl != 0x00000000); + + EXIT_NOT_IMPLEMENTED(sh.m_spiShaderIdxFormat != 0x00000000 && sh.m_spiShaderIdxFormat != 0x00000001); + EXIT_NOT_IMPLEMENTED(sh.m_geNggSubgrpCntl != 0x00000000 && sh.m_geNggSubgrpCntl != 0x00000001); + EXIT_NOT_IMPLEMENTED(sh.m_vgtGsInstanceCnt != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.GetEsVertsPerSubgrp() != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.GetGsPrimsPerSubgrp() != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.GetGsInstPrimsInSubgrp() != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_geMaxOutputPerSubgroup != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_vgtEsgsRingItemsize != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_vgtGsMaxVertOut != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_vgtGsOutPrimType != 0x00000000); } -static void ps_check(const HW::PsStageRegisters& ps) +static void ps_check(const HW::PsStageRegisters& ps, const HW::ShaderRegisters& sh) { - EXIT_NOT_IMPLEMENTED(ps.target_output_mode[0] != 4 && ps.target_output_mode[0] != 9); - EXIT_NOT_IMPLEMENTED(ps.conservative_z_export_value != 0x00000000); - EXIT_NOT_IMPLEMENTED(ps.shader_z_behavior != 0x00000001 && ps.shader_z_behavior != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.target_output_mode[0] != 4 && sh.target_output_mode[0] != 9); + EXIT_NOT_IMPLEMENTED(sh.db_shader_control.conservative_z_export_value != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.db_shader_control.shader_z_behavior != 0x00000001 && sh.db_shader_control.shader_z_behavior != 0x00000000); // EXIT_NOT_IMPLEMENTED(ps.shader_kill_enable != false); - EXIT_NOT_IMPLEMENTED(ps.shader_z_export_enable != false); + EXIT_NOT_IMPLEMENTED(sh.db_shader_control.shader_z_export_enable != false); // EXIT_NOT_IMPLEMENTED(ps.shader_execute_on_noop != false); // EXIT_NOT_IMPLEMENTED(ps.m_spiShaderPgmRsrc1Ps != 0x002c0000); // EXIT_NOT_IMPLEMENTED(ps.m_spiShaderPgmRsrc2Ps != 0x00000000); @@ -2210,15 +2234,18 @@ static void ps_check(const HW::PsStageRegisters& ps) EXIT_NOT_IMPLEMENTED(ps.scratch_en != 0); // EXIT_NOT_IMPLEMENTED(ps.user_sgpr != 0 && ps.user_sgpr != 4 && ps.user_sgpr != 12); EXIT_NOT_IMPLEMENTED(ps.wave_cnt_en != 0); - EXIT_NOT_IMPLEMENTED(ps.shader_z_format != 0x00000000); - EXIT_NOT_IMPLEMENTED(ps.ps_input_ena != 0x00000002 && ps.ps_input_ena != 0x00000302); - EXIT_NOT_IMPLEMENTED(ps.ps_input_addr != 0x00000002 && ps.ps_input_addr != 0x00000302); + EXIT_NOT_IMPLEMENTED(sh.shader_z_format != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.ps_input_ena != 0x00000002 && sh.ps_input_ena != 0x00000302); + EXIT_NOT_IMPLEMENTED(sh.ps_input_addr != 0x00000002 && sh.ps_input_addr != 0x00000302); // EXIT_NOT_IMPLEMENTED(ps.m_spiPsInControl != 0x00000000); - EXIT_NOT_IMPLEMENTED(ps.baryc_cntl != 0x00000000); - EXIT_NOT_IMPLEMENTED(ps.m_cbShaderMask != 0x0000000f); + EXIT_NOT_IMPLEMENTED(sh.baryc_cntl != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_cbShaderMask != 0x0000000f); + + EXIT_NOT_IMPLEMENTED(sh.db_shader_control.other_bits != 0x00000000); + EXIT_NOT_IMPLEMENTED(sh.m_paScShaderControl != 0x00000000); } -static void cs_check(const HW::CsStageRegisters& cs) +static void cs_check(const HW::CsStageRegisters& cs, const HW::ShaderRegisters& /*sh*/) { // EXIT_NOT_IMPLEMENTED(cs.num_thread_x != 0x00000040); // EXIT_NOT_IMPLEMENTED(cs.num_thread_y != 0x00000001); @@ -2713,13 +2740,13 @@ void ShaderCalcBindingIndices(ShaderBindResources* bind) EXIT_IF((bind->push_constant_size % 16) != 0); } -void ShaderGetInputInfoVS(const HW::VertexShaderInfo* regs, ShaderVertexInputInfo* info) +void ShaderGetInputInfoVS(const HW::VertexShaderInfo* regs, const HW::ShaderRegisters* sh, ShaderVertexInputInfo* info) { KYTY_PROFILER_FUNCTION(); EXIT_IF(info == nullptr || regs == nullptr); - info->export_count = static_cast(1 + ((regs->vs_regs.m_spiVsOutConfig >> 1u) & 0x1Fu)); + info->export_count = static_cast(sh->GetExportCount()); info->bind.push_constant_offset = 0; info->bind.push_constant_size = 0; info->bind.descriptor_set_slot = 0; @@ -2800,28 +2827,30 @@ void ShaderGetInputInfoVS(const HW::VertexShaderInfo* regs, ShaderVertexInputInf } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const ShaderVertexInputInfo* vs_info, ShaderPixelInputInfo* ps_info) +void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const HW::ShaderRegisters* sh, const ShaderVertexInputInfo* vs_info, + ShaderPixelInputInfo* ps_info) { KYTY_PROFILER_FUNCTION(); EXIT_IF(vs_info == nullptr); EXIT_IF(ps_info == nullptr); EXIT_IF(regs == nullptr); + EXIT_IF(sh == nullptr); if (regs->ps_embedded) { return; } - ps_info->input_num = regs->ps_regs.ps_in_control; - ps_info->ps_pos_xy = (regs->ps_regs.ps_input_ena == 0x00000302 && regs->ps_regs.ps_input_addr == 0x00000302); - ps_info->ps_pixel_kill_enable = regs->ps_regs.shader_kill_enable; - ps_info->ps_early_z = (regs->ps_regs.shader_z_behavior == 1); - ps_info->ps_execute_on_noop = regs->ps_regs.shader_execute_on_noop; + ps_info->input_num = sh->ps_in_control; + ps_info->ps_pos_xy = (sh->ps_input_ena == 0x00000302 && sh->ps_input_addr == 0x00000302); + ps_info->ps_pixel_kill_enable = sh->db_shader_control.shader_kill_enable; + ps_info->ps_early_z = (sh->db_shader_control.shader_z_behavior == 1); + ps_info->ps_execute_on_noop = sh->db_shader_control.shader_execute_on_noop; for (uint32_t i = 0; i < ps_info->input_num; i++) { - ps_info->interpolator_settings[i] = regs->ps_interpolator_settings[i]; + ps_info->interpolator_settings[i] = sh->ps_interpolator_settings[i]; } ps_info->bind.descriptor_set_slot = (vs_info->bind.storage_buffers.buffers_num > 0 ? 1 : 0); @@ -2830,7 +2859,7 @@ void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const ShaderVertexInp for (int i = 0; i < 8; i++) { - ps_info->target_output_mode[i] = regs->ps_regs.target_output_mode[i]; + ps_info->target_output_mode[i] = sh->target_output_mode[i]; } const auto* src = reinterpret_cast(regs->ps_regs.data_addr); @@ -2894,7 +2923,7 @@ void ShaderGetInputInfoPS(const HW::PixelShaderInfo* regs, const ShaderVertexInp } // NOLINTNEXTLINE(readability-function-cognitive-complexity) -void ShaderGetInputInfoCS(const HW::ComputeShaderInfo* regs, ShaderComputeInputInfo* info) +void ShaderGetInputInfoCS(const HW::ComputeShaderInfo* regs, const HW::ShaderRegisters* /*sh*/, ShaderComputeInputInfo* info) { EXIT_IF(info == nullptr); EXIT_IF(regs == nullptr); @@ -3355,10 +3384,13 @@ private: String m_file_name; }; -ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs) +ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs, const HW::ShaderRegisters* sh) { KYTY_PROFILER_FUNCTION(profiler::colors::Amber300); + EXIT_IF(regs == nullptr); + EXIT_IF(sh == nullptr); + ShaderCode code; code.SetType(ShaderType::Vertex); @@ -3372,8 +3404,8 @@ ShaderCode ShaderParseVS(const HW::VertexShaderInfo* regs) EXIT_NOT_IMPLEMENTED(src == nullptr); - vs_print("ShaderParseVS()", regs->vs_regs); - vs_check(regs->vs_regs); + vs_print("ShaderParseVS()", regs->vs_regs, *sh); + vs_check(regs->vs_regs, *sh); const auto* header = GetBinaryInfo(src); @@ -3434,10 +3466,13 @@ Vector ShaderRecompileVS(const ShaderCode& code, const ShaderVertexInp return ret; } -ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs) +ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs, const HW::ShaderRegisters* sh) { KYTY_PROFILER_FUNCTION(profiler::colors::Blue300); + EXIT_IF(regs == nullptr); + EXIT_IF(sh == nullptr); + ShaderCode code; code.SetType(ShaderType::Pixel); @@ -3451,8 +3486,8 @@ ShaderCode ShaderParsePS(const HW::PixelShaderInfo* regs) EXIT_NOT_IMPLEMENTED(src == nullptr); - ps_print("ShaderParsePS()", regs->ps_regs); - ps_check(regs->ps_regs); + ps_print("ShaderParsePS()", regs->ps_regs, *sh); + ps_check(regs->ps_regs, *sh); EXIT_NOT_IMPLEMENTED(regs->ps_regs.user_sgpr > regs->ps_user_sgpr.count); @@ -3520,16 +3555,19 @@ Vector ShaderRecompilePS(const ShaderCode& code, const ShaderPixelInpu return ret; } -ShaderCode ShaderParseCS(const HW::ComputeShaderInfo* regs) +ShaderCode ShaderParseCS(const HW::ComputeShaderInfo* regs, const HW::ShaderRegisters* sh) { KYTY_PROFILER_FUNCTION(profiler::colors::CyanA700); + EXIT_IF(regs == nullptr); + EXIT_IF(sh == nullptr); + const auto* src = reinterpret_cast(regs->cs_regs.data_addr); EXIT_NOT_IMPLEMENTED(src == nullptr); - cs_print("ShaderParseCS()", regs->cs_regs); - cs_check(regs->cs_regs); + cs_print("ShaderParseCS()", regs->cs_regs, *sh); + cs_check(regs->cs_regs, *sh); EXIT_NOT_IMPLEMENTED(regs->cs_regs.user_sgpr > regs->cs_user_sgpr.count); diff --git a/source/emulator/src/Libs/LibGraphicsDriver.cpp b/source/emulator/src/Libs/LibGraphicsDriver.cpp index 61d8d0f..27961e4 100644 --- a/source/emulator/src/Libs/LibGraphicsDriver.cpp +++ b/source/emulator/src/Libs/LibGraphicsDriver.cpp @@ -70,13 +70,6 @@ LIB_DEFINE(InitGraphicsDriver_1) LIB_FUNC("2JtWUUiYBXs", Gen5::GraphicsGetRegisterDefaults2); LIB_FUNC("wRbq6ZjNop4", Gen5::GraphicsGetRegisterDefaults2Internal); LIB_FUNC("f3dg2CSgRKY", Gen5::GraphicsCreateShader); - LIB_FUNC("TRO721eVt4g", Gen5::GraphicsDcbResetQueue); - LIB_FUNC("MWiElSNE8j8", Gen5::GraphicsDcbWaitUntilSafeForRendering); - LIB_FUNC("ZvwO9euwYzc", Gen5::GraphicsDcbSetCxRegistersIndirect); - LIB_FUNC("-HOOCn0JY48", Gen5::GraphicsDcbSetShRegistersIndirect); - LIB_FUNC("hvUfkUIQcOE", Gen5::GraphicsDcbSetUcRegistersIndirect); - LIB_FUNC("GIIW2J37e70", Gen5::GraphicsDcbSetIndexSize); - LIB_FUNC("Yw0jKSqop+E", Gen5::GraphicsDcbDrawIndexAuto); LIB_FUNC("vcmNN+AAXnY", Gen5::GraphicsSetCxRegIndirectPatchSetAddress); LIB_FUNC("Qrj4c+61z4A", Gen5::GraphicsSetShRegIndirectPatchSetAddress); LIB_FUNC("6lNcCp+fxi4", Gen5::GraphicsSetUcRegIndirectPatchSetAddress); @@ -85,16 +78,47 @@ LIB_DEFINE(InitGraphicsDriver_1) LIB_FUNC("vRoArM9zaIk", Gen5::GraphicsSetUcRegIndirectPatchAddRegisters); LIB_FUNC("D9sr1xGUriE", Gen5::GraphicsCreatePrimState); LIB_FUNC("HV4j+E0MBHE", Gen5::GraphicsCreateInterpolantMapping); - LIB_FUNC("n2fD4A+pb+g", Gen5::GraphicsCbSetShRegisterRangeDirect); LIB_FUNC("V++UgBtQhn0", Gen5::GraphicsGetDataPacketPayloadAddress); + LIB_FUNC("h9z6+0hEydk", Gen5::GraphicsSuspendPoint); + + LIB_FUNC("n2fD4A+pb+g", Gen5::GraphicsCbSetShRegisterRangeDirect); + LIB_FUNC("wr23dPKyWc0", Gen5::GraphicsCbReleaseMem); + LIB_FUNC("TRO721eVt4g", Gen5::GraphicsDcbResetQueue); + LIB_FUNC("MWiElSNE8j8", Gen5::GraphicsDcbWaitUntilSafeForRendering); + LIB_FUNC("ZvwO9euwYzc", Gen5::GraphicsDcbSetCxRegistersIndirect); + LIB_FUNC("-HOOCn0JY48", Gen5::GraphicsDcbSetShRegistersIndirect); + LIB_FUNC("hvUfkUIQcOE", Gen5::GraphicsDcbSetUcRegistersIndirect); + LIB_FUNC("GIIW2J37e70", Gen5::GraphicsDcbSetIndexSize); + LIB_FUNC("Yw0jKSqop+E", Gen5::GraphicsDcbDrawIndexAuto); + LIB_FUNC("aJf+j5yntiU", Gen5::GraphicsDcbEventWrite); + LIB_FUNC("57labkp+rSQ", Gen5::GraphicsDcbAcquireMem); + LIB_FUNC("i1jyy49AjXU", Gen5::GraphicsDcbWriteData); + LIB_FUNC("VmW0Tdpy420", Gen5::GraphicsDcbWaitRegMem); + LIB_FUNC("YUeqkyT7mEQ", Gen5::GraphicsDcbSetFlip); } } // namespace LibGen5 +namespace LibGen5Driver { + +LIB_VERSION("Graphics5Driver", 1, "Graphics5Driver", 1, 1); + +namespace Gen5Driver = Graphics::Gen5Driver; + +LIB_DEFINE(InitGraphicsDriver_1) +{ + PRINT_NAME_ENABLE(true); + + LIB_FUNC("UglJIZjGssM", Gen5Driver::GraphicsDriverSubmitDcb); +} + +} // namespace LibGen5Driver + LIB_DEFINE(InitGraphicsDriver_1) { LibGen4::InitGraphicsDriver_1(s); LibGen5::InitGraphicsDriver_1(s); + LibGen5Driver::InitGraphicsDriver_1(s); } } // namespace Kyty::Libs