guest_gpu: remove stale PS4/GCN era gpu registers

This commit is contained in:
nmzik
2026-08-31 20:58:35 +04:00
parent 39a34fa343
commit 1df06e230d
12 changed files with 421 additions and 1222 deletions
@@ -204,13 +204,11 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
if (texture_tile &&
(!TileGetTextureBlockLayout(transfer_format, rt.attrib3.tile_mode, volume,
texture_tile_layout) ||
rt.pitch.pitch_div8_minus1 != 0 ||
(rt.base.addr & (texture_tile_layout.block.block_size - 1u)) != 0 ||
rt.info.fmask_compression_enable || rt.info.fmask_data_compression_disable ||
rt.info.fmask_one_frag_mode || rt.info.cmask_fast_clear_enable ||
rt.info.dcc_compression_enable || rt.info.cmask_is_linear != 0 ||
rt.info.cmask_addr_type != 0 || rt.info.alt_tile_mode || rt.cmask.addr != 0 ||
rt.fmask.addr != 0 || rt.dcc_addr.addr != 0 || rt.dcc.data_write_on_dcc_clear_to_reg)) {
rt.info.dcc_compression_enable || rt.cmask.addr != 0 || rt.fmask.addr != 0 ||
rt.dcc_addr.addr != 0 || rt.dcc.data_write_on_dcc_clear_to_reg)) {
EXIT("unsupported texture-tiled render target: addr=0x%016" PRIx64 " tile=%u"
" dimension=%u depth=%u levels=%u layer=%u/%u samples=%u fragments=%u bpe=%u"
" cmask=0x%016" PRIx64 " fmask=0x%016" PRIx64 " dcc=0x%016" PRIx64 "\n",
@@ -226,9 +224,7 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
" layer=%u/%u\n",
rt.attrib3.dimension, rt.attrib3.depth, view.base_layer, view.image_layers);
}
if (rt.pitch.pitch_div8_minus1 != 0) {
pitch = (rt.pitch.pitch_div8_minus1 + 1u) << 3u;
} else if (tile) {
if (tile) {
if (volume) {
pitch = TileGetTexturePitch(transfer_format, width, rt.attrib3.tile_mode);
} else if (texture_tile) {
@@ -294,12 +290,6 @@ void RenderExecutor::ResolveRenderColorTarget(uint64_t submit_id, CommandBuffer&
mip_sizes[0] = {static_cast<uint32_t>(size), 0, 0, 0, 0, 0};
mip_padded[0] = {pitch, height};
}
if (rt.slice.slice_div64_minus1 != 0 &&
(static_cast<uint64_t>(rt.slice.slice_div64_minus1) + 1u) * 64u != size) {
EXIT("render-target slice span mismatch: encoded=0x%016" PRIx64 " derived=0x%016" PRIx64
"\n",
(static_cast<uint64_t>(rt.slice.slice_div64_minus1) + 1u) * 64u, size);
}
if (size == 0 || (!volume && size > UINT64_MAX / view.image_layers)) {
EXIT("render-target memory footprint is invalid\n");
}
+32 -150
View File
@@ -97,17 +97,11 @@ void sh_print(const char* func, const HW::Shader& /*uc*/) {
std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt) {
std::vector<std::string> dst;
dst.reserve(53);
dst.reserve(40);
dst.push_back(fmt::format("{}\n", func));
dst.push_back(fmt::format("\t base.addr = 0x{:016x}\n", rt.base.addr));
dst.push_back(
fmt::format("\t pitch.pitch_div8_minus1 = 0x{:08x}\n", rt.pitch.pitch_div8_minus1));
dst.push_back(fmt::format("\t pitch.fmask_pitch_div8_minus1 = 0x{:08x}\n",
rt.pitch.fmask_pitch_div8_minus1));
dst.push_back(fmt::format("\t slice.slice_div64_minus1 = 0x{:08x}\n",
rt.slice.slice_div64_minus1));
dst.push_back(fmt::format("\t view.base_array_slice_index = 0x{:08x}\n",
rt.view.base_array_slice_index));
dst.push_back(fmt::format("\t view.last_array_slice_index = 0x{:08x}\n",
@@ -128,12 +122,6 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
rt.info.cmask_fast_clear_enable ? "true" : "false"));
dst.push_back(fmt::format("\t info.dcc_compression_enable = {}\n",
rt.info.dcc_compression_enable ? "true" : "false"));
dst.push_back(
fmt::format("\t info.cmask_is_linear = 0x{:08x}\n", rt.info.cmask_is_linear));
dst.push_back(
fmt::format("\t info.cmask_addr_type = 0x{:08x}\n", rt.info.cmask_addr_type));
dst.push_back(fmt::format("\t info.alt_tile_mode = {}\n",
rt.info.alt_tile_mode ? "true" : "false"));
dst.push_back(fmt::format("\t info.format = 0x{:08x}\n",
static_cast<uint32_t>(rt.info.format)));
dst.push_back(fmt::format("\t info.channel_type = 0x{:08x}\n",
@@ -148,10 +136,6 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
rt.info.round_mode ? "true" : "false"));
dst.push_back(fmt::format("\t attrib.force_dest_alpha_to_one = {}\n",
rt.attrib.force_dest_alpha_to_one ? "true" : "false"));
dst.push_back(fmt::format("\t attrib.tile_mode = 0x{:08x}\n",
static_cast<uint32_t>(rt.attrib.tile_mode)));
dst.push_back(fmt::format("\t attrib.fmask_tile_mode = 0x{:08x}\n",
static_cast<uint32_t>(rt.attrib.fmask_tile_mode)));
dst.push_back(
fmt::format("\t attrib.num_samples = 0x{:08x}\n", rt.attrib.num_samples));
dst.push_back(
@@ -166,42 +150,32 @@ std::vector<std::string> rt_print(const char* func, const HW::RenderTarget& rt)
static_cast<uint32_t>(rt.attrib3.tile_mode)));
dst.push_back(
fmt::format("\t attrib3.dimension = 0x{:08x}\n", rt.attrib3.dimension));
dst.push_back(fmt::format("\t attrib3.cmask_pipe_aligned = {}\n",
rt.attrib3.cmask_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.dcc_pipe_aligned = {}\n",
rt.attrib3.dcc_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.metadata_pipe_aligned = {}\n",
rt.attrib3.metadata_pipe_aligned ? "true" : "false"));
dst.push_back(fmt::format("\t attrib3.write_vrs_rate_hint_to_cmask = {}\n",
rt.attrib3.write_vrs_rate_hint_to_cmask ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.max_uncompressed_block_size = 0x{:08x}\n",
rt.dcc.max_uncompressed_block_size));
dst.push_back(fmt::format("\t dcc.max_compressed_block_size = 0x{:08x}\n",
rt.dcc.max_compressed_block_size));
dst.push_back(fmt::format("\t dcc.min_compressed_block_size = 0x{:08x}\n",
rt.dcc.min_compressed_block_size));
dst.push_back(
fmt::format("\t dcc.color_transform = 0x{:08x}\n", rt.dcc.color_transform));
dst.push_back(fmt::format("\t dcc.overwrite_combiner_disable = {}\n",
rt.dcc.overwrite_combiner_disable ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_64b_blocks = {}\n",
rt.dcc.independent_64b_blocks ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_128b_blocks = {}\n",
rt.dcc.independent_128b_blocks ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.independent_block_size = 0x{:02x}\n",
static_cast<uint8_t>(rt.dcc.independent_block_size)));
dst.push_back(fmt::format("\t data_write_on_dcc_clear_to_reg = {}\n",
rt.dcc.data_write_on_dcc_clear_to_reg ? "true" : "false"));
dst.push_back(fmt::format("\t dcc.dcc_clear_key_enable = {}\n",
rt.dcc.dcc_clear_key_enable ? "true" : "false"));
dst.push_back(fmt::format("\t cmask.addr = 0x{:016x}\n", rt.cmask.addr));
dst.push_back(fmt::format("\t cmask_slice.slice_minus1 = 0x{:08x}\n",
rt.cmask_slice.slice_minus1));
dst.push_back(fmt::format("\t fmask.addr = 0x{:016x}\n", rt.fmask.addr));
dst.push_back(fmt::format("\t fmask_slice.slice_minus1 = 0x{:08x}\n",
rt.fmask_slice.slice_minus1));
dst.push_back(
fmt::format("\t clear_word0.word0 = 0x{:08x}\n", rt.clear_word0.word0));
dst.push_back(
fmt::format("\t clear_word1.word1 = 0x{:08x}\n", rt.clear_word1.word1));
dst.push_back(
fmt::format("\t dcc_addr.addr = 0x{:016x}\n", rt.dcc_addr.addr));
dst.push_back(fmt::format("\t size.width = 0x{:08x}\n", rt.size.width));
dst.push_back(fmt::format("\t size.height = 0x{:08x}\n", rt.size.height));
return dst;
}
@@ -231,13 +205,8 @@ static bool RenderIsColorDimension(uint32_t dimension) {
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void RtCheck(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.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 > rt.view.last_array_slice_index);
if (rt.view.base_array_slice_index != 0x00000000 ||
rt.view.last_array_slice_index != 0x00000000) {
@@ -281,22 +250,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
if (rt.info.cmask_is_linear != 0x00000000 || rt.info.cmask_addr_type != 0x00000000) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: ignoring PS5 CMASK metadata fields "
"is_linear=%u addr_type=%u\n",
rt.info.cmask_is_linear, rt.info.cmask_addr_type);
logged = true;
}
}
if (rt.info.alt_tile_mode) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: ignoring alternate tile mode flag\n");
logged = true;
}
}
if (rt.info.blend_bypass) {
static bool logged = false;
if (!logged) {
@@ -323,8 +276,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
// EXIT_NOT_IMPLEMENTED(rt.tile_mode != 0x0000000a);
// EXIT_NOT_IMPLEMENTED(rt.fmask_tile_mode != 0x0000000a);
if (rt.attrib.num_samples != 0x00000000 || rt.attrib.num_fragments != 0x00000000) {
static bool logged = false;
if (!logged) {
@@ -359,34 +310,22 @@ static void RtCheck(const HW::RenderTarget& rt) {
if (!RenderIsColorDimension(rt.attrib3.dimension)) {
EXIT("unknown PS5 render-target dimension: 0x%08" PRIx32 "\n", rt.attrib3.dimension);
}
if (!rt.attrib3.cmask_pipe_aligned) {
if (!rt.attrib3.metadata_pipe_aligned) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: accepting unaligned PS5 CMASK pipe flag\n");
logged = true;
}
}
if (!rt.attrib3.dcc_pipe_aligned) {
static bool logged = false;
if (!logged) {
LOGF("RenderTarget: temporary: accepting unaligned PS5 DCC pipe flag\n");
LOGF("RenderTarget: temporary: accepting unaligned PS5 metadata pipe flag\n");
logged = true;
}
}
EXIT_NOT_IMPLEMENTED(rt.attrib3.write_vrs_rate_hint_to_cmask);
// 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);
// EXIT_NOT_IMPLEMENTED(rt.dcc.color_transform != 0x00000000);
EXIT_NOT_IMPLEMENTED(rt.dcc.overwrite_combiner_disable != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.force_independent_blocks != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.independent_128b_blocks != false);
// EXIT_NOT_IMPLEMENTED(rt.dcc.data_write_on_dcc_clear_to_reg != false);
EXIT_NOT_IMPLEMENTED(rt.dcc.dcc_clear_key_enable != false);
if (rt.cmask.addr != 0x0000000000000000 || rt.cmask_slice.slice_minus1 != 0x00000000 ||
rt.fmask.addr != 0x0000000000000000 ||
(rt.fmask_slice.slice_minus1 != 0x00000000 &&
rt.fmask_slice.slice_minus1 != rt.slice.slice_div64_minus1) ||
if (rt.cmask.addr != 0x0000000000000000 || rt.fmask.addr != 0x0000000000000000 ||
rt.dcc_addr.addr != 0x0000000000000000) {
static bool logged = false;
if (!logged) {
@@ -396,9 +335,6 @@ static void RtCheck(const HW::RenderTarget& rt) {
logged = true;
}
}
EXIT_NOT_IMPLEMENTED(rt.size.width != 0);
EXIT_NOT_IMPLEMENTED(rt.size.height != 0);
}
}
@@ -418,37 +354,20 @@ static void ZPrint(const char* func, const HW::DepthRenderTarget& z) {
"\t stencil_info.htile_stencil_disabled = %s\n"
"\t stencil_info.expclear_enabled = %s\n"
"\t stencil_info.partially_resident = %s\n"
"\t depth_info.addr5_swizzle_mask = 0x%08" PRIx32 "\n"
"\t depth_info.array_mode = 0x%08" PRIx32 "\n"
"\t depth_info.pipe_config = 0x%08" PRIx32 "\n"
"\t depth_info.bank_width = 0x%08" PRIx32 "\n"
"\t depth_info.bank_height = 0x%08" PRIx32 "\n"
"\t depth_info.macro_tile_aspect = 0x%08" PRIx32 "\n"
"\t depth_info.num_banks = 0x%08" PRIx32 "\n"
"\t depth_view.slice_start = 0x%08" PRIx32 "\n"
"\t depth_view.slice_max = 0x%08" PRIx32 "\n"
"\t depth_view.current_mip_level = 0x%02" PRIx8 "\n"
"\t depth_view.depth_write_disable = %s\n"
"\t depth_view.stencil_write_disable = %s\n"
"\t htile_surface.linear = 0x%08" PRIx32 "\n"
"\t htile_surface.full_cache = 0x%08" PRIx32 "\n"
"\t htile_surface.htile_uses_preload_win = 0x%08" PRIx32 "\n"
"\t htile_surface.preload = 0x%08" PRIx32 "\n"
"\t htile_surface.prefetch_width = 0x%08" PRIx32 "\n"
"\t htile_surface.prefetch_height = 0x%08" PRIx32 "\n"
"\t htile_surface.dst_outside_zero_to_one = 0x%08" PRIx32 "\n"
"\t z_read_base_addr = 0x%016" PRIx64 "\n"
"\t stencil_read_base_addr = 0x%016" PRIx64 "\n"
"\t z_write_base_addr = 0x%016" PRIx64 "\n"
"\t stencil_write_base_addr = 0x%016" PRIx64 "\n"
"\t pitch_div8_minus1 = 0x%08" PRIx32 "\n"
"\t height_div8_minus1 = 0x%08" PRIx32 "\n"
"\t slice_div64_minus1 = 0x%08" PRIx32 "\n"
"\t htile_data_base_addr = 0x%016" PRIx64 "\n"
"\t width = 0x%08" PRIx32 "\n"
"\t height = 0x%08" PRIx32 "\n"
"\t shading_rate_encoding = 0x%02" PRIx8 "\n"
"\t size.x_max = 0x%04" PRIx16 "\n"
"\t size.y_max = 0x%04" PRIx16 "\n",
"\t size.y_max = 0x%04" PRIx16 "\n"
"\t size.valid = %s\n",
static_cast<uint32_t>(z.z_info.format), z.z_info.num_samples,
static_cast<uint32_t>(z.z_info.texture_compatibility),
z.z_info.htile_acceleration ? "true" : "false",
@@ -459,30 +378,27 @@ static void ZPrint(const char* func, const HW::DepthRenderTarget& z) {
static_cast<uint32_t>(z.stencil_info.texture_compatibility),
z.stencil_info.htile_stencil_disabled ? "true" : "false",
z.stencil_info.expclear_enabled ? "true" : "false",
z.stencil_info.partially_resident ? "true" : "false", z.depth_info.addr5_swizzle_mask,
z.depth_info.array_mode, z.depth_info.pipe_config, z.depth_info.bank_width,
z.depth_info.bank_height, z.depth_info.macro_tile_aspect, z.depth_info.num_banks,
z.depth_view.slice_start, z.depth_view.slice_max, z.depth_view.current_mip_level,
z.stencil_info.partially_resident ? "true" : "false", z.depth_view.slice_start,
z.depth_view.slice_max, z.depth_view.current_mip_level,
z.depth_view.depth_write_disable ? "true" : "false",
z.depth_view.stencil_write_disable ? "true" : "false", z.htile_surface.linear,
z.htile_surface.full_cache, z.htile_surface.htile_uses_preload_win,
z.htile_surface.preload, z.htile_surface.prefetch_width, z.htile_surface.prefetch_height,
z.htile_surface.dst_outside_zero_to_one, z.z_read_base_addr, z.stencil_read_base_addr,
z.z_write_base_addr, z.stencil_write_base_addr, z.pitch_div8_minus1, z.height_div8_minus1,
z.slice_div64_minus1, z.htile_data_base_addr, z.width, z.height, z.size.x_max,
z.size.y_max);
z.depth_view.stencil_write_disable ? "true" : "false", z.z_read_base_addr,
z.stencil_read_base_addr, z.z_write_base_addr, z.stencil_write_base_addr,
z.htile_data_base_addr, z.shading_rate_encoding, z.size.x_max, z.size.y_max,
z.size.valid ? "true" : "false");
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
const HW::RenderControl& rc) {
const bool depth_active =
dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable || rc.depth_clear_enable;
const bool stencil_active = dc.stencil_enable || rc.stencil_clear_enable;
const bool depth_active = dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable ||
rc.depth_clear_enable || rc.copy_depth_to_color;
const bool stencil_active =
dc.stencil_enable || rc.stencil_clear_enable || rc.copy_stencil_to_color;
if (!depth_active && !stencil_active) {
return;
}
EXIT_NOT_IMPLEMENTED(rc.copy_depth_to_color || rc.copy_stencil_to_color);
EXIT_NOT_IMPLEMENTED(!z.z_info.HasValidTextureCompatibility());
EXIT_NOT_IMPLEMENTED(!z.stencil_info.HasValidTextureCompatibility());
if (z.z_info.format == Prospero::DepthFormat::kInvalid) {
@@ -519,21 +435,7 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
if (z.z_info.format != Prospero::DepthFormat::kInvalid ||
z.stencil_info.format != Prospero::StencilFormat::kInvalid) {
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);
EXIT_NOT_IMPLEMENTED(z.shading_rate_encoding != 0);
if (z.depth_view.current_mip_level != 0x00000000) {
static std::atomic<uint32_t> log_count {0};
@@ -555,23 +457,8 @@ static void ZCheck(const HW::DepthRenderTarget& z, const HW::DepthControl& dc,
EXIT_NOT_IMPLEMENTED(!z.depth_view.stencil_write_disable &&
z.stencil_read_base_addr != z.stencil_write_base_addr);
EXIT_NOT_IMPLEMENTED(!z.depth_view.depth_write_disable && z.z_write_base_addr == 0);
// EXIT_NOT_IMPLEMENTED(z.pitch_div8_minus1 != 0x000000ff);
// EXIT_NOT_IMPLEMENTED(z.height_div8_minus1 != 0x0000008f);
// EXIT_NOT_IMPLEMENTED(z.slice_div64_minus1 != 0x00008fff);
// 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.width != 0);
EXIT_NOT_IMPLEMENTED(z.height != 0);
if (z.size.x_max == 0 || z.size.y_max == 0) {
static std::atomic<uint32_t> log_count {0};
if (log_count.fetch_add(1) < 16) {
LOGF("DepthTarget: temporary: inferring PS5 default depth extent x_max=0x%04" PRIx16
", y_max=0x%04" PRIx16 "\n",
z.size.x_max, z.size.y_max);
}
}
EXIT_NOT_IMPLEMENTED(!z.size.valid);
}
}
@@ -754,8 +641,6 @@ static void DPrint(const char* func, const HW::DepthControl& c, const HW::Stenci
"\t backface_enable = %s\n"
"\t stencilfunc = %" PRIu8 "\n"
"\t stencilfunc_bf = %" PRIu8 "\n"
"\t color_writes_on_depth_fail_enable = %s\n"
"\t color_writes_on_depth_pass_disable = %s\n"
"\t stencil_fail = %" PRIu8 "\n"
"\t stencil_zpass = %" PRIu8 "\n"
"\t stencil_zfail = %" PRIu8 "\n"
@@ -772,12 +657,11 @@ static void DPrint(const char* func, const HW::DepthControl& c, const HW::Stenci
"\t stencil_opval_bf = %" PRIu8 "\n",
c.stencil_enable ? "true" : "false", c.z_enable ? "true" : "false",
c.z_write_enable ? "true" : "false", c.depth_bounds_enable ? "true" : "false", c.zfunc,
c.backface_enable ? "true" : "false", c.stencilfunc, c.stencilfunc_bf,
c.color_writes_on_depth_fail_enable ? "true" : "false",
c.color_writes_on_depth_pass_disable ? "true" : "false", s.stencil_fail, s.stencil_zpass,
s.stencil_zfail, s.stencil_fail_bf, s.stencil_zpass_bf, s.stencil_zfail_bf,
sm.stencil_testval, sm.stencil_mask, sm.stencil_writemask, sm.stencil_opval,
sm.stencil_testval_bf, sm.stencil_mask_bf, sm.stencil_writemask_bf, sm.stencil_opval_bf);
c.backface_enable ? "true" : "false", c.stencilfunc, c.stencilfunc_bf, s.stencil_fail,
s.stencil_zpass, s.stencil_zfail, s.stencil_fail_bf, s.stencil_zpass_bf,
s.stencil_zfail_bf, sm.stencil_testval, sm.stencil_mask, sm.stencil_writemask,
sm.stencil_opval, sm.stencil_testval_bf, sm.stencil_mask_bf, sm.stencil_writemask_bf,
sm.stencil_opval_bf);
}
static void DCheck(const HW::DepthControl& c, const HW::StencilControl& s,
@@ -789,8 +673,6 @@ static void DCheck(const HW::DepthControl& c, const HW::StencilControl& s,
// Back-face stencil state is handled separately when enabled.
// EXIT_NOT_IMPLEMENTED(c.stencilfunc != 0);
// EXIT_NOT_IMPLEMENTED(c.stencilfunc_bf != 0);
EXIT_NOT_IMPLEMENTED(c.color_writes_on_depth_fail_enable != false);
EXIT_NOT_IMPLEMENTED(c.color_writes_on_depth_pass_disable != false);
// EXIT_NOT_IMPLEMENTED(s.stencil_fail != 0);
// EXIT_NOT_IMPLEMENTED(s.stencil_zpass != 0);
// EXIT_NOT_IMPLEMENTED(s.stencil_zfail != 0);
@@ -108,9 +108,10 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
const auto& sc = hw.GetStencilControl();
const auto& sm = hw.GetStencilMask();
const bool has_stencil = z.stencil_info.format != Prospero::StencilFormat::kInvalid;
const bool depth_active =
dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable || rc.depth_clear_enable;
const bool stencil_active = has_stencil && (dc.stencil_enable || rc.stencil_clear_enable);
const bool depth_active = dc.z_enable || dc.z_write_enable || dc.depth_bounds_enable ||
rc.depth_clear_enable || rc.copy_depth_to_color;
const bool stencil_active =
has_stencil && (dc.stencil_enable || rc.stencil_clear_enable || rc.copy_stencil_to_color);
if (!depth_active && !stencil_active) {
return;
}
@@ -127,22 +128,14 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
!z.stencil_info.expclear_enabled && !z.stencil_info.partially_resident &&
z.depth_view.slice_start == 0 && z.depth_view.slice_max == 0 &&
z.depth_view.current_mip_level == 0 && !z.depth_view.depth_write_disable &&
!z.depth_view.stencil_write_disable && z.depth_info.addr5_swizzle_mask == 0 &&
z.depth_info.array_mode == 0 && z.depth_info.pipe_config == 0 &&
z.depth_info.bank_width == 0 && z.depth_info.bank_height == 0 &&
z.depth_info.macro_tile_aspect == 0 && z.depth_info.num_banks == 0 &&
z.htile_surface.linear == 0 && z.htile_surface.full_cache == 0 &&
z.htile_surface.htile_uses_preload_win == 0 && z.htile_surface.preload == 0 &&
z.htile_surface.prefetch_width == 0 && z.htile_surface.prefetch_height == 0 &&
z.htile_surface.dst_outside_zero_to_one == 0 && z.z_read_base_addr == 0 &&
z.z_write_base_addr == 0 && z.stencil_read_base_addr == 0 &&
z.stencil_write_base_addr == 0 && z.htile_data_base_addr == 0 &&
!z.depth_view.stencil_write_disable && z.z_read_base_addr == 0 && z.z_write_base_addr == 0 &&
z.stencil_read_base_addr == 0 && z.stencil_write_base_addr == 0 &&
z.htile_data_base_addr == 0 &&
// DB_DEPTH_SIZE_XY is independent state and may remain programmed after the attachment
// formats and addresses are unbound. A zero encoding is the valid 1x1 value, so its
// presence alone must not manufacture a depth attachment.
!z.z_info.htile_acceleration && !z.width_height_valid && !z.pitch_height_valid &&
z.size.x_max == 0 && z.size.y_max == 0 && z.pitch_div8_minus1 == 0 &&
z.height_div8_minus1 == 0 && z.slice_div64_minus1 == 0 && z.width == 0 && z.height == 0;
!z.z_info.htile_acceleration && z.shading_rate_encoding == 0 && z.size.x_max == 0 &&
z.size.y_max == 0;
if (attachment_unbound) {
static std::atomic_bool logged = false;
if (!logged.exchange(true, std::memory_order_relaxed)) {
@@ -165,17 +158,12 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
DepthFatal("invalid depth view: base=%u last=%u", z.depth_view.slice_start,
z.depth_view.slice_max);
}
if (rc.copy_centroid || rc.copy_sample != 0 || z.z_info.expclear_enabled ||
if (rc.copy_depth_to_color || rc.copy_stencil_to_color || rc.copy_centroid ||
rc.copy_sample != 0 || z.z_info.expclear_enabled ||
z.stencil_info.expclear_enabled || z.z_info.partially_resident ||
z.stencil_info.partially_resident || z.z_info.max_mip_level != 0 ||
z.depth_view.current_mip_level != 0 || z.depth_info.addr5_swizzle_mask != 0 ||
z.depth_info.array_mode != 0 || z.depth_info.pipe_config != 0 ||
z.depth_info.bank_width != 0 || z.depth_info.bank_height != 0 ||
z.depth_info.macro_tile_aspect != 0 || z.depth_info.num_banks != 0 ||
z.htile_surface.linear != 0 || z.htile_surface.full_cache != 0 ||
z.htile_surface.htile_uses_preload_win != 0 || z.htile_surface.preload != 0 ||
z.htile_surface.prefetch_width != 0 || z.htile_surface.prefetch_height != 0 ||
z.htile_surface.dst_outside_zero_to_one != 0 || z.z_read_base_addr == 0 ||
z.depth_view.current_mip_level != 0 || z.shading_rate_encoding != 0 ||
z.z_read_base_addr == 0 ||
(!z.depth_view.depth_write_disable && z.z_write_base_addr != z.z_read_base_addr) ||
(z.z_read_base_addr & 0xffffu) != 0 ||
dc.zfunc > static_cast<uint8_t>(vk::CompareOp::eAlways)) {
@@ -203,18 +191,13 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
DepthFatal("HTile clear tracking supports at most 32 slices");
}
}
const bool size_xy_valid = z.size.valid;
const bool wh_valid = z.width_height_valid && z.width != 0 && z.height != 0;
if (!size_xy_valid && !wh_valid) {
if (!z.size.valid) {
DepthFatal("missing depth extent");
}
const uint32_t width = size_xy_valid ? static_cast<uint32_t>(z.size.x_max) + 1u : z.width;
const uint32_t height = size_xy_valid ? static_cast<uint32_t>(z.size.y_max) + 1u : z.height;
if (width > 16384 || height > 16384 ||
(size_xy_valid && wh_valid && (width != z.width || height != z.height)) ||
(!z.pitch_height_valid &&
(z.pitch_div8_minus1 != 0 || z.height_div8_minus1 != 0 || z.slice_div64_minus1 != 0))) {
DepthFatal("inconsistent depth extent or encoded layout");
const uint32_t width = static_cast<uint32_t>(z.size.x_max) + 1u;
const uint32_t height = static_cast<uint32_t>(z.size.y_max) + 1u;
if (width > 16384 || height > 16384) {
DepthFatal("invalid depth extent");
}
const auto* policy = FindDepthFormatPolicy(z.z_info.format);
if (policy == nullptr) {
@@ -229,11 +212,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
const auto guest_format = policy->guest_format;
const uint32_t bytes = policy->bytes_per_element;
const auto pitch = TileGetDepthPitch(width, bytes, z.z_info.num_samples);
if (z.pitch_height_valid && ((static_cast<uint64_t>(z.pitch_div8_minus1) + 1u) * 8u != pitch ||
(static_cast<uint64_t>(z.height_div8_minus1) + 1u) * 8u !=
((static_cast<uint64_t>(height) + 7u) & ~7ull))) {
DepthFatal("encoded depth pitch or height mismatch");
}
TileSizeAlign depth_size {};
TileSizeAlign stencil_size {};
TileSizeAlign htile_size {};
@@ -244,14 +222,6 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, CommandBuffer&
(has_htile != (htile_size.align == 32768 && htile_size.size != 0))) {
DepthFatal("unsupported depth/stencil/HTile footprint");
}
if (z.pitch_height_valid &&
(static_cast<uint64_t>(z.slice_div64_minus1) + 1u) * 64u != depth_size.size) {
DepthFatal("depth footprint mismatch: extent=%ux%u pitch=%u expected=0x%016" PRIx64
" align=0x%016" PRIx64 " encoded_valid=%u encoded=0x%016" PRIx64,
width, height, pitch, depth_size.size, depth_size.align,
z.pitch_height_valid ? 1u : 0u,
(static_cast<uint64_t>(z.slice_div64_minus1) + 1u) * 64u);
}
if (depth_size.size > UINT64_MAX / view.image_layers ||
stencil_size.size > UINT64_MAX / view.image_layers ||
htile_size.size > UINT64_MAX / view.image_layers) {
@@ -411,7 +411,7 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
const auto& vs = sh_ctx.GetVs();
return vs.gs_regs.chksum != 0 && ShaderAddressValid(vs.es_regs.data_addr);
return ShaderAddressValid(vs.es_regs.data_addr);
}
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
@@ -443,7 +443,6 @@ static bool ShouldSkipGeShader(const CommandBuffer& buffer) {
};
const bool ps5_ngg_vertex_path = stages == 0x02002000 && vertex_info.es_regs.data_addr != 0 &&
vertex_info.gs_regs.chksum != 0 &&
sh_regs.m_vgtGsMaxVertOut == 0x00000000 &&
is_known_gs_out_prim_type(sh_regs.m_vgtGsOutPrimType);
@@ -1450,7 +1449,7 @@ void RenderExecutor::DrawAuto(uint64_t submit_id, CommandBuffer& buffer, uint32_
if (graphics_debug_dump_enabled()) {
LOGF("DrawIndexAuto: skipping rect-list draw with no VS param exports and PS inputs: "
"ps_inputs=%u ps=0x%016" PRIx64 " es=0x%016" PRIx64 " gs=0x%016" PRIx64 "\n",
state.ps_input_info.input_num, sh_ctx.GetPs().ps_regs.chksum,
state.ps_input_info.input_num, sh_ctx.GetPs().ps_regs.data_addr,
sh_ctx.GetVs().es_regs.data_addr, sh_ctx.GetVs().gs_regs.data_addr);
}
ResetBindings();