mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
PS5 graphics (#42)
This commit is contained in:
@@ -13,6 +13,7 @@ struct Config
|
||||
uint32_t screen_width = 1280;
|
||||
uint32_t screen_height = 720;
|
||||
bool neo = true;
|
||||
bool next_gen = false;
|
||||
bool vulkan_validation_enabled = false;
|
||||
bool shader_validation_enabled = false;
|
||||
ShaderOptimizationType shader_optimization_type = ShaderOptimizationType::None;
|
||||
@@ -115,7 +116,7 @@ uint32_t GetScreenHeight()
|
||||
|
||||
bool IsNeo()
|
||||
{
|
||||
return g_config->neo;
|
||||
return g_config->neo || g_config->next_gen;
|
||||
}
|
||||
|
||||
bool VulkanValidationEnabled()
|
||||
@@ -193,6 +194,16 @@ String GetPipelineDumpFolder()
|
||||
return g_config->pipeline_dump_folder;
|
||||
}
|
||||
|
||||
void SetNextGen(bool mode)
|
||||
{
|
||||
g_config->next_gen = mode;
|
||||
}
|
||||
|
||||
bool IsNextGen()
|
||||
{
|
||||
return g_config->next_gen;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Config
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Emulator/Graphics/Objects/IndexBuffer.h"
|
||||
#include "Emulator/Graphics/Objects/Label.h"
|
||||
#include "Emulator/Graphics/Pm4.h"
|
||||
#include "Emulator/Graphics/Shader.h"
|
||||
#include "Emulator/Graphics/Tile.h"
|
||||
#include "Emulator/Graphics/VideoOut.h"
|
||||
#include "Emulator/Graphics/Window.h"
|
||||
@@ -40,6 +41,7 @@ KYTY_SUBSYSTEM_INIT(Graphics)
|
||||
LabelInit();
|
||||
TileInit();
|
||||
IndexBufferInit();
|
||||
ShaderInit();
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Graphics) {}
|
||||
@@ -755,12 +757,6 @@ namespace Gen5 {
|
||||
|
||||
LIB_NAME("Graphics5", "Graphics5");
|
||||
|
||||
struct ShaderRegister
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
struct RegisterDefaultInfo
|
||||
{
|
||||
uint32_t type;
|
||||
@@ -778,93 +774,6 @@ struct RegisterDefaults
|
||||
uint32_t count = 0;
|
||||
};
|
||||
|
||||
struct ShaderSharp
|
||||
{
|
||||
uint16_t offset_dw : 15;
|
||||
uint16_t size : 1;
|
||||
};
|
||||
|
||||
struct ShaderUserData
|
||||
{
|
||||
uint16_t* direct_resource_offset;
|
||||
ShaderSharp* sharp_resource_offset[4];
|
||||
uint16_t eud_size_dw;
|
||||
uint16_t srt_size_dw;
|
||||
uint16_t direct_resource_count;
|
||||
uint16_t sharp_resource_count[4];
|
||||
};
|
||||
|
||||
struct ShaderRegisterRange
|
||||
{
|
||||
uint16_t start;
|
||||
uint16_t end;
|
||||
};
|
||||
|
||||
struct ShaderDrawModifier
|
||||
{
|
||||
uint32_t enbl_start_vertex_offset : 1;
|
||||
uint32_t enbl_start_index_offset : 1;
|
||||
uint32_t enbl_start_instance_offset : 1;
|
||||
uint32_t enbl_draw_index : 1;
|
||||
uint32_t enbl_user_vgprs : 1;
|
||||
uint32_t render_target_slice_offset : 3;
|
||||
uint32_t fuse_draws : 1;
|
||||
uint32_t compiler_flags : 23;
|
||||
uint32_t is_default : 1;
|
||||
uint32_t reserved : 31;
|
||||
};
|
||||
|
||||
struct ShaderSpecialRegs
|
||||
{
|
||||
ShaderRegister ge_cntl;
|
||||
ShaderRegister vgt_shader_stages_en;
|
||||
uint32_t dispatch_modifier;
|
||||
ShaderRegisterRange user_data_range;
|
||||
ShaderDrawModifier draw_modifier;
|
||||
ShaderRegister vgt_gs_out_prim_type;
|
||||
ShaderRegister ge_user_vgpr_en;
|
||||
};
|
||||
|
||||
struct ShaderSemantic
|
||||
{
|
||||
uint32_t semantic : 8;
|
||||
uint32_t hardware_mapping : 8;
|
||||
uint32_t size_in_elements : 4;
|
||||
uint32_t is_f16 : 2;
|
||||
uint32_t is_flat_shaded : 1;
|
||||
uint32_t is_linear : 1;
|
||||
uint32_t is_custom : 1;
|
||||
uint32_t static_vb_index : 1;
|
||||
uint32_t static_attribute : 1;
|
||||
uint32_t reserved : 1;
|
||||
uint32_t default_value : 2;
|
||||
uint32_t default_value_hi : 2;
|
||||
};
|
||||
|
||||
struct Shader
|
||||
{
|
||||
uint32_t file_header;
|
||||
uint32_t version;
|
||||
ShaderUserData* user_data;
|
||||
const volatile void* code;
|
||||
ShaderRegister* cx_registers;
|
||||
ShaderRegister* sh_registers;
|
||||
ShaderSpecialRegs* specials;
|
||||
ShaderSemantic* input_semantics;
|
||||
ShaderSemantic* output_semantics;
|
||||
uint32_t header_size;
|
||||
uint32_t shader_size;
|
||||
uint32_t embedded_constant_buffer_size_dqw;
|
||||
uint32_t target;
|
||||
uint32_t num_input_semantics;
|
||||
uint16_t scratch_size_dw_per_thread;
|
||||
uint16_t num_output_semantics;
|
||||
uint16_t special_sizes_bytes;
|
||||
uint8_t type;
|
||||
uint8_t num_cx_registers;
|
||||
uint8_t num_sh_registers;
|
||||
};
|
||||
|
||||
struct CommandBuffer
|
||||
{
|
||||
using Callback = KYTY_SYSV_ABI bool (*)(CommandBuffer*, uint32_t, void*);
|
||||
@@ -1561,6 +1470,17 @@ int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatil
|
||||
|
||||
auto base = reinterpret_cast<uint64_t>(code);
|
||||
|
||||
printf("\t base = 0x%016" PRIx64 "\n", base);
|
||||
|
||||
ShaderMappedData map;
|
||||
map.user_data = h->user_data;
|
||||
map.input_semantics = h->input_semantics;
|
||||
map.num_input_semantics = h->num_input_semantics;
|
||||
|
||||
ShaderMapUserData(base, map);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((base & 0xFFFF0000000000FFull) != 0);
|
||||
|
||||
if (h->type == 2 && h->num_sh_registers >= 2 && h->sh_registers[0].offset == Pm4::SPI_SHADER_PGM_LO_ES &&
|
||||
h->sh_registers[1].offset == Pm4::SPI_SHADER_PGM_HI_ES)
|
||||
{
|
||||
@@ -1716,6 +1636,7 @@ int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegiste
|
||||
return OK;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs, const Shader* ps)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -1733,20 +1654,42 @@ int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const S
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(sizeof(ShaderSemantic) != 4);
|
||||
EXIT_NOT_IMPLEMENTED(ps != nullptr && gs->num_output_semantics != ps->num_input_semantics);
|
||||
EXIT_NOT_IMPLEMENTED(ps != nullptr && ps->num_output_semantics != 0);
|
||||
|
||||
auto* out32 = reinterpret_cast<uint32_t*>(gs->output_semantics);
|
||||
auto* in32 = (ps != nullptr ? reinterpret_cast<uint32_t*>(ps->input_semantics) : nullptr);
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
for (uint16_t i = 0; i < 32; i++)
|
||||
{
|
||||
regs[i].offset = Pm4::SPI_PS_INPUT_CNTL_0 + i;
|
||||
regs[i].value = 0;
|
||||
|
||||
if (i < static_cast<int>(gs->num_output_semantics))
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(out32[i] != 0x0000000f);
|
||||
EXIT_NOT_IMPLEMENTED(in32 != nullptr && out32[i] != in32[i]);
|
||||
regs[i].value = i;
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].semantic != 15 + i);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].hardware_mapping != i);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].size_in_elements != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].is_f16 != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].is_flat_shaded != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].is_linear != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].is_custom != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].static_vb_index != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].static_attribute != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].default_value != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gs->output_semantics[i].default_value_hi != 0);
|
||||
bool flat = false;
|
||||
if (ps != nullptr)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].semantic != gs->output_semantics[i].semantic);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].hardware_mapping != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].size_in_elements != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].is_f16 != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].is_linear != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].is_custom != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].static_vb_index != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].static_attribute != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].default_value != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ps->input_semantics[i].default_value_hi != 0);
|
||||
flat = ps->input_semantics[i].is_flat_shaded != 0;
|
||||
}
|
||||
regs[i].value = i | (flat ? 0x400u : 0u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1837,7 +1780,7 @@ uint32_t* KYTY_SYSV_ABI GraphicsCbReleaseMem(CommandBuffer* buf, uint8_t action,
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(buf == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(dst != 1);
|
||||
EXIT_NOT_IMPLEMENTED(data_sel != 2);
|
||||
EXIT_NOT_IMPLEMENTED(data_sel != 2 && data_sel != 3);
|
||||
EXIT_NOT_IMPLEMENTED(gds_offset != 0);
|
||||
EXIT_NOT_IMPLEMENTED(gds_size != 1);
|
||||
EXIT_NOT_IMPLEMENTED(interrupt != 0);
|
||||
@@ -1851,7 +1794,7 @@ uint32_t* KYTY_SYSV_ABI GraphicsCbReleaseMem(CommandBuffer* buf, uint8_t action,
|
||||
|
||||
cmd[0] = KYTY_PM4(7, Pm4::IT_NOP, Pm4::R_RELEASE_MEM);
|
||||
cmd[1] = action | (static_cast<uint32_t>(cache_policy) << 8u);
|
||||
cmd[2] = gcr_cntl;
|
||||
cmd[2] = gcr_cntl | (static_cast<uint32_t>(data_sel) << 16u);
|
||||
cmd[3] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(address) & 0xffffffffu);
|
||||
cmd[4] = static_cast<uint32_t>((reinterpret_cast<uint64_t>(address) >> 32u) & 0xffffffffu);
|
||||
cmd[5] = static_cast<uint32_t>(data & 0xffffffffu);
|
||||
@@ -1909,6 +1852,25 @@ uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(buf == nullptr);
|
||||
|
||||
buf->DbgDump();
|
||||
|
||||
auto* cmd = buf->AllocateDW(3);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
|
||||
|
||||
cmd[0] = KYTY_PM4(3, Pm4::IT_SET_SH_REG, 0u);
|
||||
cmd[1] = reg.offset;
|
||||
cmd[2] = reg.value;
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
@@ -471,6 +471,7 @@ static void uc_print(const char* func, const HW::UserConfig& uc)
|
||||
|
||||
printf("\t GetPrimType() = 0x%08" PRIx32 "\n", uc.GetPrimType());
|
||||
printf("\t primitive_group_size = 0x%04" PRIx16 "\n", ge_cntl.primitive_group_size);
|
||||
printf("\t vertex_group_size = 0x%04" PRIx16 "\n", ge_cntl.vertex_group_size);
|
||||
printf("\t en_user_vgpr1 = %s\n", user_en.vgpr1 ? "true" : "false");
|
||||
printf("\t en_user_vgpr2 = %s\n", user_en.vgpr2 ? "true" : "false");
|
||||
printf("\t en_user_vgpr3 = %s\n", user_en.vgpr3 ? "true" : "false");
|
||||
@@ -481,8 +482,8 @@ static void uc_check(const HW::UserConfig& uc)
|
||||
const auto& ge_cntl = uc.GetGeControl();
|
||||
const auto& user_en = uc.GetGeUserVgprEn();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(ge_cntl.primitive_group_size != 0x0000);
|
||||
EXIT_NOT_IMPLEMENTED(ge_cntl.vertex_group_size != 0x0000);
|
||||
EXIT_NOT_IMPLEMENTED(ge_cntl.primitive_group_size != 0x0000 && ge_cntl.primitive_group_size != 0x0040);
|
||||
EXIT_NOT_IMPLEMENTED(ge_cntl.vertex_group_size != 0x0000 && ge_cntl.vertex_group_size != 0x0040);
|
||||
EXIT_NOT_IMPLEMENTED(user_en.vgpr1 != false);
|
||||
EXIT_NOT_IMPLEMENTED(user_en.vgpr2 != false);
|
||||
EXIT_NOT_IMPLEMENTED(user_en.vgpr3 != false);
|
||||
@@ -565,11 +566,15 @@ static void rt_check(const HW::RenderTarget& rt)
|
||||
{
|
||||
if (rt.base.addr != 0)
|
||||
{
|
||||
bool render_to_texture = (rt.attrib.tile_mode == 0x0d);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.base_addr == 0);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.pitch_div8_minus1 != 0x000000ef);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.fmask_pitch_div8_minus1 != 0x000000ef);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.slice_div64_minus1 != 0x000086ff);
|
||||
bool ps5 = Config::IsNextGen();
|
||||
// bool render_to_texture = (rt.attrib.tile_mode == 0x0d);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.base_addr == 0);
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(rt.pitch.pitch_div8_minus1 != 0);
|
||||
EXIT_NOT_IMPLEMENTED(rt.pitch.fmask_pitch_div8_minus1 != 0);
|
||||
EXIT_NOT_IMPLEMENTED(rt.slice.slice_div64_minus1 != 0);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(rt.view.base_array_slice_index != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.view.last_array_slice_index != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.view.current_mip_level != 0x00000000);
|
||||
@@ -581,7 +586,7 @@ static void rt_check(const HW::RenderTarget& rt)
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.cmask_fast_clear_enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.dcc_compression_enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(!render_to_texture && rt.info.neo_mode != Config::IsNeo());
|
||||
EXIT_NOT_IMPLEMENTED(!(rt.attrib.tile_mode == 0x0d) && rt.info.neo_mode != Config::IsNeo());
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.cmask_tile_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.cmask_tile_mode_neo != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.info.blend_bypass != false);
|
||||
@@ -595,14 +600,27 @@ static void rt_check(const HW::RenderTarget& rt)
|
||||
// EXIT_NOT_IMPLEMENTED(rt.fmask_tile_mode != 0x0000000a);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib.num_samples != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib.num_fragments != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.num_mip_levels != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.depth != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.tile_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dimension != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.cmask_pipe_aligned != false);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dcc_pipe_aligned != false);
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.width == 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.height == 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.num_mip_levels != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.depth != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.tile_mode != 0x0000001b);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dimension != 0x00000001);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.cmask_pipe_aligned != true);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dcc_pipe_aligned != true);
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib2.num_mip_levels != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.depth != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.tile_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dimension != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.cmask_pipe_aligned != false);
|
||||
EXIT_NOT_IMPLEMENTED(rt.attrib3.dcc_pipe_aligned != false);
|
||||
}
|
||||
// EXIT_NOT_IMPLEMENTED(rt.dcc_max_uncompressed_block_size != 0x00000002);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.dcc.max_compressed_block_size != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.dcc.min_compressed_block_size != 0x00000000);
|
||||
@@ -619,8 +637,11 @@ static void rt_check(const HW::RenderTarget& rt)
|
||||
EXIT_NOT_IMPLEMENTED(rt.clear_word0.word0 != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.clear_word1.word1 != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.dcc_addr.addr != 0x0000000000000000);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.width != 0x00000780);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.height != 0x00000438);
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(rt.size.width != 0);
|
||||
EXIT_NOT_IMPLEMENTED(rt.size.height != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,25 +750,46 @@ static void z_check(const HW::DepthRenderTarget& z)
|
||||
|
||||
if (z.z_info.format != 0 || z.stencil_info.format != 0)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.addr5_swizzle_mask != 0x00000001);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.array_mode != 0x00000004);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.pipe_config != (Config::IsNeo() ? 0x00000012 : 0x0c));
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_width != 0x00000000);
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.bank_height != (Config::IsNeo() ? 0x00000001 : 2));
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.macro_tile_aspect != (Config::IsNeo() ? 0x00000000 : 2));
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.num_banks != (Config::IsNeo() ? 0x00000002 : 3));
|
||||
bool ps5 = Config::IsNextGen();
|
||||
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.addr5_swizzle_mask != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.array_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.pipe_config != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.macro_tile_aspect != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.num_banks != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.linear != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.full_cache != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.htile_uses_preload_win != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.preload != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.dst_outside_zero_to_one != 0x00000000);
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.addr5_swizzle_mask != 0x00000001);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.array_mode != 0x00000004);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.pipe_config != (Config::IsNeo() ? 0x00000012 : 0x0c));
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_info.bank_width != 0x00000000);
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.bank_height != (Config::IsNeo() ? 0x00000001 : 2));
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.macro_tile_aspect != (Config::IsNeo() ? 0x00000000 : 2));
|
||||
// EXIT_NOT_IMPLEMENTED(z.depth_info.num_banks != (Config::IsNeo() ? 0x00000002 : 3));
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.linear != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.full_cache != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.htile_uses_preload_win != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.preload != 0x00000001);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.dst_outside_zero_to_one != 0x00000000);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_view.slice_start != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_view.slice_max != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_view.current_mip_level != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_view.depth_write_disable != false);
|
||||
EXIT_NOT_IMPLEMENTED(z.depth_view.stencil_write_disable != false);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.linear != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.full_cache != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.htile_uses_preload_win != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.preload != 0x00000001);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_width != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.prefetch_height != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.htile_surface.dst_outside_zero_to_one != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(z.z_read_base_addr != z.z_write_base_addr);
|
||||
EXIT_NOT_IMPLEMENTED(z.stencil_read_base_addr != z.stencil_write_base_addr);
|
||||
EXIT_NOT_IMPLEMENTED(z.z_write_base_addr == 0);
|
||||
@@ -758,8 +800,13 @@ static void z_check(const HW::DepthRenderTarget& z)
|
||||
// EXIT_NOT_IMPLEMENTED(z.htile_data_base_addr == 0);
|
||||
// EXIT_NOT_IMPLEMENTED(z.width != 0x00000780);
|
||||
// EXIT_NOT_IMPLEMENTED(z.height != 0x00000438);
|
||||
EXIT_NOT_IMPLEMENTED(z.size.x_max != 0);
|
||||
EXIT_NOT_IMPLEMENTED(z.size.y_max != 0);
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(z.width != 0);
|
||||
EXIT_NOT_IMPLEMENTED(z.height != 0);
|
||||
EXIT_NOT_IMPLEMENTED(z.size.x_max == 0);
|
||||
EXIT_NOT_IMPLEMENTED(z.size.y_max == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,14 +1091,23 @@ static void vp_print(const char* func, const HW::ScreenViewport& vp, const HW::S
|
||||
|
||||
static void vp_check(const HW::ScreenViewport& vp, const HW::ScanModeControl& smc)
|
||||
{
|
||||
bool ps5 = Config::IsNextGen();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(smc.msaa_enable);
|
||||
// EXIT_NOT_IMPLEMENTED(smc.vport_scissor_enable);
|
||||
EXIT_NOT_IMPLEMENTED(smc.line_stipple_enable);
|
||||
|
||||
bool generic_scissor =
|
||||
(vp.generic_scissor_left != 0 || vp.generic_scissor_top != 0 || vp.generic_scissor_right != 0 || vp.generic_scissor_bottom != 0);
|
||||
bool screen_scissor =
|
||||
(vp.screen_scissor_left != 0 || vp.screen_scissor_top != 0 || vp.screen_scissor_right != 0 || vp.screen_scissor_bottom != 0);
|
||||
bool viewport_scissor = (vp.viewports[0].viewport_scissor_left != 0 || vp.viewports[0].viewport_scissor_top != 0 ||
|
||||
vp.viewports[0].viewport_scissor_right != 0 || vp.viewports[0].viewport_scissor_bottom != 0);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].zmin != 0.000000);
|
||||
EXIT_NOT_IMPLEMENTED(viewport_scissor && (generic_scissor || screen_scissor));
|
||||
EXIT_NOT_IMPLEMENTED(viewport_scissor && (!smc.vport_scissor_enable));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].zmin > 0.000000);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].zmax != 1.000000);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].xscale != 960.000000);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].xoffset != 960.000000);
|
||||
@@ -1068,14 +1124,21 @@ static void vp_check(const HW::ScreenViewport& vp, const HW::ScanModeControl& sm
|
||||
// EXIT_NOT_IMPLEMENTED(vp.hw_offset_y != 32);
|
||||
// EXIT_NOT_IMPLEMENTED(fabsf(vp.guard_band_horz_clip - 33.133327f) > 0.001f);
|
||||
// EXIT_NOT_IMPLEMENTED(fabsf(vp.guard_band_vert_clip - 59.629623f) > 0.001f);
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_horz_discard != 1.000000);
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_vert_discard != 1.000000);
|
||||
if (ps5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_horz_discard != 0.0f);
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_vert_discard != 0.0f);
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_horz_discard != 1.000000);
|
||||
EXIT_NOT_IMPLEMENTED(vp.guard_band_vert_discard != 1.000000);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(vp.generic_scissor_window_offset_enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_left != 0);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_top != 0);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_right != 0);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_bottom != 0);
|
||||
EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_window_offset_enable != false);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_left != 0);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_top != 0);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_right != 0);
|
||||
// EXIT_NOT_IMPLEMENTED(vp.viewports[0].viewport_scissor_bottom != 0);
|
||||
EXIT_NOT_IMPLEMENTED(viewport_scissor && vp.viewports[0].viewport_scissor_window_offset_enable != true);
|
||||
}
|
||||
|
||||
static void hw_check(const HW::Context& hw)
|
||||
@@ -1785,33 +1848,53 @@ uint64_t SamplerCache::GetSamplerId(const ShaderSamplerResource& r)
|
||||
return m_samplers_size;
|
||||
}
|
||||
|
||||
static void get_input_format(const ShaderBufferResource& res, VkFormat* format, uint32_t* size)
|
||||
static void get_input_format(const ShaderBufferResource& res, VkFormat* format, uint32_t* size, bool ps5)
|
||||
{
|
||||
EXIT_IF(format == nullptr);
|
||||
EXIT_IF(size == nullptr);
|
||||
auto nfmt = res.Nfmt();
|
||||
auto dfmt = res.Dfmt();
|
||||
if (nfmt == 7 && dfmt == 14)
|
||||
if (ps5)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
*size = 4;
|
||||
} else if (nfmt == 7 && dfmt == 13)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
*size = 3;
|
||||
} else if (nfmt == 7 && dfmt == 11)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32_SFLOAT;
|
||||
*size = 2;
|
||||
} else if (nfmt == 0 && dfmt == 10)
|
||||
{
|
||||
*format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
*size = 4;
|
||||
auto fmt = res.Format();
|
||||
if (fmt == 74)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
*size = 3;
|
||||
} else if (fmt == 64)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32_SFLOAT;
|
||||
*size = 2;
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format: fmt = %u\n", fmt);
|
||||
*format = VK_FORMAT_UNDEFINED;
|
||||
*size = 4;
|
||||
}
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
*format = VK_FORMAT_UNDEFINED;
|
||||
*size = 4;
|
||||
auto nfmt = res.Nfmt();
|
||||
auto dfmt = res.Dfmt();
|
||||
if (nfmt == 7 && dfmt == 14)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
*size = 4;
|
||||
} else if (nfmt == 7 && dfmt == 13)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
*size = 3;
|
||||
} else if (nfmt == 7 && dfmt == 11)
|
||||
{
|
||||
*format = VK_FORMAT_R32G32_SFLOAT;
|
||||
*size = 2;
|
||||
} else if (nfmt == 0 && dfmt == 10)
|
||||
{
|
||||
*format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
*size = 4;
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
*format = VK_FORMAT_UNDEFINED;
|
||||
*size = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1952,6 +2035,8 @@ static VulkanPipeline* CreatePipelineInternal(VkRenderPass render_pass, const Sh
|
||||
VkVertexInputAttributeDescription input_attr[ShaderVertexInputInfo::RES_MAX];
|
||||
VkVertexInputBindingDescription input_desc[ShaderVertexInputInfo::RES_MAX];
|
||||
|
||||
bool gen5 = Config::IsNextGen();
|
||||
|
||||
for (int bi = 0; bi < vs_input_info->buffers_num; bi++)
|
||||
{
|
||||
const auto& b = vs_input_info->buffers[bi];
|
||||
@@ -1967,10 +2052,14 @@ static VulkanPipeline* CreatePipelineInternal(VkRenderPass render_pass, const Sh
|
||||
input_attr[index].offset = b.attr_offsets[ai];
|
||||
|
||||
uint32_t attr_size = 4;
|
||||
get_input_format(vs_input_info->resources[index], &input_attr[index].format, &attr_size);
|
||||
get_input_format(vs_input_info->resources[index], &input_attr[index].format, &attr_size, gen5);
|
||||
|
||||
auto registers_num = vs_input_info->resources_dst[index].registers_num;
|
||||
|
||||
if (gen5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(vs_input_info->resources[index].OutOfBounds() != 0);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(vs_input_info->resources[index].AddTid());
|
||||
EXIT_NOT_IMPLEMENTED(vs_input_info->resources[index].SwizzleEnabled());
|
||||
|
||||
@@ -2484,17 +2573,23 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re
|
||||
|
||||
bool generic_scissor =
|
||||
(vp.generic_scissor_left != 0 || vp.generic_scissor_top != 0 || vp.generic_scissor_right != 0 || vp.generic_scissor_bottom != 0);
|
||||
bool viewport_scissor = (vp.viewports[0].viewport_scissor_left != 0 || vp.viewports[0].viewport_scissor_top != 0 ||
|
||||
vp.viewports[0].viewport_scissor_right != 0 || vp.viewports[0].viewport_scissor_bottom != 0);
|
||||
|
||||
p.static_params->viewport_scale[0] = vp.viewports[0].xscale;
|
||||
p.static_params->viewport_scale[1] = vp.viewports[0].yscale;
|
||||
p.static_params->viewport_scale[2] = vp.viewports[0].zscale;
|
||||
p.static_params->viewport_offset[0] = vp.viewports[0].xoffset;
|
||||
p.static_params->viewport_offset[1] = vp.viewports[0].yoffset;
|
||||
p.static_params->viewport_offset[2] = vp.viewports[0].zoffset;
|
||||
p.static_params->scissor_ltrb[0] = (generic_scissor ? vp.generic_scissor_left : vp.screen_scissor_left);
|
||||
p.static_params->scissor_ltrb[1] = (generic_scissor ? vp.generic_scissor_top : vp.screen_scissor_top);
|
||||
p.static_params->scissor_ltrb[2] = (generic_scissor ? vp.generic_scissor_right : vp.screen_scissor_right);
|
||||
p.static_params->scissor_ltrb[3] = (generic_scissor ? vp.generic_scissor_bottom : vp.screen_scissor_bottom);
|
||||
p.static_params->viewport_scale[0] = vp.viewports[0].xscale;
|
||||
p.static_params->viewport_scale[1] = vp.viewports[0].yscale;
|
||||
p.static_params->viewport_scale[2] = vp.viewports[0].zscale;
|
||||
p.static_params->viewport_offset[0] = vp.viewports[0].xoffset;
|
||||
p.static_params->viewport_offset[1] = vp.viewports[0].yoffset;
|
||||
p.static_params->viewport_offset[2] = vp.viewports[0].zoffset;
|
||||
p.static_params->scissor_ltrb[0] =
|
||||
(viewport_scissor ? vp.viewports[0].viewport_scissor_left : (generic_scissor ? vp.generic_scissor_left : vp.screen_scissor_left));
|
||||
p.static_params->scissor_ltrb[1] =
|
||||
(viewport_scissor ? vp.viewports[0].viewport_scissor_top : (generic_scissor ? vp.generic_scissor_top : vp.screen_scissor_top));
|
||||
p.static_params->scissor_ltrb[2] = (viewport_scissor ? vp.viewports[0].viewport_scissor_right
|
||||
: (generic_scissor ? vp.generic_scissor_right : vp.screen_scissor_right));
|
||||
p.static_params->scissor_ltrb[3] = (viewport_scissor ? vp.viewports[0].viewport_scissor_bottom
|
||||
: (generic_scissor ? vp.generic_scissor_bottom : vp.screen_scissor_bottom));
|
||||
p.static_params->topology = topology;
|
||||
p.static_params->with_depth = (depth->format != VK_FORMAT_UNDEFINED && depth->vulkan_buffer != nullptr);
|
||||
p.static_params->depth_test_enable = depth->depth_test_enable;
|
||||
@@ -3713,42 +3808,22 @@ static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, c
|
||||
|
||||
EXIT_IF(r == nullptr);
|
||||
|
||||
bool neo = Config::IsNeo();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& dc = hw.GetDepthControl();
|
||||
const auto& sc = hw.GetStencilControl();
|
||||
const auto& sm = hw.GetStencilMask();
|
||||
const auto& cc = hw.GetColorControl();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& dc = hw.GetDepthControl();
|
||||
const auto& sc = hw.GetStencilControl();
|
||||
const auto& sm = hw.GetStencilMask();
|
||||
const auto& cc = hw.GetColorControl();
|
||||
|
||||
uint32_t size = 0;
|
||||
uint32_t pitch = (z.pitch_div8_minus1 + 1) * 8;
|
||||
TileSizeAlign stencil_size {};
|
||||
TileSizeAlign htile_size {};
|
||||
TileSizeAlign depth_size {};
|
||||
|
||||
if (z.z_info.format == 3)
|
||||
{
|
||||
size = (z.slice_div64_minus1 + 1) * 64 * 4;
|
||||
} else if (z.z_info.format == 1)
|
||||
{
|
||||
size = (z.slice_div64_minus1 + 1) * 64 * 2;
|
||||
}
|
||||
|
||||
bool htile = z.z_info.tile_surface_enable;
|
||||
|
||||
bool neo = Config::IsNeo();
|
||||
bool ps5 = Config::IsNextGen();
|
||||
bool htile = z.z_info.tile_surface_enable;
|
||||
bool decompress = htile && (rc.depth_compress_disable || rc.stencil_compress_disable);
|
||||
|
||||
if (!TileGetDepthSize(z.width, z.height, pitch, z.z_info.format, z.stencil_info.format, htile, neo, &stencil_size, &htile_size,
|
||||
&depth_size))
|
||||
{
|
||||
depth_size.size = size;
|
||||
depth_size.align = neo ? 65536 : 32768;
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(depth_size.size != size);
|
||||
}
|
||||
|
||||
if (dc.z_enable || dc.z_write_enable || dc.stencil_enable || decompress)
|
||||
{
|
||||
switch (z.z_info.format * 2 + z.stencil_info.format)
|
||||
@@ -3763,6 +3838,38 @@ static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, c
|
||||
}
|
||||
}
|
||||
|
||||
if (r->format != VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
if (ps5)
|
||||
{
|
||||
bool size_found = TileGetDepthSize(z.size.x_max + 1, z.size.y_max + 1, 0, z.z_info.format, z.stencil_info.format, htile, true,
|
||||
true, &stencil_size, &htile_size, &depth_size);
|
||||
EXIT_NOT_IMPLEMENTED(!size_found);
|
||||
} else
|
||||
{
|
||||
uint32_t size = 0;
|
||||
uint32_t pitch = (z.pitch_div8_minus1 + 1) * 8;
|
||||
|
||||
if (z.z_info.format == 3)
|
||||
{
|
||||
size = (z.slice_div64_minus1 + 1) * 64 * 4;
|
||||
} else if (z.z_info.format == 1)
|
||||
{
|
||||
size = (z.slice_div64_minus1 + 1) * 64 * 2;
|
||||
}
|
||||
|
||||
if (!TileGetDepthSize(z.width, z.height, pitch, z.z_info.format, z.stencil_info.format, htile, neo, false, &stencil_size,
|
||||
&htile_size, &depth_size))
|
||||
{
|
||||
depth_size.size = size;
|
||||
depth_size.align = neo ? 65536 : 32768;
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(depth_size.size != size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto stencil_addr_mask = static_cast<uint64_t>(stencil_size.align) - 1;
|
||||
auto depth_addr_mask = static_cast<uint64_t>(depth_size.align) - 1;
|
||||
auto htile_addr_mask = static_cast<uint64_t>(htile_size.align) - 1;
|
||||
@@ -3778,8 +3885,8 @@ static void FindRenderDepthInfo(uint64_t submit_id, CommandBuffer* /*buffer*/, c
|
||||
r->htile_buffer_size = htile_size.size;
|
||||
r->htile_buffer_vaddr = z.htile_data_base_addr & ~htile_addr_mask;
|
||||
r->htile_tile_swizzle = z.htile_data_base_addr & htile_addr_mask;
|
||||
r->width = z.width;
|
||||
r->height = z.height;
|
||||
r->width = (ps5 ? z.size.x_max + 1 : z.width);
|
||||
r->height = (ps5 ? z.size.y_max + 1 : z.height);
|
||||
r->depth_clear_enable = rc.depth_clear_enable;
|
||||
r->depth_clear_value = hw.GetDepthClearValue();
|
||||
r->depth_test_enable = dc.z_enable;
|
||||
@@ -3888,38 +3995,69 @@ static void FindRenderColorInfo(uint64_t submit_id, CommandBuffer* buffer, const
|
||||
return;
|
||||
}
|
||||
|
||||
auto width = rt.size.width;
|
||||
auto height = rt.size.height;
|
||||
auto pitch = (rt.pitch.pitch_div8_minus1 + 1) * 8;
|
||||
auto size = (rt.slice.slice_div64_minus1 + 1) * 64 * 4;
|
||||
bool tile = false;
|
||||
bool write_back = false;
|
||||
bool ps5 = Config::IsNextGen();
|
||||
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t pitch = 0;
|
||||
uint32_t size = 0;
|
||||
bool tile = false;
|
||||
bool write_back = false;
|
||||
|
||||
if (ps5)
|
||||
{
|
||||
switch (rt.attrib3.tile_mode)
|
||||
{
|
||||
case 0x1b:
|
||||
tile = true;
|
||||
write_back = false;
|
||||
break;
|
||||
default: EXIT("unknown tile mode: %u\n", rt.attrib3.tile_mode);
|
||||
}
|
||||
|
||||
width = rt.attrib2.width + 1;
|
||||
height = rt.attrib2.height + 1;
|
||||
pitch = width;
|
||||
|
||||
Graphics::TileSizeAlign size32 {};
|
||||
Graphics::TileGetVideoOutSize(width, height, pitch, tile, true, &size32);
|
||||
|
||||
size = size32.size;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size == 0);
|
||||
} else
|
||||
{
|
||||
switch (rt.attrib.tile_mode)
|
||||
{
|
||||
case 0x8:
|
||||
tile = false;
|
||||
write_back = false;
|
||||
break;
|
||||
|
||||
case 0x1f:
|
||||
tile = false;
|
||||
write_back = true;
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
tile = true;
|
||||
write_back = false;
|
||||
break;
|
||||
|
||||
default: EXIT("unknown tile mode: %u\n", rt.attrib.tile_mode);
|
||||
}
|
||||
|
||||
width = rt.size.width;
|
||||
height = rt.size.height;
|
||||
pitch = (rt.pitch.pitch_div8_minus1 + 1) * 8;
|
||||
size = (rt.slice.slice_div64_minus1 + 1) * 64 * 4;
|
||||
}
|
||||
|
||||
auto video_image = VideoOut::VideoOutGetImage(rt.base.addr);
|
||||
bool render_to_texture = (video_image.image == nullptr);
|
||||
|
||||
switch (rt.attrib.tile_mode)
|
||||
{
|
||||
case 0x8:
|
||||
tile = false;
|
||||
write_back = false;
|
||||
break;
|
||||
|
||||
case 0x1f:
|
||||
tile = false;
|
||||
write_back = true;
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
case 0xd:
|
||||
case 0xe:
|
||||
tile = true;
|
||||
write_back = false;
|
||||
break;
|
||||
|
||||
default: EXIT("unknown tile mode: %u\n", rt.attrib.tile_mode);
|
||||
}
|
||||
|
||||
if (render_to_texture)
|
||||
{
|
||||
RenderTextureFormat rt_format = RenderTextureFormat::Unknown;
|
||||
@@ -3955,8 +4093,8 @@ static void FindRenderColorInfo(uint64_t submit_id, CommandBuffer* buffer, const
|
||||
r->buffer_size = size;
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(
|
||||
!(rt.info.format == 0xa && (rt.info.channel_type == 0x6 || rt.info.channel_type == 0x0) && rt.info.channel_order == 0x1));
|
||||
EXIT_NOT_IMPLEMENTED(!(rt.info.format == 0xa && (rt.info.channel_type == 0x6 || rt.info.channel_type == 0x0) &&
|
||||
(rt.info.channel_order == 0x0 || rt.info.channel_order == 0x1)));
|
||||
|
||||
// Display buffer
|
||||
EXIT_NOT_IMPLEMENTED(video_image.buffer_size != size);
|
||||
@@ -3994,6 +4132,7 @@ static void InvalidateMemoryObject(const RenderDepthInfo& r)
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
static void PrepareStorageBuffers(uint64_t submit_id, CommandBuffer* buffer, const ShaderStorageResources& storage_buffers,
|
||||
VulkanBuffer** buffers, uint32_t** sgprs)
|
||||
{
|
||||
@@ -4003,26 +4142,36 @@ static void PrepareStorageBuffers(uint64_t submit_id, CommandBuffer* buffer, con
|
||||
EXIT_IF(sgprs == nullptr);
|
||||
EXIT_IF(*sgprs == nullptr);
|
||||
|
||||
bool gen5 = Config::IsNextGen();
|
||||
|
||||
for (int i = 0; i < storage_buffers.buffers_num; i++)
|
||||
{
|
||||
auto r = storage_buffers.buffers[i];
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(r.AddTid());
|
||||
EXIT_NOT_IMPLEMENTED(r.SwizzleEnabled());
|
||||
EXIT_NOT_IMPLEMENTED(!((r.Stride() == 4 && r.DstSelXYZW() == DstSel(4, 0, 0, 0) && r.Dfmt() == 4 && r.Nfmt() == 4) ||
|
||||
(r.Stride() == 4 && r.DstSelXYZW() == DstSel(4, 0, 0, 1) && r.Dfmt() == 4 && r.Nfmt() == 7) ||
|
||||
(r.Stride() == 8 && r.DstSelXYZW() == DstSel(4, 5, 0, 0) && r.Dfmt() == 11 && r.Nfmt() == 4) ||
|
||||
(r.Stride() == 16 && r.DstSelXYZW() == DstSel(4, 5, 6, 7) && r.Dfmt() == 14 && r.Nfmt() == 7)));
|
||||
EXIT_NOT_IMPLEMENTED(!(r.MemoryType() == 0x00 || r.MemoryType() == 0x10 || r.MemoryType() == 0x6d));
|
||||
|
||||
auto addr = r.Base();
|
||||
if (gen5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(r.OutOfBounds() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(!((r.Stride() == 16 && r.DstSelXYZW() == DstSel(4, 5, 6, 7) && r.Format() == 77)));
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(!((r.Stride() == 4 && r.DstSelXYZW() == DstSel(4, 0, 0, 0) && r.Dfmt() == 4 && r.Nfmt() == 4) ||
|
||||
(r.Stride() == 4 && r.DstSelXYZW() == DstSel(4, 0, 0, 1) && r.Dfmt() == 4 && r.Nfmt() == 7) ||
|
||||
(r.Stride() == 8 && r.DstSelXYZW() == DstSel(4, 5, 0, 0) && r.Dfmt() == 11 && r.Nfmt() == 4) ||
|
||||
(r.Stride() == 16 && r.DstSelXYZW() == DstSel(4, 5, 6, 7) && r.Dfmt() == 14 && r.Nfmt() == 7)));
|
||||
EXIT_NOT_IMPLEMENTED(!(r.MemoryType() == 0x00 || r.MemoryType() == 0x10 || r.MemoryType() == 0x6d));
|
||||
}
|
||||
|
||||
auto addr = (gen5 ? r.Base48() : r.Base44());
|
||||
auto stride = r.Stride();
|
||||
auto num_records = r.NumRecords();
|
||||
auto size = stride * num_records;
|
||||
EXIT_NOT_IMPLEMENTED(size == 0);
|
||||
EXIT_NOT_IMPLEMENTED((size & 0x3u) != 0);
|
||||
|
||||
bool read_only = (r.MemoryType() == 0x10);
|
||||
bool read_only = (gen5 ? false : (r.MemoryType() == 0x10));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(read_only && !(storage_buffers.usages[i] == ShaderStorageUsage::ReadOnly ||
|
||||
storage_buffers.usages[i] == ShaderStorageUsage::Constant));
|
||||
@@ -4038,9 +4187,15 @@ static void PrepareStorageBuffers(uint64_t submit_id, CommandBuffer* buffer, con
|
||||
|
||||
buffers[i] = buf;
|
||||
|
||||
r.UpdateAddress(i);
|
||||
if (gen5)
|
||||
{
|
||||
r.UpdateAddress48(i);
|
||||
} else
|
||||
{
|
||||
r.UpdateAddress44(i);
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((r.Base() >> 32u) != 0);
|
||||
EXIT_NOT_IMPLEMENTED(((gen5 ? r.Base48() : r.Base44()) >> 32u) != 0);
|
||||
|
||||
(*sgprs)[0] = r.fields[0];
|
||||
(*sgprs)[1] = r.fields[1];
|
||||
@@ -4065,48 +4220,83 @@ static void PrepareTextures(uint64_t submit_id, CommandBuffer* buffer, const Sha
|
||||
int index_sampled = 0;
|
||||
int index_storage = 0;
|
||||
|
||||
bool gen5 = Config::IsNextGen();
|
||||
|
||||
for (int i = 0; i < textures.textures_num; i++)
|
||||
{
|
||||
auto r = textures.desc[i].texture;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(r.Base() == 0);
|
||||
if (gen5)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(!(r.TileMode() == 0));
|
||||
EXIT_NOT_IMPLEMENTED(r.Format() != 56);
|
||||
EXIT_NOT_IMPLEMENTED(r.PerfMod5() != 7 && r.PerfMod5() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.BCSwizzle() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.BaseArray5() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.ArrayPitch() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MaxMip() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MinLodWarn5() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MipStatsCntId() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MipStatsCntEn() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.CornerSample() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.PrtDefColor() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MsaaDepth() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MaxUncompBlkSize() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MaxCompBlkSize() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MetaPipeAligned() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.WriteCompress() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MetaCompress() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.DccAlphaPos() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.DccColorTransf() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MetaAddr() != 0);
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(r.Dfmt() != 1 && r.Dfmt() != 10 && r.Dfmt() != 37 && r.Dfmt() != 4 && r.Dfmt() != 35 && r.Dfmt() != 3 &&
|
||||
r.Dfmt() != 36);
|
||||
EXIT_NOT_IMPLEMENTED(r.Nfmt() != 9 && r.Nfmt() != 0 && r.Nfmt() != 7);
|
||||
EXIT_NOT_IMPLEMENTED(r.PerfMod() != 7 && r.PerfMod() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.Interlaced() != false);
|
||||
EXIT_NOT_IMPLEMENTED(!(r.TileMode() == 8 || r.TileMode() == 13 || r.TileMode() == 14 || r.TileMode() == 2 ||
|
||||
r.TileMode() == 10 || r.TileMode() == 31));
|
||||
EXIT_NOT_IMPLEMENTED(r.BaseArray() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.LastArray() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MinLodWarn() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.CounterBankId() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.LodHdwCntEn() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MemoryType() != 0x10 && r.MemoryType() != 0x6d);
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED((gen5 ? r.Base40() : r.Base38()) == 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MinLod() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.Dfmt() != 1 && r.Dfmt() != 10 && r.Dfmt() != 37 && r.Dfmt() != 4 && r.Dfmt() != 35 && r.Dfmt() != 3 &&
|
||||
r.Dfmt() != 36);
|
||||
EXIT_NOT_IMPLEMENTED(r.Nfmt() != 9 && r.Nfmt() != 0 && r.Nfmt() != 7);
|
||||
EXIT_NOT_IMPLEMENTED(r.PerfMod() != 7 && r.PerfMod() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.Interlaced() != false);
|
||||
EXIT_NOT_IMPLEMENTED(!(r.TilingIdx() == 8 || r.TilingIdx() == 13 || r.TilingIdx() == 14 || r.TilingIdx() == 2 ||
|
||||
r.TilingIdx() == 10 || r.TilingIdx() == 31));
|
||||
EXIT_NOT_IMPLEMENTED(r.Type() != 9);
|
||||
EXIT_NOT_IMPLEMENTED(r.Depth() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.BaseArray() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.LastArray() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.MinLodWarn() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.CounterBankId() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.LodHdwCntEn() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.MemoryType() != 0x10 && r.MemoryType() != 0x6d);
|
||||
|
||||
bool read_only = (r.MemoryType() == 0x10);
|
||||
bool read_only = (gen5 ? false : (r.MemoryType() == 0x10));
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(read_only && !(textures.desc[i].usage == ShaderTextureUsage::ReadOnly));
|
||||
|
||||
TileSizeAlign size {};
|
||||
auto addr = r.Base();
|
||||
auto addr = (gen5 ? r.Base40() : r.Base38());
|
||||
bool neo = Config::IsNeo();
|
||||
auto width = r.Width() + 1;
|
||||
auto height = r.Height() + 1;
|
||||
auto pitch = r.Pitch() + 1;
|
||||
auto width = (gen5 ? r.Width5() : r.Width4()) + 1;
|
||||
auto height = (gen5 ? r.Height5() : r.Height4()) + 1;
|
||||
auto pitch = (gen5 ? width : r.Pitch() + 1);
|
||||
auto base_level = r.BaseLevel();
|
||||
auto levels = r.LastLevel() + 1;
|
||||
auto tile = r.TilingIdx();
|
||||
auto dfmt = r.Dfmt();
|
||||
auto nfmt = r.Nfmt();
|
||||
auto tile = r.TileMode();
|
||||
auto dfmt = (gen5 ? 0 : r.Dfmt());
|
||||
auto nfmt = (gen5 ? 0 : r.Nfmt());
|
||||
auto fmt = (gen5 ? r.Format() : 0);
|
||||
uint32_t swizzle = r.DstSelXYZW();
|
||||
|
||||
bool check_depth_texture = (tile == 2);
|
||||
bool check_depth_texture = (!gen5 && tile == 2);
|
||||
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, &size, nullptr, nullptr);
|
||||
if (gen5)
|
||||
{
|
||||
TileGetTextureSize2(fmt, width, height, pitch, levels, tile, &size, nullptr, nullptr);
|
||||
} else
|
||||
{
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, &size, nullptr, nullptr);
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size.size == 0);
|
||||
EXIT_NOT_IMPLEMENTED((addr & (static_cast<uint64_t>(size.align) - 1u)) != 0);
|
||||
@@ -4149,14 +4339,14 @@ static void PrepareTextures(uint64_t submit_id, CommandBuffer* buffer, const Sha
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(textures.desc[i].usage != ShaderTextureUsage::ReadWrite);
|
||||
|
||||
StorageTextureObject vulkan_texture_info(dfmt, nfmt, width, height, pitch, base_level, levels, tile, neo, swizzle);
|
||||
StorageTextureObject vulkan_texture_info(dfmt, nfmt, fmt, width, height, pitch, base_level, levels, tile, neo, swizzle);
|
||||
tex = static_cast<StorageTextureVulkanImage*>(
|
||||
GpuMemoryCreateObject(submit_id, g_render_ctx->GetGraphicCtx(), buffer, addr, size.size, vulkan_texture_info));
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(textures.desc[i].usage != ShaderTextureUsage::ReadOnly);
|
||||
|
||||
if (tile == 10)
|
||||
if (!gen5 && tile == 10)
|
||||
{
|
||||
RenderTextureFormat rt_format = RenderTextureFormat::Unknown;
|
||||
if (dfmt == 10 && nfmt == 0)
|
||||
@@ -4169,7 +4359,7 @@ static void PrepareTextures(uint64_t submit_id, CommandBuffer* buffer, const Sha
|
||||
submit_id, g_render_ctx->GetGraphicCtx(), buffer, addr, size.size, vulkan_buffer_info));
|
||||
} else
|
||||
{
|
||||
TextureObject vulkan_texture_info(dfmt, nfmt, width, height, pitch, base_level, levels, tile, neo, swizzle);
|
||||
TextureObject vulkan_texture_info(dfmt, nfmt, fmt, width, height, pitch, base_level, levels, tile, neo, swizzle);
|
||||
tex = static_cast<TextureVulkanImage*>(
|
||||
GpuMemoryCreateObject(submit_id, g_render_ctx->GetGraphicCtx(), buffer, addr, size.size, vulkan_texture_info));
|
||||
}
|
||||
@@ -4181,17 +4371,29 @@ static void PrepareTextures(uint64_t submit_id, CommandBuffer* buffer, const Sha
|
||||
if (textures.desc[i].textures2d_without_sampler)
|
||||
{
|
||||
images_storage[index_storage] = tex;
|
||||
r.UpdateAddress(index_storage);
|
||||
if (gen5)
|
||||
{
|
||||
r.UpdateAddress40(index_storage);
|
||||
} else
|
||||
{
|
||||
r.UpdateAddress38(index_storage);
|
||||
}
|
||||
index_storage++;
|
||||
} else
|
||||
{
|
||||
images_sampled[index_sampled] = tex;
|
||||
images_sampled_view[index_sampled] = (depth_texture ? VulkanImage::VIEW_DEPTH_TEXTURE : view_type);
|
||||
r.UpdateAddress(index_sampled);
|
||||
if (gen5)
|
||||
{
|
||||
r.UpdateAddress40(index_sampled);
|
||||
} else
|
||||
{
|
||||
r.UpdateAddress38(index_sampled);
|
||||
}
|
||||
index_sampled++;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((r.Base() >> 32u) != 0);
|
||||
EXIT_NOT_IMPLEMENTED(((gen5 ? r.Base40() : r.Base38()) >> 32u) != 0);
|
||||
|
||||
(*sgprs)[0] = r.fields[0];
|
||||
(*sgprs)[1] = r.fields[1];
|
||||
@@ -4215,6 +4417,8 @@ static void PrepareSamplers(const ShaderSamplerResources& samplers, uint64_t* sa
|
||||
EXIT_IF(sgprs == nullptr);
|
||||
EXIT_IF(*sgprs == nullptr);
|
||||
|
||||
bool gen5 = Config::IsNextGen();
|
||||
|
||||
for (int i = 0; i < samplers.samplers_num; i++)
|
||||
{
|
||||
auto r = samplers.samplers[i];
|
||||
@@ -4226,8 +4430,12 @@ static void PrepareSamplers(const ShaderSamplerResources& samplers, uint64_t* sa
|
||||
EXIT_NOT_IMPLEMENTED(r.DepthCompareFunc() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.ForceUnormCoords() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.AnisoThreshold() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.McCoordTrunc() != false);
|
||||
EXIT_NOT_IMPLEMENTED(!gen5 && r.McCoordTrunc() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.ForceDegamma() != false);
|
||||
EXIT_NOT_IMPLEMENTED(gen5 && r.SkipDegamma() != false);
|
||||
EXIT_NOT_IMPLEMENTED(gen5 && r.PointPreclamp() != false);
|
||||
EXIT_NOT_IMPLEMENTED(gen5 && r.AnisoOverride() != false);
|
||||
EXIT_NOT_IMPLEMENTED(gen5 && r.BlendZeroPrt() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.AnisoBias() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(r.TruncCoord() != false);
|
||||
EXIT_NOT_IMPLEMENTED(r.DisableCubeWrap() != false);
|
||||
@@ -4457,7 +4665,7 @@ void GraphicsRenderDrawIndex(uint64_t submit_id, CommandBuffer* buffer, HW::Cont
|
||||
hw_print(*ctx);
|
||||
hw_check(*ctx);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(ctx->GetShaderStages() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ctx->GetShaderStages() != 0 && ctx->GetShaderStages() != 0x02002000);
|
||||
|
||||
VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
|
||||
@@ -4605,7 +4813,7 @@ void GraphicsRenderDrawIndexAuto(uint64_t submit_id, CommandBuffer* buffer, HW::
|
||||
printf("\t flags = 0x%08" PRIx32 "\n", flags);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(flags != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ctx->GetShaderStages() != 0);
|
||||
EXIT_NOT_IMPLEMENTED(ctx->GetShaderStages() != 0 && ctx->GetShaderStages() != 0x02002000);
|
||||
|
||||
RenderDepthInfo depth_info;
|
||||
FindRenderDepthInfo(submit_id, buffer, *ctx, &depth_info);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
|
||||
#include "Emulator/Config.h"
|
||||
#include "Emulator/Graphics/AsyncJob.h"
|
||||
#include "Emulator/Graphics/GraphicContext.h"
|
||||
#include "Emulator/Graphics/Graphics.h"
|
||||
@@ -309,7 +310,7 @@ private:
|
||||
CommandProcessor* m_compute_cp[8] = {};
|
||||
ComputeRing* m_compute_ring[64] = {};
|
||||
|
||||
int m_done_num = 0;
|
||||
std::atomic_int m_done_num = 0;
|
||||
};
|
||||
|
||||
using hw_ctx_parser_func_t = uint32_t (*)(KYTY_HW_CTX_PARSER_ARGS);
|
||||
@@ -452,7 +453,7 @@ bool Gpu::AreSubmitsAllowed()
|
||||
|
||||
int Gpu::GetFrameNum()
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
// Core::LockGuard lock(m_mutex);
|
||||
|
||||
return m_done_num;
|
||||
}
|
||||
@@ -1179,7 +1180,8 @@ void CommandProcessor::WriteAtEndOfPipe64(uint32_t cache_policy, uint32_t event_
|
||||
cache_action == 0x38 && source64 && !with_interrupt)
|
||||
{
|
||||
GraphicsRenderWriteAtEndOfPipeWithWriteBack64(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
|
||||
} else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && source_counter && !with_interrupt)
|
||||
} else if (((eop_event_type == 0x04 && event_index == 0x05) || (eop_event_type == 0x28 && event_index == 0x00)) &&
|
||||
cache_action == 0x00 && source_counter && !with_interrupt)
|
||||
{
|
||||
GraphicsRenderWriteAtEndOfPipeClockCounter(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr));
|
||||
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x00 && source64 && with_interrupt)
|
||||
@@ -1581,6 +1583,11 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_color_info)
|
||||
r.cmask_tile_mode_neo = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, CMASK_ADDR_TYPE);
|
||||
r.neo_mode = KYTY_PM4_GET(buffer[0], CB_COLOR0_INFO, ALT_TILE_MODE) != 0;
|
||||
|
||||
if (!r.neo_mode && Config::IsNextGen())
|
||||
{
|
||||
r.neo_mode = true;
|
||||
}
|
||||
|
||||
cp->GetCtx()->SetColorInfo(param, r);
|
||||
|
||||
return 1;
|
||||
@@ -1957,6 +1964,11 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_render_target)
|
||||
info.cmask_tile_mode_neo = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, CMASK_ADDR_TYPE);
|
||||
info.neo_mode = KYTY_PM4_GET(buffer[4], CB_COLOR0_INFO, ALT_TILE_MODE) != 0;
|
||||
|
||||
if (!info.neo_mode && Config::IsNextGen())
|
||||
{
|
||||
info.neo_mode = true;
|
||||
}
|
||||
|
||||
// attrib.force_dest_alpha_to_one = (buffer[5] & 0x20000u) != 0;
|
||||
// attrib.tile_mode = buffer[5] & 0x1fu;
|
||||
// attrib.fmask_tile_mode = (buffer[5] >> 5u) & 0x1fu;
|
||||
@@ -3223,21 +3235,39 @@ KYTY_CP_OP_PARSER(cp_op_release_mem)
|
||||
|
||||
if (custom)
|
||||
{
|
||||
uint32_t gcr_cntl = buffer[1];
|
||||
uint32_t gcr_cntl = buffer[1] & 0xffffu;
|
||||
uint32_t data_sel = (buffer[1] >> 16u) & 0xffu;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(gcr_cntl != 0x200);
|
||||
EXIT_NOT_IMPLEMENTED((buffer[0] >> 8u) != 0x3);
|
||||
EXIT_NOT_IMPLEMENTED(data_sel != 2 && data_sel != 3);
|
||||
|
||||
if (gcr_cntl == 0x200)
|
||||
if (data_sel == 2)
|
||||
{
|
||||
cache_action = 0x38;
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(gcr_cntl != 0x0200);
|
||||
EXIT_NOT_IMPLEMENTED((buffer[0] >> 8u) != 0x3);
|
||||
|
||||
cache_policy = 0;
|
||||
event_index = 0;
|
||||
event_write_dest = 0;
|
||||
event_write_source = 2;
|
||||
interrupt_selector = 0;
|
||||
if (gcr_cntl == 0x200)
|
||||
{
|
||||
cache_action = 0x38;
|
||||
}
|
||||
|
||||
cache_policy = 0;
|
||||
event_index = 0;
|
||||
event_write_dest = 0;
|
||||
event_write_source = 2;
|
||||
interrupt_selector = 0;
|
||||
} else if (data_sel == 3)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(gcr_cntl != 0x0000);
|
||||
EXIT_NOT_IMPLEMENTED((buffer[0] >> 8u) != 0x0);
|
||||
|
||||
cache_action = 0x00;
|
||||
|
||||
cache_policy = 0;
|
||||
event_index = 0;
|
||||
event_write_dest = 0;
|
||||
event_write_source = 4;
|
||||
interrupt_selector = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cp->WriteAtEndOfPipe64(cache_policy, event_write_dest, eop_event_type, cache_action, event_index, event_write_source, dst_gpu_addr,
|
||||
@@ -3513,6 +3543,10 @@ static void graphics_init_jmp_tables_cx_indirect()
|
||||
info.dcc_compression_enable = KYTY_PM4_GET(value, CB_COLOR0_INFO, DCC_ENABLE) != 0;
|
||||
info.cmask_tile_mode_neo = KYTY_PM4_GET(value, CB_COLOR0_INFO, CMASK_ADDR_TYPE);
|
||||
info.neo_mode = KYTY_PM4_GET(value, CB_COLOR0_INFO, ALT_TILE_MODE) != 0;
|
||||
if (!info.neo_mode && Config::IsNextGen())
|
||||
{
|
||||
info.neo_mode = true;
|
||||
}
|
||||
cp->GetCtx()->SetColorInfo(slot, info);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,21 +17,27 @@
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
static VkFormat get_texture_format(uint32_t dfmt, uint32_t nfmt)
|
||||
static VkFormat get_texture_format(uint32_t dfmt, uint32_t nfmt, uint32_t fmt)
|
||||
{
|
||||
if (nfmt == 9 && dfmt == 10)
|
||||
if (fmt == 0)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 10)
|
||||
if (nfmt == 9 && dfmt == 10)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 10)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
if (nfmt == 9 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
}
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
} else
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
EXIT("unknown format: fmt = %u\n", fmt);
|
||||
}
|
||||
if (nfmt == 9 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
}
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
@@ -130,8 +136,9 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
auto* vk_obj = static_cast<StorageTextureVulkanImage*>(obj);
|
||||
|
||||
auto tile = params[StorageTextureObject::PARAM_TILE];
|
||||
auto dfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto fmt = (params[StorageTextureObject::PARAM_FORMAT] >> 16u) & 0xffffu;
|
||||
auto dfmt = (params[StorageTextureObject::PARAM_FORMAT] >> 8u) & 0xffu;
|
||||
auto nfmt = (params[StorageTextureObject::PARAM_FORMAT]) & 0xffu;
|
||||
auto width = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
// auto base_level = params[StorageTextureObject::PARAM_LEVELS] >> 32u;
|
||||
@@ -147,7 +154,13 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
|
||||
TileSizeOffset level_sizes[16];
|
||||
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr);
|
||||
if (fmt != 0)
|
||||
{
|
||||
TileGetTextureSize2(fmt, width, height, pitch, levels, tile, nullptr, level_sizes, nullptr);
|
||||
} else
|
||||
{
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr);
|
||||
}
|
||||
|
||||
// dbg_test_mipmaps(ctx, VK_FORMAT_BC3_SRGB_BLOCK, 512, 512);
|
||||
|
||||
@@ -187,6 +200,7 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
if (tile == 13)
|
||||
{
|
||||
// EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
EXIT_NOT_IMPLEMENTED(fmt != 0);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, pitch,
|
||||
levels, neo);
|
||||
@@ -208,8 +222,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[StorageTextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto fmt = (params[StorageTextureObject::PARAM_FORMAT] >> 16u) & 0xffffu;
|
||||
auto dfmt = (params[StorageTextureObject::PARAM_FORMAT] >> 8u) & 0xffu;
|
||||
auto nfmt = (params[StorageTextureObject::PARAM_FORMAT]) & 0xffu;
|
||||
auto width = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[StorageTextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[StorageTextureObject::PARAM_LEVELS] >> 32u;
|
||||
@@ -227,7 +242,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt, fmt);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(pixel_format == VK_FORMAT_UNDEFINED);
|
||||
EXIT_NOT_IMPLEMENTED(width == 0);
|
||||
@@ -336,7 +351,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
bool StorageTextureObject::Equal(const uint64_t* other) const
|
||||
{
|
||||
return (params[PARAM_DFMT_NFMT] == other[PARAM_DFMT_NFMT] && params[PARAM_PITCH] == other[PARAM_PITCH] &&
|
||||
return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_PITCH] == other[PARAM_PITCH] &&
|
||||
params[PARAM_WIDTH_HEIGHT] == other[PARAM_WIDTH_HEIGHT] && params[PARAM_LEVELS] == other[PARAM_LEVELS] &&
|
||||
params[PARAM_TILE] == other[PARAM_TILE] && params[PARAM_NEO] == other[PARAM_NEO] &&
|
||||
params[PARAM_SWIZZLE] == other[PARAM_SWIZZLE]);
|
||||
|
||||
@@ -17,41 +17,51 @@
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
||||
static VkFormat get_texture_format(uint32_t dfmt, uint32_t nfmt)
|
||||
static VkFormat get_texture_format(uint32_t dfmt, uint32_t nfmt, uint32_t fmt)
|
||||
{
|
||||
if (nfmt == 9 && dfmt == 10)
|
||||
if (fmt == 0)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 10)
|
||||
if (nfmt == 9 && dfmt == 10)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_SRGB;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 10)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 1)
|
||||
{
|
||||
return VK_FORMAT_R8_UNORM;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 3)
|
||||
{
|
||||
return VK_FORMAT_R8G8_UNORM;
|
||||
}
|
||||
if (nfmt == 9 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 36)
|
||||
{
|
||||
return VK_FORMAT_BC2_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 35)
|
||||
{
|
||||
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
}
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
} else
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
if (fmt == 56)
|
||||
{
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
EXIT("unknown format: fmt = %u\n", fmt);
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 1)
|
||||
{
|
||||
return VK_FORMAT_R8_UNORM;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 3)
|
||||
{
|
||||
return VK_FORMAT_R8G8_UNORM;
|
||||
}
|
||||
if (nfmt == 9 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_SRGB_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 37)
|
||||
{
|
||||
return VK_FORMAT_BC3_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 36)
|
||||
{
|
||||
return VK_FORMAT_BC2_UNORM_BLOCK;
|
||||
}
|
||||
if (nfmt == 0 && dfmt == 35)
|
||||
{
|
||||
return VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
|
||||
}
|
||||
EXIT("unknown format: nfmt = %u, dfmt = %u\n", nfmt, dfmt);
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
@@ -150,8 +160,9 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
auto* vk_obj = static_cast<TextureVulkanImage*>(obj);
|
||||
|
||||
auto tile = params[TextureObject::PARAM_TILE];
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto fmt = (params[TextureObject::PARAM_FORMAT] >> 16u) & 0xffffu;
|
||||
auto dfmt = (params[TextureObject::PARAM_FORMAT] >> 8u) & 0xffu;
|
||||
auto nfmt = (params[TextureObject::PARAM_FORMAT]) & 0xffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto levels = params[TextureObject::PARAM_LEVELS] & 0xffffffffu;
|
||||
@@ -162,11 +173,19 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(levels >= 16);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(tile != 8 && tile != 13);
|
||||
|
||||
TileSizeOffset level_sizes[16];
|
||||
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr);
|
||||
if (fmt != 0)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(tile != 0);
|
||||
|
||||
TileGetTextureSize2(fmt, width, height, pitch, levels, tile, nullptr, level_sizes, nullptr);
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(tile != 8 && tile != 13);
|
||||
|
||||
TileGetTextureSize(dfmt, nfmt, width, height, pitch, levels, tile, neo, nullptr, level_sizes, nullptr);
|
||||
}
|
||||
|
||||
// dbg_test_mipmaps(ctx, VK_FORMAT_BC3_SRGB_BLOCK, 512, 512);
|
||||
|
||||
@@ -201,17 +220,27 @@ static void update_func(GraphicContext* ctx, const uint64_t* params, void* obj,
|
||||
}
|
||||
}
|
||||
|
||||
if (tile == 13)
|
||||
if (fmt == 0)
|
||||
{
|
||||
// EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, pitch,
|
||||
levels, neo);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
delete[] temp_buf;
|
||||
} else if (tile == 8)
|
||||
if (tile == 13)
|
||||
{
|
||||
// EXIT_NOT_IMPLEMENTED(pitch != width);
|
||||
EXIT_NOT_IMPLEMENTED(fmt != 0);
|
||||
auto* temp_buf = new uint8_t[*size];
|
||||
TileConvertTiledToLinear(temp_buf, reinterpret_cast<void*>(*vaddr), TileMode::TextureTiled, dfmt, nfmt, width, height, pitch,
|
||||
levels, neo);
|
||||
UtilFillImage(ctx, vk_obj, temp_buf, *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
delete[] temp_buf;
|
||||
} else if (tile == 8)
|
||||
{
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
}
|
||||
} else
|
||||
{
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
if (tile == 0)
|
||||
{
|
||||
UtilFillImage(ctx, vk_obj, reinterpret_cast<void*>(*vaddr), *size, regions, static_cast<uint64_t>(vk_layout));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,8 +421,9 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto fmt = (params[TextureObject::PARAM_FORMAT] >> 16u) & 0xffffu;
|
||||
auto dfmt = (params[TextureObject::PARAM_FORMAT] >> 8u) & 0xffu;
|
||||
auto nfmt = (params[TextureObject::PARAM_FORMAT]) & 0xffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[TextureObject::PARAM_LEVELS] >> 32u;
|
||||
@@ -409,7 +439,7 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt, fmt);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(pixel_format == VK_FORMAT_UNDEFINED);
|
||||
EXIT_NOT_IMPLEMENTED(width == 0);
|
||||
@@ -504,8 +534,9 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
EXIT_IF(ctx == nullptr);
|
||||
EXIT_IF(params == nullptr);
|
||||
|
||||
auto dfmt = params[TextureObject::PARAM_DFMT_NFMT] >> 32u;
|
||||
auto nfmt = params[TextureObject::PARAM_DFMT_NFMT] & 0xffffffffu;
|
||||
auto fmt = (params[TextureObject::PARAM_FORMAT] >> 16u) & 0xffffu;
|
||||
auto dfmt = (params[TextureObject::PARAM_FORMAT] >> 8u) & 0xffu;
|
||||
auto nfmt = (params[TextureObject::PARAM_FORMAT]) & 0xffu;
|
||||
auto width = params[TextureObject::PARAM_WIDTH_HEIGHT] >> 32u;
|
||||
auto height = params[TextureObject::PARAM_WIDTH_HEIGHT] & 0xffffffffu;
|
||||
auto base_level = params[TextureObject::PARAM_LEVELS] >> 32u;
|
||||
@@ -521,7 +552,7 @@ static void* create2_func(GraphicContext* ctx, CommandBuffer* buffer, const uint
|
||||
components.b = get_swizzle(GetDstSel(swizzle, 2));
|
||||
components.a = get_swizzle(GetDstSel(swizzle, 3));
|
||||
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt);
|
||||
auto pixel_format = get_texture_format(dfmt, nfmt, fmt);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(pixel_format == VK_FORMAT_UNDEFINED);
|
||||
EXIT_NOT_IMPLEMENTED(width == 0);
|
||||
@@ -628,7 +659,7 @@ static void delete_func(GraphicContext* ctx, void* obj, VulkanMemory* mem)
|
||||
|
||||
bool TextureObject::Equal(const uint64_t* other) const
|
||||
{
|
||||
return (params[PARAM_DFMT_NFMT] == other[PARAM_DFMT_NFMT] && params[PARAM_PITCH] == other[PARAM_PITCH] &&
|
||||
return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_PITCH] == other[PARAM_PITCH] &&
|
||||
params[PARAM_WIDTH_HEIGHT] == other[PARAM_WIDTH_HEIGHT] && params[PARAM_LEVELS] == other[PARAM_LEVELS] &&
|
||||
params[PARAM_TILE] == other[PARAM_TILE] && params[PARAM_NEO] == other[PARAM_NEO] &&
|
||||
params[PARAM_SWIZZLE] == other[PARAM_SWIZZLE]);
|
||||
|
||||
+986
-2010
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -501,7 +501,7 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
|
||||
}
|
||||
|
||||
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo,
|
||||
TileSizeAlign* stencil_size, TileSizeAlign* htile_size, TileSizeAlign* depth_size)
|
||||
bool next_gen, TileSizeAlign* stencil_size, TileSizeAlign* htile_size, TileSizeAlign* depth_size)
|
||||
{
|
||||
struct DepthInfo
|
||||
{
|
||||
@@ -585,11 +585,53 @@ bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t
|
||||
{1280, 720, 1, 1, false, true, 1280, {983040, 32768}, {0, 0}, {1966080, 65536}},
|
||||
};
|
||||
|
||||
static const DepthInfo infos_next_gen[] = {
|
||||
{3840, 2160, 3, 0, true, true, 3840, {0, 0}, {655360, 32768}, {33423360, 65536}},
|
||||
{3840, 2160, 3, 0, false, true, 3840, {0, 0}, {0, 0}, {33423360, 65536}},
|
||||
{1920, 1080, 3, 0, true, true, 1920, {0, 0}, {196608, 32768}, {8847360, 65536}},
|
||||
{1920, 1080, 3, 0, false, true, 1920, {0, 0}, {0, 0}, {8847360, 65536}},
|
||||
{1280, 720, 3, 0, true, true, 1280, {0, 0}, {131072, 32768}, {3932160, 65536}},
|
||||
{1280, 720, 3, 0, false, true, 1280, {0, 0}, {0, 0}, {3932160, 65536}},
|
||||
{3840, 2160, 1, 0, true, true, 3840, {0, 0}, {655360, 32768}, {16711680, 65536}},
|
||||
{3840, 2160, 1, 0, false, true, 3840, {0, 0}, {0, 0}, {16711680, 65536}},
|
||||
{1920, 1080, 1, 0, true, true, 2048, {0, 0}, {196608, 32768}, {4718592, 65536}},
|
||||
{1920, 1080, 1, 0, false, true, 2048, {0, 0}, {0, 0}, {4718592, 65536}},
|
||||
{1280, 720, 1, 0, true, true, 1280, {0, 0}, {131072, 32768}, {1966080, 65536}},
|
||||
{1280, 720, 1, 0, false, true, 1280, {0, 0}, {0, 0}, {1966080, 65536}},
|
||||
{3840, 2160, 3, 1, true, true, 3840, {8847360, 65536}, {655360, 32768}, {33423360, 65536}},
|
||||
{3840, 2160, 3, 1, false, true, 3840, {8847360, 65536}, {0, 0}, {33423360, 65536}},
|
||||
{1920, 1080, 3, 1, true, true, 1920, {2621440, 65536}, {196608, 32768}, {8847360, 65536}},
|
||||
{1920, 1080, 3, 1, false, true, 1920, {2621440, 65536}, {0, 0}, {8847360, 65536}},
|
||||
{1280, 720, 3, 1, true, true, 1280, {983040, 65536}, {131072, 32768}, {3932160, 65536}},
|
||||
{1280, 720, 3, 1, false, true, 1280, {983040, 65536}, {0, 0}, {3932160, 65536}},
|
||||
{3840, 2160, 1, 1, true, true, 3840, {8847360, 65536}, {655360, 32768}, {16711680, 65536}},
|
||||
{3840, 2160, 1, 1, false, true, 3840, {8847360, 65536}, {0, 0}, {16711680, 65536}},
|
||||
{1920, 1080, 1, 1, true, true, 2048, {2621440, 65536}, {196608, 32768}, {4718592, 65536}},
|
||||
{1920, 1080, 1, 1, false, true, 2048, {2621440, 65536}, {0, 0}, {4718592, 65536}},
|
||||
{1280, 720, 1, 1, true, true, 1280, {983040, 65536}, {131072, 32768}, {1966080, 65536}},
|
||||
{1280, 720, 1, 1, false, true, 1280, {983040, 65536}, {0, 0}, {1966080, 65536}},
|
||||
};
|
||||
|
||||
EXIT_IF(depth_size == nullptr);
|
||||
EXIT_IF(htile_size == nullptr);
|
||||
EXIT_IF(stencil_size == nullptr);
|
||||
|
||||
if (neo)
|
||||
if (next_gen)
|
||||
{
|
||||
EXIT_IF(pitch != 0);
|
||||
EXIT_IF(!neo);
|
||||
for (const auto& i: infos_next_gen)
|
||||
{
|
||||
if (i.width == width && i.height == height /*&& i.pitch == pitch*/ && i.tile == htile && i.z_format == z_format &&
|
||||
i.stencil_format == stencil_format)
|
||||
{
|
||||
*depth_size = i.depth;
|
||||
*htile_size = i.htile;
|
||||
*stencil_size = i.stencil;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (neo)
|
||||
{
|
||||
for (const auto& i: infos_neo)
|
||||
{
|
||||
@@ -719,6 +761,12 @@ struct TextureInfoSize
|
||||
uint32_t mipmap_size = 0;
|
||||
};
|
||||
|
||||
struct TextureInfoSize2
|
||||
{
|
||||
uint32_t mipmap_offset = 0;
|
||||
uint32_t mipmap_size = 0;
|
||||
};
|
||||
|
||||
struct TextureInfo
|
||||
{
|
||||
uint32_t dfmt = 0;
|
||||
@@ -733,6 +781,21 @@ struct TextureInfo
|
||||
TextureInfoPadded padded[16];
|
||||
};
|
||||
|
||||
struct TextureInfo2
|
||||
{
|
||||
uint32_t fmt = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t pitch = 0;
|
||||
uint32_t levels = 0;
|
||||
uint32_t tile = 0;
|
||||
uint32_t total_size = 0;
|
||||
uint32_t total_align = 0;
|
||||
TextureInfoSize2 size[16];
|
||||
TextureInfoPadded padded[16];
|
||||
};
|
||||
|
||||
#include "Tables/TileTextureInfo_0_56.inc"
|
||||
#include "Tables/TileTextureInfo_10_10_0.inc"
|
||||
#include "Tables/TileTextureInfo_13_10_0.inc"
|
||||
#include "Tables/TileTextureInfo_13_10_9.inc"
|
||||
@@ -759,6 +822,8 @@ static const TextureInfo* g_info_map_8_1_0[16][16][16][2] = {};
|
||||
static const TextureInfo* g_info_map_8_10_0[16][16][16][2] = {};
|
||||
static const TextureInfo* g_info_map_8_10_9[16][16][16][2] = {};
|
||||
|
||||
static const TextureInfo2* g_info_map_0_56[16][16][16][16] = {};
|
||||
|
||||
template <class Map>
|
||||
static void init_map(Map& map, const TextureInfo* info, int num)
|
||||
{
|
||||
@@ -786,7 +851,41 @@ static void init_map(Map& map, const TextureInfo* info, int num)
|
||||
auto h = IntLog2(i.height);
|
||||
auto p = IntLog2(i.pitch);
|
||||
auto n = i.neo ? 1 : 0;
|
||||
EXIT_IF(w > 16 || h > 16 || p > 16 || n > 2);
|
||||
EXIT_IF(w >= 16 || h >= 16 || p >= 16 || n >= 2);
|
||||
EXIT_IF(map[w][h][p][n] != nullptr);
|
||||
map[w][h][p][n] = &i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Map>
|
||||
static void init_map2(Map& map, const TextureInfo2* info, int num)
|
||||
{
|
||||
for (int w = 0; w < 16; w++)
|
||||
{
|
||||
for (int h = 0; h < 16; h++)
|
||||
{
|
||||
for (int p = 0; p < 16; p++)
|
||||
{
|
||||
for (int n = 0; n < 16; n++)
|
||||
{
|
||||
map[w][h][p][n] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = 0; index < num; index++)
|
||||
{
|
||||
const auto& i = info[index];
|
||||
if (!(i.width == 0 && i.height == 0 && i.pitch == 0))
|
||||
{
|
||||
EXIT_IF(!(IsPowerOfTwo(i.width) && IsPowerOfTwo(i.height) && IsPowerOfTwo(i.pitch)));
|
||||
auto w = IntLog2(i.width);
|
||||
auto h = IntLog2(i.height);
|
||||
auto p = IntLog2(i.pitch);
|
||||
auto n = i.levels;
|
||||
EXIT_IF(w >= 16 || h >= 16 || p >= 16 || n >= 16);
|
||||
EXIT_IF(map[w][h][p][n] != nullptr);
|
||||
map[w][h][p][n] = &i;
|
||||
}
|
||||
@@ -796,15 +895,20 @@ static void init_map(Map& map, const TextureInfo* info, int num)
|
||||
template <class Map>
|
||||
static const TextureInfo* check_map(Map& map, uint32_t width, uint32_t height, uint32_t pitch, bool neo)
|
||||
{
|
||||
// if (IsPowerOfTwo(width) && IsPowerOfTwo(height) && IsPowerOfTwo(pitch))
|
||||
{
|
||||
auto w = IntLog2(width);
|
||||
auto h = IntLog2(height);
|
||||
auto p = IntLog2(pitch);
|
||||
auto n = neo ? 1 : 0;
|
||||
return map[w][h][p][n];
|
||||
}
|
||||
// return nullptr;
|
||||
auto w = IntLog2(width);
|
||||
auto h = IntLog2(height);
|
||||
auto p = IntLog2(pitch);
|
||||
auto n = neo ? 1 : 0;
|
||||
return map[w][h][p][n];
|
||||
}
|
||||
|
||||
template <class Map>
|
||||
static const TextureInfo2* check_map2(Map& map, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels)
|
||||
{
|
||||
auto w = IntLog2(width);
|
||||
auto h = IntLog2(height);
|
||||
auto p = IntLog2(pitch);
|
||||
return map[w][h][p][levels];
|
||||
}
|
||||
|
||||
static void init_maps()
|
||||
@@ -821,6 +925,8 @@ static void init_maps()
|
||||
init_map(g_info_map_8_1_0, infos_8_1_0_pow2, std::size(infos_8_1_0_pow2));
|
||||
init_map(g_info_map_8_10_0, infos_8_10_0_pow2, std::size(infos_8_10_0_pow2));
|
||||
init_map(g_info_map_8_10_9, infos_8_10_9_pow2, std::size(infos_8_10_9_pow2));
|
||||
|
||||
init_map2(g_info_map_0_56, infos_0_56_pow2, std::size(infos_0_56_pow2));
|
||||
}
|
||||
|
||||
#define KYTY_TEXTURE_CHECK(n) \
|
||||
@@ -841,6 +947,24 @@ static void init_maps()
|
||||
*num = std::size(infos_##n); \
|
||||
}
|
||||
|
||||
#define KYTY_TEXTURE_CHECK2(n) \
|
||||
if (pow2) \
|
||||
{ \
|
||||
if (const auto* i = check_map2(g_info_map_##n, width, height, pitch, levels); i != nullptr) \
|
||||
{ \
|
||||
*info = i; \
|
||||
*num = 1; \
|
||||
} else \
|
||||
{ \
|
||||
*info = nullptr; \
|
||||
*num = 0; \
|
||||
} \
|
||||
} else \
|
||||
{ \
|
||||
*info = infos_##n; \
|
||||
*num = std::size(infos_##n); \
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
static void FindTextureInfo(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t tile, bool neo,
|
||||
const TextureInfo** info, int* num, bool pow2)
|
||||
@@ -905,6 +1029,23 @@ static void FindTextureInfo(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
static void FindTextureInfo2(uint32_t fmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t tile, uint32_t levels,
|
||||
const TextureInfo2** info, int* num, bool pow2)
|
||||
{
|
||||
EXIT_IF(info == nullptr);
|
||||
EXIT_IF(num == nullptr);
|
||||
|
||||
if (tile == 0 && fmt == 56)
|
||||
{
|
||||
KYTY_TEXTURE_CHECK2(0_56);
|
||||
} else
|
||||
{
|
||||
*info = nullptr;
|
||||
*num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
|
||||
bool neo, TileSizeAlign* total_size, TileSizeOffset* level_sizes, TilePaddedSize* padded_size)
|
||||
@@ -1004,6 +1145,72 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
|
||||
}
|
||||
}
|
||||
|
||||
void TileGetTextureSize2(uint32_t format, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
|
||||
TileSizeAlign* total_size, TileSizeOffset* level_sizes, TilePaddedSize* padded_size)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
const TextureInfo2* infos = nullptr;
|
||||
int num = 0;
|
||||
|
||||
bool pow2 = (IsPowerOfTwo(width) && IsPowerOfTwo(height) && IsPowerOfTwo(pitch));
|
||||
|
||||
EXIT_IF(levels == 0 || levels > 16);
|
||||
|
||||
FindTextureInfo2(format, width, height, pitch, tile, levels, &infos, &num, pow2);
|
||||
|
||||
for (int index = 0; index < num; index++)
|
||||
{
|
||||
const auto& i = infos[index];
|
||||
if (i.fmt == format && i.width == width && i.pitch == pitch && i.height == height && i.levels == levels && i.tile == tile)
|
||||
{
|
||||
if (total_size != nullptr)
|
||||
{
|
||||
total_size->size = i.total_size;
|
||||
total_size->align = i.total_align;
|
||||
}
|
||||
|
||||
if (level_sizes != nullptr)
|
||||
{
|
||||
if (levels == 1)
|
||||
{
|
||||
level_sizes[0].size = i.total_size;
|
||||
level_sizes[0].offset = 0;
|
||||
} else
|
||||
{
|
||||
for (uint32_t l = 0; l < levels; l++)
|
||||
{
|
||||
level_sizes[l].size = i.size[l].mipmap_size;
|
||||
level_sizes[l].offset = i.size[l].mipmap_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (padded_size != nullptr)
|
||||
{
|
||||
for (uint32_t l = 0; l < levels; l++)
|
||||
{
|
||||
padded_size[l].width = i.padded[l].width;
|
||||
padded_size[l].height = i.padded[l].height;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_size != nullptr && total_size->size == 0)
|
||||
{
|
||||
Core::StringList list;
|
||||
list.Add(String::FromPrintf("format = %u", format));
|
||||
list.Add(String::FromPrintf("width = %u", width));
|
||||
list.Add(String::FromPrintf("height = %u", height));
|
||||
list.Add(String::FromPrintf("pitch = %u", pitch));
|
||||
list.Add(String::FromPrintf("levels = %u", levels));
|
||||
list.Add(String::FromPrintf("tile = %u", tile));
|
||||
EXIT("unknown format:\n%s\n", list.Concat(U'\n').C_Str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -236,7 +236,7 @@ static void calc_buffer_size(const VideoOutBufferAttribute* attribute, const Vid
|
||||
|
||||
if (attribute2 != nullptr)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(attribute2->option != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute2->option != 0 && attribute2->option != 8);
|
||||
EXIT_NOT_IMPLEMENTED(attribute2->aspect_ratio != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute2->pixel_format != 0x8000000000000000ULL && attribute2->pixel_format != 0x8000000022000000ULL);
|
||||
} else
|
||||
@@ -1015,7 +1015,7 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers2(int handle, int set_index, int buffer
|
||||
EXIT_NOT_IMPLEMENTED(attribute->tiling_mode != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->aspect_ratio != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->pitch_in_pixel != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->option != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->option != 0 && attribute->option != 8);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->dcc_cb_register_clear_color != 0);
|
||||
EXIT_NOT_IMPLEMENTED(attribute->dcc_control != 0);
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
bool Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Find(uint64_t phys_addr, bool next, PhysicalMemory::AllocatedBlock* out);
|
||||
|
||||
[[nodiscard]] Core::Mutex& GetMutex() { return m_mutex; }
|
||||
[[nodiscard]] const Vector<AllocatedBlock>& GetBlocks() const { return m_allocated; }
|
||||
|
||||
private:
|
||||
Vector<AllocatedBlock> m_allocated;
|
||||
Core::Mutex m_mutex;
|
||||
@@ -81,6 +84,9 @@ public:
|
||||
bool Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode, Graphics::GpuMemoryMode* gpu_mode);
|
||||
|
||||
[[nodiscard]] Core::Mutex& GetMutex() { return m_mutex; }
|
||||
[[nodiscard]] const Vector<AllocatedBlock>& GetBlocks() const { return m_allocated; }
|
||||
|
||||
private:
|
||||
Vector<AllocatedBlock> m_allocated;
|
||||
uint64_t m_allocated_total = 0;
|
||||
@@ -89,6 +95,8 @@ private:
|
||||
|
||||
static PhysicalMemory* g_physical_memory = nullptr;
|
||||
static FlexibleMemory* g_flexible_memory = nullptr;
|
||||
static callback_func_t g_alloc_callback = nullptr;
|
||||
static callback_func_t g_free_callback = nullptr;
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(Memory)
|
||||
{
|
||||
@@ -107,6 +115,29 @@ static uint64_t get_aligned_pos(uint64_t pos, size_t align)
|
||||
return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos);
|
||||
}
|
||||
|
||||
void RegisterCallbacks(callback_func_t alloc_func, callback_func_t free_func)
|
||||
{
|
||||
EXIT_IF(g_alloc_callback != nullptr || g_free_callback != nullptr);
|
||||
EXIT_IF(alloc_func == nullptr || free_func == nullptr);
|
||||
|
||||
g_alloc_callback = alloc_func;
|
||||
g_free_callback = free_func;
|
||||
|
||||
g_physical_memory->GetMutex().Lock();
|
||||
for (const auto& b: g_physical_memory->GetBlocks())
|
||||
{
|
||||
g_alloc_callback(b.map_vaddr, b.map_size);
|
||||
}
|
||||
g_physical_memory->GetMutex().Unlock();
|
||||
|
||||
g_flexible_memory->GetMutex().Lock();
|
||||
for (const auto& b: g_flexible_memory->GetBlocks())
|
||||
{
|
||||
g_alloc_callback(b.map_vaddr, b.map_size);
|
||||
}
|
||||
g_flexible_memory->GetMutex().Unlock();
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment, uint64_t* phys_addr_out,
|
||||
int memory_type)
|
||||
{
|
||||
@@ -445,6 +476,11 @@ int32_t KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t le
|
||||
Graphics::GpuMemorySetAllocatedRange(out_addr, len);
|
||||
}
|
||||
|
||||
if (g_alloc_callback != nullptr)
|
||||
{
|
||||
g_alloc_callback(out_addr, len);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -490,6 +526,11 @@ int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len)
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, len, true);
|
||||
}
|
||||
|
||||
if (g_free_callback != nullptr)
|
||||
{
|
||||
g_free_callback(vaddr, len);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -639,6 +680,11 @@ int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len)
|
||||
Graphics::GpuMemoryFree(Graphics::WindowGetGraphicContext(), vaddr, size, true);
|
||||
}
|
||||
|
||||
if (g_free_callback != nullptr)
|
||||
{
|
||||
g_free_callback(vaddr, len);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -722,6 +768,11 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f
|
||||
Graphics::GpuMemorySetAllocatedRange(out_addr, len);
|
||||
}
|
||||
|
||||
if (g_alloc_callback != nullptr)
|
||||
{
|
||||
g_alloc_callback(out_addr, len);
|
||||
}
|
||||
|
||||
printf(FG_GREEN "\t [Ok]\n" FG_DEFAULT);
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -46,6 +46,15 @@ static void load_symbols(const String& id, Loader::RuntimeLinker* rt)
|
||||
}
|
||||
}
|
||||
|
||||
static void load_symbols_all(Loader::RuntimeLinker* rt)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
|
||||
EXIT_IF(rt == nullptr);
|
||||
|
||||
Libs::InitAll(rt->Symbols());
|
||||
}
|
||||
|
||||
static void print_system_info()
|
||||
{
|
||||
Loader::SystemInfo info = Loader::GetSystemInfo();
|
||||
@@ -212,6 +221,22 @@ KYTY_SCRIPT_FUNC(kyty_load_symbols_func)
|
||||
return 0;
|
||||
}
|
||||
|
||||
KYTY_SCRIPT_FUNC(kyty_load_symbols_all_func)
|
||||
{
|
||||
auto count = Scripts::ArgGetVarCount();
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
EXIT("invalid args\n");
|
||||
}
|
||||
|
||||
auto* rt = Core::Singleton<Loader::RuntimeLinker>::Instance();
|
||||
|
||||
load_symbols_all(rt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
KYTY_SCRIPT_FUNC(kyty_load_param_sfo_func)
|
||||
{
|
||||
auto count = Scripts::ArgGetVarCount();
|
||||
@@ -405,6 +430,7 @@ void kyty_reg()
|
||||
Scripts::RegisterFunc("kyty_load_elf", LuaFunc::kyty_load_elf_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_save_main_elf", LuaFunc::kyty_save_main_elf_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_symbols", LuaFunc::kyty_load_symbols_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_symbols_all", LuaFunc::kyty_load_symbols_all_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_param_sfo", LuaFunc::kyty_load_param_sfo_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_dbg_dump", LuaFunc::kyty_dbg_dump_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_execute", LuaFunc::kyty_execute_func, LuaFunc::kyty_help);
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
#include "Kyty/Sys/SysDbg.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Kernel/Memory.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/Loader/SymbolDatabase.h"
|
||||
#include "Emulator/Loader/VirtualMemory.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs {
|
||||
|
||||
LIB_VERSION("DbgAddressSanitizer", 1, "DbgAddressSanitizer", 1, 1);
|
||||
|
||||
namespace DbgAddressSanitizer {
|
||||
|
||||
struct SourceLocation
|
||||
{
|
||||
const char* filename;
|
||||
int line_no;
|
||||
int column_no;
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
uintptr_t beg;
|
||||
uintptr_t size;
|
||||
uintptr_t size_with_redzone;
|
||||
const char* name;
|
||||
const char* module_name;
|
||||
uintptr_t has_dynamic_init;
|
||||
SourceLocation* location;
|
||||
uintptr_t odr_indicator;
|
||||
};
|
||||
|
||||
struct Shadow
|
||||
{
|
||||
uintptr_t start = 0;
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
struct AsanContext
|
||||
{
|
||||
Core::Mutex mutex;
|
||||
Vector<Shadow> shadows;
|
||||
};
|
||||
|
||||
static uint32_t g_fake_stack = 0;
|
||||
static AsanContext* g_ctx = nullptr;
|
||||
|
||||
static void AllocShadow(uintptr_t min_addr, uintptr_t max_addr)
|
||||
{
|
||||
EXIT_IF(g_ctx == nullptr);
|
||||
|
||||
Core::LockGuard lock(g_ctx->mutex);
|
||||
|
||||
static const uintptr_t page_size = 0x10000ull;
|
||||
|
||||
auto min_shadow = ((min_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
auto max_shadow = ((max_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
|
||||
auto size = max_shadow - min_shadow + page_size;
|
||||
|
||||
printf("\t shadow = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(min_shadow));
|
||||
printf("\t size = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(size));
|
||||
|
||||
for (uintptr_t page = min_shadow; page <= max_shadow; page += page_size)
|
||||
{
|
||||
if (auto index = g_ctx->shadows.Find(page, [](auto& s, auto p) { return s.start == p; }); g_ctx->shadows.IndexValid(index))
|
||||
{
|
||||
g_ctx->shadows[index].count++;
|
||||
} else
|
||||
{
|
||||
if (!Loader::VirtualMemory::AllocFixed(page, page_size, Loader::VirtualMemory::Mode::ReadWrite))
|
||||
{
|
||||
EXIT("can't allocate shadow memory\n");
|
||||
}
|
||||
|
||||
Shadow s;
|
||||
s.start = page;
|
||||
s.count = 1;
|
||||
g_ctx->shadows.Add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FreeShadow(uintptr_t min_addr, uintptr_t max_addr)
|
||||
{
|
||||
EXIT_IF(g_ctx == nullptr);
|
||||
|
||||
Core::LockGuard lock(g_ctx->mutex);
|
||||
|
||||
static const uintptr_t page_size = 0x10000ull;
|
||||
|
||||
auto min_shadow = ((min_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
auto max_shadow = ((max_addr >> 3u) + 0x10000000000ull) & ~(page_size - 1);
|
||||
|
||||
auto size = max_shadow - min_shadow + page_size;
|
||||
|
||||
printf("\t shadow = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(min_shadow));
|
||||
printf("\t size = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(size));
|
||||
|
||||
for (uintptr_t page = min_shadow; page <= max_shadow; page += page_size)
|
||||
{
|
||||
if (auto index = g_ctx->shadows.Find(page, [](auto& s, auto p) { return s.start == p; }); g_ctx->shadows.IndexValid(index))
|
||||
{
|
||||
g_ctx->shadows[index].count--;
|
||||
|
||||
if (g_ctx->shadows[index].count <= 0)
|
||||
{
|
||||
if (!Loader::VirtualMemory::Free(page))
|
||||
{
|
||||
EXIT("can't free shadow memory\n");
|
||||
}
|
||||
|
||||
g_ctx->shadows.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void KernelAlloc(uintptr_t addr, size_t size)
|
||||
{
|
||||
AllocShadow(addr, addr + size - 1);
|
||||
}
|
||||
|
||||
static void KernelFree(uintptr_t addr, size_t size)
|
||||
{
|
||||
FreeShadow(addr, addr + size - 1);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_init()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(g_ctx != nullptr);
|
||||
|
||||
g_ctx = new AsanContext;
|
||||
|
||||
sys_dbg_stack_info_t s {};
|
||||
sys_stack_usage(s);
|
||||
|
||||
AllocShadow(s.reserved_addr, reinterpret_cast<uintptr_t>(&s));
|
||||
|
||||
LibKernel::Memory::RegisterCallbacks(KernelAlloc, KernelFree);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_version_mismatch_check_v8()
|
||||
{
|
||||
PRINT_NAME();
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_register_elf_globals(uintptr_t* flag, Global* start, Global* stop)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t flag = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(flag));
|
||||
printf("\t start = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(start));
|
||||
printf("\t stop = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(stop));
|
||||
|
||||
if (flag == nullptr || start == nullptr || stop == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (*flag != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto num = stop - start;
|
||||
|
||||
if (num != 0)
|
||||
{
|
||||
uintptr_t min_addr = UINTPTR_MAX;
|
||||
uintptr_t max_addr = 0;
|
||||
|
||||
for (ptrdiff_t i = 0; i < num; i++)
|
||||
{
|
||||
auto* g = start + i;
|
||||
|
||||
printf("asan global:\n");
|
||||
printf("\t beg = %016" PRIx64 "\n", static_cast<uint64_t>(g->beg));
|
||||
printf("\t size = %016" PRIx64 "\n", static_cast<uint64_t>(g->size));
|
||||
printf("\t size_with_redzone = %016" PRIx64 "\n", static_cast<uint64_t>(g->size_with_redzone));
|
||||
printf("\t name = %s\n", g->name);
|
||||
printf("\t module_name = %s\n", g->module_name);
|
||||
printf("\t has_dynamic_init = %" PRIu64 "\n", static_cast<uint64_t>(g->has_dynamic_init));
|
||||
printf("\t odr_indicator = %016" PRIx64 "\n", static_cast<uint64_t>(g->odr_indicator));
|
||||
if (g->location != nullptr)
|
||||
{
|
||||
printf("\t location = %s:%d\n", g->location->filename, g->location->line_no);
|
||||
}
|
||||
|
||||
min_addr = std::min(g->beg, min_addr);
|
||||
max_addr = std::max(g->beg + g->size_with_redzone - 1, max_addr);
|
||||
}
|
||||
|
||||
AllocShadow(min_addr, max_addr);
|
||||
}
|
||||
|
||||
*flag = 0;
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_before_dynamic_init(const char* module_name)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t name = %s\n", module_name);
|
||||
}
|
||||
|
||||
static void KYTY_SYSV_ABI asan_after_dynamic_init()
|
||||
{
|
||||
PRINT_NAME();
|
||||
}
|
||||
|
||||
static void* KYTY_SYSV_ABI asan_memcpy(void* dst, const void* src, size_t size)
|
||||
{
|
||||
return std::memcpy(dst, src, size);
|
||||
}
|
||||
|
||||
static void* KYTY_SYSV_ABI asan_memset(void* dst, int ch, size_t size)
|
||||
{
|
||||
return std::memset(dst, ch, size);
|
||||
}
|
||||
|
||||
} // namespace DbgAddressSanitizer
|
||||
|
||||
LIB_DEFINE(InitDbgAddressSanitizer_1)
|
||||
{
|
||||
LIB_OBJECT("OmecxEgrhCs", &DbgAddressSanitizer::g_fake_stack);
|
||||
|
||||
LIB_FUNC("xLoVJKHvRMU", DbgAddressSanitizer::asan_init);
|
||||
LIB_FUNC("GY2I-Okc7q0", DbgAddressSanitizer::asan_version_mismatch_check_v8);
|
||||
LIB_FUNC("W+2HQAGdPuU", DbgAddressSanitizer::asan_register_elf_globals);
|
||||
LIB_FUNC("G9xSYlaNv+Y", DbgAddressSanitizer::asan_before_dynamic_init);
|
||||
LIB_FUNC("z5Gy5T3tptE", DbgAddressSanitizer::asan_after_dynamic_init);
|
||||
LIB_FUNC("g+Neom2EHO8", DbgAddressSanitizer::asan_memcpy);
|
||||
LIB_FUNC("q-hZf47nHhQ", DbgAddressSanitizer::asan_memset);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
@@ -85,6 +85,7 @@ LIB_DEFINE(InitGraphicsDriver_1)
|
||||
LIB_FUNC("wr23dPKyWc0", Gen5::GraphicsCbReleaseMem);
|
||||
LIB_FUNC("TRO721eVt4g", Gen5::GraphicsDcbResetQueue);
|
||||
LIB_FUNC("MWiElSNE8j8", Gen5::GraphicsDcbWaitUntilSafeForRendering);
|
||||
LIB_FUNC("pFLArOT53+w", Gen5::GraphicsDcbSetShRegisterDirect);
|
||||
LIB_FUNC("ZvwO9euwYzc", Gen5::GraphicsDcbSetCxRegistersIndirect);
|
||||
LIB_FUNC("-HOOCn0JY48", Gen5::GraphicsDcbSetShRegistersIndirect);
|
||||
LIB_FUNC("hvUfkUIQcOE", Gen5::GraphicsDcbSetUcRegistersIndirect);
|
||||
|
||||
@@ -243,11 +243,16 @@ static void KYTY_SYSV_ABI KernelRtldSetApplicationHeapAPI(void* api[])
|
||||
[[maybe_unused]] auto* heap_posix_memalign = api[6];
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
static int64_t KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(d < 0 || d > 2);
|
||||
EXIT_NOT_IMPLEMENTED(d < 0);
|
||||
|
||||
if (d > 2)
|
||||
{
|
||||
return POSIX_N_CALL(FileSystem::KernelWrite(d, str, size));
|
||||
}
|
||||
|
||||
int size_int = static_cast<int>(size);
|
||||
|
||||
@@ -256,6 +261,18 @@ static int KYTY_SYSV_ABI write(int d, const char* str, int64_t size)
|
||||
return size_int;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI open(const char* path, int flags, int mode)
|
||||
{
|
||||
return POSIX_N_CALL(FileSystem::KernelOpen(path, flags, mode));
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI close(int d)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(d <= 2);
|
||||
|
||||
return POSIX_CALL(FileSystem::KernelClose(d));
|
||||
}
|
||||
|
||||
static int64_t KYTY_SYSV_ABI read(int d, void* buf, uint64_t nbytes)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
@@ -623,6 +640,7 @@ LIB_DEFINE(InitLibKernel_1)
|
||||
LIB_OBJECT("djxxOmW6-aw", &LibKernel::g_progname);
|
||||
|
||||
LIB_FUNC("1jfXLRVzisc", LibKernel::KernelUsleep);
|
||||
LIB_FUNC("6c3rCVE-fTU", LibKernel::open);
|
||||
LIB_FUNC("6xVpy0Fdq+I", LibKernel::sigprocmask);
|
||||
LIB_FUNC("6Z83sYWFlA8", LibKernel::exit);
|
||||
LIB_FUNC("8OnWXlgQlvo", LibKernel::KernelRtldThreadAtexitDecrement);
|
||||
@@ -636,6 +654,7 @@ LIB_DEFINE(InitLibKernel_1)
|
||||
LIB_FUNC("FxVZqBAA7ks", LibKernel::write);
|
||||
LIB_FUNC("kbw4UHHSYy0", LibKernel::pthread_cxa_finalize);
|
||||
LIB_FUNC("lLMT9vJAck0", LibKernel::clock_gettime);
|
||||
LIB_FUNC("NNtFaKJbPt0", LibKernel::close);
|
||||
LIB_FUNC("OMDRKKAZ8I4", LibKernel::KernelDebugRaiseException);
|
||||
LIB_FUNC("Ou3iL1abvng", LibKernel::stack_chk_fail);
|
||||
LIB_FUNC("p5EcQeEeJAE", LibKernel::KernelRtldSetApplicationHeapAPI);
|
||||
|
||||
@@ -10,6 +10,7 @@ LIB_DEFINE(InitLibcInternal_1);
|
||||
|
||||
LIB_DEFINE(InitAppContent_1);
|
||||
LIB_DEFINE(InitAudio_1);
|
||||
LIB_DEFINE(InitDbgAddressSanitizer_1);
|
||||
LIB_DEFINE(InitDebug_1);
|
||||
LIB_DEFINE(InitDialog_1);
|
||||
LIB_DEFINE(InitDiscMap_1);
|
||||
@@ -26,9 +27,10 @@ LIB_DEFINE(InitVideoOut_1);
|
||||
|
||||
bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
{
|
||||
LIB_CHECK(U"libAudio_1", InitAudio_1);
|
||||
LIB_CHECK(U"libAppContent_1", InitAppContent_1);
|
||||
LIB_CHECK(U"libAudio_1", InitAudio_1);
|
||||
LIB_CHECK(U"libc_internal_1", LibcInternal::InitLibcInternal_1);
|
||||
LIB_CHECK(U"libDbgAddressSanitizer_1", InitDbgAddressSanitizer_1);
|
||||
LIB_CHECK(U"libDebug_1", InitDebug_1);
|
||||
LIB_CHECK(U"libDialog_1", InitDialog_1);
|
||||
LIB_CHECK(U"libDiscMap_1", InitDiscMap_1);
|
||||
@@ -46,6 +48,27 @@ bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
return false;
|
||||
}
|
||||
|
||||
void InitAll(Loader::SymbolDatabase* s)
|
||||
{
|
||||
LIB_LOAD(InitAudio_1);
|
||||
LIB_LOAD(InitAppContent_1);
|
||||
LIB_LOAD(LibcInternal::InitLibcInternal_1);
|
||||
LIB_LOAD(InitDbgAddressSanitizer_1);
|
||||
LIB_LOAD(InitDebug_1);
|
||||
LIB_LOAD(InitDialog_1);
|
||||
LIB_LOAD(InitDiscMap_1);
|
||||
LIB_LOAD(InitGraphicsDriver_1);
|
||||
LIB_LOAD(InitLibKernel_1);
|
||||
LIB_LOAD(InitNet_1);
|
||||
LIB_LOAD(InitPad_1);
|
||||
LIB_LOAD(InitPlayGo_1);
|
||||
LIB_LOAD(InitSaveData_1);
|
||||
LIB_LOAD(InitSysmodule_1);
|
||||
LIB_LOAD(InitSystemService_1);
|
||||
LIB_LOAD(InitUserService_1);
|
||||
LIB_LOAD(InitVideoOut_1);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Sys/SysDbg.h"
|
||||
|
||||
#include "Emulator/Config.h"
|
||||
#include "Emulator/Graphics/Objects/GpuMemory.h"
|
||||
#include "Emulator/Kernel/Pthread.h"
|
||||
#include "Emulator/Loader/Elf.h"
|
||||
@@ -211,13 +212,16 @@ static void kyty_exception_handler(const VirtualMemory::ExceptionHandler::Except
|
||||
return;
|
||||
}
|
||||
|
||||
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(info->rbp);
|
||||
if (info->rbp != 0)
|
||||
{
|
||||
Core::Singleton<Loader::RuntimeLinker>::Instance()->StackTrace(info->rbp);
|
||||
}
|
||||
|
||||
EXIT("Access violation: %s [%016" PRIx64 "] %s\n", Core::EnumName(info->access_violation_type).C_Str(),
|
||||
info->access_violation_vaddr, (info->access_violation_vaddr == g_invalid_memory ? "(Unpatched object)" : ""));
|
||||
}
|
||||
|
||||
EXIT("Unknown exception!!!");
|
||||
EXIT("Unknown exception!!! (%08" PRIx32 ")", info->exception_win_code);
|
||||
}
|
||||
|
||||
static void encode_id_64(uint16_t in_id, String* out_id)
|
||||
@@ -1105,6 +1109,7 @@ static uint64_t calc_base_size(const Elf64_Ehdr* ehdr, const Elf64_Phdr* phdr)
|
||||
return base_size;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RuntimeLinker::LoadProgramToMemory(Program* program)
|
||||
{
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
@@ -1122,6 +1127,11 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
||||
|
||||
EXIT_IF(phdr == nullptr || ehdr == nullptr);
|
||||
|
||||
if (is_next_gen && !is_shared)
|
||||
{
|
||||
Config::SetNextGen(true);
|
||||
}
|
||||
|
||||
program->base_size = calc_base_size(ehdr, phdr);
|
||||
program->base_size_aligned = (program->base_size & ~(static_cast<uint64_t>(0x1000) - 1)) + 0x1000;
|
||||
|
||||
@@ -1163,7 +1173,7 @@ void RuntimeLinker::LoadProgramToMemory(Program* program)
|
||||
SYSTEM_RESERVED,
|
||||
kyty_exception_handler);
|
||||
|
||||
if (Libs::Graphics::GpuMemoryWatcherEnabled())
|
||||
// if (Libs::Graphics::GpuMemoryWatcherEnabled())
|
||||
{
|
||||
VirtualMemory::ExceptionHandler::InstallVectored(kyty_exception_handler);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,8 @@ public:
|
||||
info.access_violation_vaddr = exception_record->ExceptionInformation[1];
|
||||
}
|
||||
|
||||
info.rbp = dispatcher_context->ContextRecord->Rbp;
|
||||
info.rbp = dispatcher_context->ContextRecord->Rbp;
|
||||
info.exception_win_code = exception_record->ExceptionCode;
|
||||
|
||||
auto* p = *static_cast<ExceptionHandlerPrivate**>(dispatcher_context->HandlerData);
|
||||
p->func(&info);
|
||||
@@ -205,6 +206,19 @@ static LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS exception)
|
||||
|
||||
info.exception_address = reinterpret_cast<uint64_t>(exception_record->ExceptionAddress);
|
||||
|
||||
// printf("exception_record->ExceptionCode = %u\n", static_cast<uint32_t>(exception_record->ExceptionCode));
|
||||
|
||||
if (exception_record->ExceptionCode == DBG_PRINTEXCEPTION_C || exception_record->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C)
|
||||
{
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
if (exception_record->ExceptionCode == 0x406D1388)
|
||||
{
|
||||
// Set a thread name
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
info.type = ExceptionHandler::ExceptionType::AccessViolation;
|
||||
@@ -218,6 +232,9 @@ static LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS exception)
|
||||
info.access_violation_vaddr = exception_record->ExceptionInformation[1];
|
||||
}
|
||||
|
||||
info.rbp = exception->ContextRecord->Rbp;
|
||||
info.exception_win_code = exception_record->ExceptionCode;
|
||||
|
||||
ExceptionHandlerPrivate::g_vec_func(&info);
|
||||
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
|
||||
Reference in New Issue
Block a user