#ifndef EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_DEPTHRENDERTARGET_H_ #define EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_DEPTHRENDERTARGET_H_ #include "common/assert.h" #include "graphics/host_gpu/renderer/cache/textureCache.h" #include "graphics/host_gpu/renderer/image/imageView.h" #include "graphics/host_gpu/renderer/renderTarget.h" #include "graphics/host_gpu/vulkanCommon.h" #include namespace Libs::Graphics { // Without a stencil plane, Hi-Stencil fields are inactive. An active plane is compatible when // Hi-Stencil is disabled or HTile backing is present. inline constexpr bool depth_htile_stencil_acceleration_compatible(bool has_stencil, bool has_htile, bool htile_stencil_disabled) { return !has_stencil || htile_stencil_disabled || has_htile; } struct RenderDepthInfo { // Discovery keeps guest image information but can remap the view into a larger cache image. TextureCache::ImageDesc desc; bool depth_clear_enable = false; bool depth_load_clear_enable = false; float depth_clear_value = 0.0f; bool depth_test_enable = false; // Effective draw writes; discovery applies test, target-write and clear controls. bool depth_write_enable = false; vk::CompareOp depth_compare_op = vk::CompareOp::eNever; bool depth_bounds_test_enable = false; float depth_min_bounds = 0.0f; float depth_max_bounds = 0.0f; bool stencil_clear_enable = false; uint8_t stencil_clear_value = 0; bool stencil_test_enable = false; vk::StencilOpState stencil_front; vk::StencilOpState stencil_back; ImageId image_id; [[nodiscard]] vk::ImageAspectFlags AttachmentWriteAspects() const; }; inline vk::ImageLayout depth_attachment_layout(const RenderDepthInfo& depth) { const auto available = ImageViewOps::DepthAspectMask(depth.desc.view_info.format); const auto writes = depth.AttachmentWriteAspects(); const bool has_depth = static_cast(available & vk::ImageAspectFlagBits::eDepth); const bool has_stencil = static_cast(available & vk::ImageAspectFlagBits::eStencil); // LoadOp clears are separate from guest depth writes. const bool depth_write = depth.depth_write_enable; const bool stencil_write = static_cast(writes & vk::ImageAspectFlagBits::eStencil); if (!has_stencil) { return depth_write ? vk::ImageLayout::eDepthAttachmentOptimal : vk::ImageLayout::eDepthReadOnlyOptimal; } if (!has_depth) { return stencil_write ? vk::ImageLayout::eStencilAttachmentOptimal : vk::ImageLayout::eStencilReadOnlyOptimal; } if (depth_write && stencil_write) { return vk::ImageLayout::eDepthStencilAttachmentOptimal; } if (depth_write) { return vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal; } if (stencil_write) { return vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal; } return vk::ImageLayout::eDepthStencilReadOnlyOptimal; } } // namespace Libs::Graphics #endif // EMULATOR_SRC_GRAPHICS_HOST_GPU_RENDERER_DEPTHRENDERTARGET_H_