mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
graphics: unify buffer bindings and depth target handling
This commit is contained in:
@@ -87,7 +87,7 @@ static bool UsesStencilOpValue(uint8_t fail, uint8_t pass, uint8_t depth_fail) {
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandBuffer& buffer,
|
||||
RenderDepthInfo& r) {
|
||||
RenderDepthInfo& r) {
|
||||
KYTY_PROFILER_FUNCTION();
|
||||
(void)submit_id;
|
||||
const auto& hw = buffer.GetRegisters();
|
||||
@@ -102,31 +102,34 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
if (!depth_active && !stencil_active) {
|
||||
return;
|
||||
}
|
||||
if (!z.z_info.HasValidTextureCompatibility() ||
|
||||
!z.stencil_info.HasValidTextureCompatibility()) {
|
||||
DepthFatal("invalid PS5 depth texture-compatibility encoding");
|
||||
}
|
||||
const bool attachment_unbound =
|
||||
z.z_info.format == Prospero::GpuEnumValue(Prospero::DepthFormat::kInvalid) &&
|
||||
z.stencil_info.format == Prospero::GpuEnumValue(Prospero::StencilFormat::kInvalid) &&
|
||||
z.z_info.tile_mode_index == 0 && z.z_info.num_samples == 0 &&
|
||||
z.z_info.zrange_precision <= 1 && !z.z_info.expclear_enabled &&
|
||||
!z.z_info.embedded_sample_locations && !z.z_info.partially_resident &&
|
||||
z.z_info.num_mip_levels == 0 && z.z_info.plane_compression == 0 &&
|
||||
z.stencil_info.tile_mode_index == 0 && z.stencil_info.tile_split == 0 &&
|
||||
!z.stencil_info.expclear_enabled && !z.stencil_info.texture_compatible_stencil &&
|
||||
!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.z_info.num_samples == 0 &&
|
||||
z.z_info.texture_compatibility == Prospero::TextureCompatiblePlaneCompression::kDisable &&
|
||||
!z.z_info.expclear_enabled && !z.z_info.partially_resident && z.z_info.max_mip_level == 0 &&
|
||||
z.stencil_info.texture_compatibility == Prospero::TextureCompatibleStencil::kDisable &&
|
||||
!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 &&
|
||||
// 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.tile_surface_enable && !z.width_height_valid && !z.pitch_height_valid &&
|
||||
!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;
|
||||
if (attachment_unbound) {
|
||||
@@ -138,13 +141,13 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
}
|
||||
const bool has_stencil =
|
||||
z.stencil_info.format != Prospero::GpuEnumValue(Prospero::StencilFormat::kInvalid);
|
||||
const bool has_htile = z.z_info.tile_surface_enable;
|
||||
const bool has_htile = z.z_info.htile_acceleration;
|
||||
const auto samples = render_sample_count(z.z_info.num_samples);
|
||||
if (samples == 0) {
|
||||
DepthFatal("unsupported depth fragment count: %u", z.z_info.num_samples);
|
||||
}
|
||||
const bool htile_stencil_compat = depth_htile_stencil_acceleration_compatible(
|
||||
has_stencil, has_htile, z.stencil_info.tile_stencil_disable);
|
||||
has_stencil, has_htile, z.stencil_info.htile_stencil_disabled);
|
||||
const auto view = ResolveTargetViewInfo(z.depth_view.slice_start, z.depth_view.slice_max);
|
||||
switch (view.type) {
|
||||
case TargetViewType::Image2D: break;
|
||||
@@ -155,14 +158,10 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
DepthFatal("invalid depth view: base=%u last=%u", z.depth_view.slice_start,
|
||||
z.depth_view.slice_max);
|
||||
}
|
||||
// Prospero defines the compression-disable bits as tile writeback policy. Vulkan attachments
|
||||
// expose the same logical depth/stencil values regardless of the driver's backing compression.
|
||||
if ((stencil_active && !has_stencil) || rc.resummarize_enable || rc.copy_centroid ||
|
||||
rc.copy_sample != 0 || z.z_info.expclear_enabled || z.stencil_info.expclear_enabled ||
|
||||
z.z_info.embedded_sample_locations || z.z_info.partially_resident ||
|
||||
z.stencil_info.partially_resident || z.z_info.plane_compression != 0 ||
|
||||
z.z_info.num_mip_levels != 0 || z.z_info.tile_mode_index != 0 ||
|
||||
z.z_info.zrange_precision > 1 || z.depth_view.current_mip_level != 0 ||
|
||||
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 ||
|
||||
@@ -176,27 +175,16 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
DepthFatal("unsupported depth register state");
|
||||
}
|
||||
if (has_stencil) {
|
||||
// Prospero defines Hi-Stencil as HTile-backed acceleration of the logical stencil plane.
|
||||
// Keep the plane native in Vulkan while tracking HTile separately.
|
||||
if (z.stencil_info.format != Prospero::GpuEnumValue(Prospero::StencilFormat::k8UInt) ||
|
||||
z.stencil_info.tile_mode_index != 0 || z.stencil_info.tile_split != 0 ||
|
||||
!htile_stencil_compat || z.stencil_info.texture_compatible_stencil ||
|
||||
z.stencil_read_base_addr == 0 ||
|
||||
!htile_stencil_compat || z.stencil_read_base_addr == 0 ||
|
||||
z.stencil_write_base_addr != z.stencil_read_base_addr ||
|
||||
(z.stencil_read_base_addr & 0xffffu) != 0 || z.depth_view.stencil_write_disable) {
|
||||
DepthFatal("unsupported stencil attachment state");
|
||||
}
|
||||
if (!z.stencil_info.tile_stencil_disable) {
|
||||
static std::atomic_bool logged = false;
|
||||
if (!logged.load(std::memory_order_relaxed) &&
|
||||
!logged.exchange(true, std::memory_order_relaxed)) {
|
||||
LOGF("DepthTarget: compatibility: using native stencil with PS5 HTILE "
|
||||
"acceleration\n");
|
||||
}
|
||||
}
|
||||
} else if (z.stencil_read_base_addr != 0 || z.stencil_write_base_addr != 0 ||
|
||||
z.stencil_info.tile_mode_index != 0 || z.stencil_info.tile_split != 0 ||
|
||||
!htile_stencil_compat || z.stencil_info.texture_compatible_stencil) {
|
||||
!htile_stencil_compat ||
|
||||
z.stencil_info.texture_compatibility !=
|
||||
Prospero::TextureCompatibleStencil::kDisable) {
|
||||
DepthFatal("stencil state without an active stencil attachment");
|
||||
}
|
||||
if (has_htile) {
|
||||
@@ -271,16 +259,16 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
(has_htile && htile_backing_size > TRACKER_ADDRESS_SIZE - z.htile_data_base_addr)) {
|
||||
DepthFatal("layered depth backing range is invalid");
|
||||
}
|
||||
r.htile = has_htile;
|
||||
r.width = width;
|
||||
r.height = height;
|
||||
r.samples = samples;
|
||||
r.depth_buffer_size = depth_backing_size;
|
||||
r.depth_buffer_vaddr = z.z_read_base_addr;
|
||||
r.stencil_buffer_size = has_stencil ? stencil_backing_size : 0;
|
||||
r.stencil_buffer_vaddr = has_stencil ? z.stencil_read_base_addr : 0;
|
||||
r.htile_buffer_size = has_htile ? htile_backing_size : 0;
|
||||
r.htile_buffer_vaddr = has_htile ? z.htile_data_base_addr : 0;
|
||||
r.htile = has_htile;
|
||||
r.width = width;
|
||||
r.height = height;
|
||||
r.samples = samples;
|
||||
r.depth_buffer_size = depth_backing_size;
|
||||
r.depth_buffer_vaddr = z.z_read_base_addr;
|
||||
r.stencil_buffer_size = has_stencil ? stencil_backing_size : 0;
|
||||
r.stencil_buffer_vaddr = has_stencil ? z.stencil_read_base_addr : 0;
|
||||
r.htile_buffer_size = has_htile ? htile_backing_size : 0;
|
||||
r.htile_buffer_vaddr = has_htile ? z.htile_data_base_addr : 0;
|
||||
r.depth_clear_enable = rc.depth_clear_enable;
|
||||
r.depth_meta_clear_enable = false;
|
||||
r.depth_load_clear_enable = r.depth_clear_enable;
|
||||
@@ -334,13 +322,13 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
r.size[1] = r.stencil_buffer_size;
|
||||
}
|
||||
TextureCache::ImageDesc desc {};
|
||||
desc.type = TextureCache::BindingType::DepthTarget;
|
||||
desc.info.data = {r.depth_buffer_vaddr, r.depth_buffer_size};
|
||||
desc.info.stencil = {r.stencil_buffer_vaddr, r.stencil_buffer_size};
|
||||
desc.info.pixel_format = r.format;
|
||||
desc.info.guest_format = guest_format;
|
||||
desc.info.type = Prospero::ImageType::kColor2D;
|
||||
desc.info.extent = {width, height, 1};
|
||||
desc.type = TextureCache::BindingType::DepthTarget;
|
||||
desc.info.data = {r.depth_buffer_vaddr, r.depth_buffer_size};
|
||||
desc.info.stencil = {r.stencil_buffer_vaddr, r.stencil_buffer_size};
|
||||
desc.info.pixel_format = r.format;
|
||||
desc.info.guest_format = guest_format;
|
||||
desc.info.type = Prospero::ImageType::kColor2D;
|
||||
desc.info.extent = {width, height, 1};
|
||||
desc.info.resources = {1, view.image_layers};
|
||||
desc.info.pitch = pitch;
|
||||
desc.info.bytes_per_block = bytes;
|
||||
@@ -350,20 +338,20 @@ void RenderExecutor::ResolveRenderDepthTarget(uint64_t submit_id, RenderCommandB
|
||||
desc.info.metadata.range = {r.htile_buffer_vaddr, r.htile_buffer_size};
|
||||
desc.info.metadata.kind = has_htile ? ImageMetadataKind::Htile : ImageMetadataKind::None;
|
||||
desc.info.metadata.stencil_compressed =
|
||||
has_stencil && has_htile && !z.stencil_info.tile_stencil_disable;
|
||||
has_stencil && has_htile && !z.stencil_info.htile_stencil_disabled;
|
||||
desc.view_info.format = r.format;
|
||||
desc.view_info.type =
|
||||
view.layer_count == 1 ? vk::ImageViewType::e2D : vk::ImageViewType::e2DArray;
|
||||
desc.view_info.aspect = ImageViewOps::DepthAspectMask(r.format);
|
||||
desc.view_info.base_level = 0;
|
||||
desc.view_info.level_count = 1;
|
||||
desc.view_info.base_layer = view.base_layer;
|
||||
desc.view_info.layer_count = view.layer_count;
|
||||
desc.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
r.desc = std::move(desc);
|
||||
auto& cache = m_context.GetTextureCache();
|
||||
r.image_id = cache.FindImage(r.desc);
|
||||
r.image_view = nullptr;
|
||||
desc.view_info.aspect = ImageViewOps::DepthAspectMask(r.format);
|
||||
desc.view_info.base_level = 0;
|
||||
desc.view_info.level_count = 1;
|
||||
desc.view_info.base_layer = view.base_layer;
|
||||
desc.view_info.layer_count = view.layer_count;
|
||||
desc.view_info.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
r.desc = std::move(desc);
|
||||
auto& cache = m_context.GetTextureCache();
|
||||
r.image_id = cache.FindImage(r.desc);
|
||||
r.image_view = nullptr;
|
||||
BindRenderTarget(r.image_id);
|
||||
}
|
||||
|
||||
@@ -372,7 +360,7 @@ vk::ImageAspectFlags RenderDepthInfo::AttachmentWriteAspects() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto available = ImageViewOps::DepthAspectMask(format);
|
||||
const auto available = ImageViewOps::DepthAspectMask(format);
|
||||
vk::ImageAspectFlags writes {};
|
||||
if ((available & vk::ImageAspectFlagBits::eDepth) &&
|
||||
(depth_load_clear_enable || (depth_test_enable && depth_write_enable))) {
|
||||
@@ -415,9 +403,8 @@ vk::ImageAspectFlags RenderDepthInfo::AttachmentWriteAspects() const {
|
||||
(can_pass && depth_fail && state.depthFailOp != vk::StencilOp::eKeep);
|
||||
};
|
||||
if (stencil_clear_enable ||
|
||||
(stencil_test_enable &&
|
||||
(face_writes(stencil_static_front, stencil_dynamic_front) ||
|
||||
face_writes(stencil_static_back, stencil_dynamic_back)))) {
|
||||
(stencil_test_enable && (face_writes(stencil_static_front, stencil_dynamic_front) ||
|
||||
face_writes(stencil_static_back, stencil_dynamic_back)))) {
|
||||
writes |= vk::ImageAspectFlagBits::eStencil;
|
||||
}
|
||||
return writes;
|
||||
|
||||
Reference in New Issue
Block a user