diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index e4d22cdcf..f850eb837 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -431,7 +431,7 @@ struct Liverpool { BitField<28, 4, u32> output7_mask; [[nodiscard]] u8 GetMask(int buf_id) const { - return (raw >> (buf_id * 4)) & 0xffu; + return (raw >> (buf_id * 4)) & 0xfu; } }; @@ -732,6 +732,20 @@ struct Liverpool { float back_offset; }; + struct Address { + u32 address; + + VAddr GetAddress() const { + return u64(address) << 8; + } + }; + + union DepthRenderControl { + u32 raw; + BitField<0, 1, u32> depth_clear_enable; + BitField<1, 1, u32> stencil_clear_enable; + }; + union Regs { struct { INSERT_PADDING_WORDS(0x2C08); @@ -740,11 +754,15 @@ struct Liverpool { ShaderProgram vs_program; INSERT_PADDING_WORDS(0x2E00 - 0x2C4C - 16); ComputeProgram cs_program; - INSERT_PADDING_WORDS(0xA008 - 0x2E00 - 80); + INSERT_PADDING_WORDS(0xA008 - 0x2E00 - 80 - 3 - 5); + DepthRenderControl depth_render_control; + INSERT_PADDING_WORDS(4); + Address depth_htile_data_base; + INSERT_PADDING_WORDS(2); float depth_bounds_min; float depth_bounds_max; u32 stencil_clear; - u32 depth_clear; + float depth_clear; Scissor screen_scissor; INSERT_PADDING_WORDS(0xA010 - 0xA00C - 2); DepthBuffer depth_buffer; @@ -925,6 +943,8 @@ static_assert(GFX6_3D_REG_INDEX(cs_program) == 0x2E00); static_assert(GFX6_3D_REG_INDEX(cs_program.dim_z) == 0x2E03); static_assert(GFX6_3D_REG_INDEX(cs_program.address_lo) == 0x2E0C); static_assert(GFX6_3D_REG_INDEX(cs_program.user_data) == 0x2E40); +static_assert(GFX6_3D_REG_INDEX(depth_render_control) == 0xA000); +static_assert(GFX6_3D_REG_INDEX(depth_htile_data_base) == 0xA005); static_assert(GFX6_3D_REG_INDEX(screen_scissor) == 0xA00C); static_assert(GFX6_3D_REG_INDEX(depth_buffer.depth_slice) == 0xA017); static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E); @@ -942,6 +962,7 @@ static_assert(GFX6_3D_REG_INDEX(color_export_format) == 0xA1C5); static_assert(GFX6_3D_REG_INDEX(blend_control) == 0xA1E0); static_assert(GFX6_3D_REG_INDEX(index_base_address) == 0xA1F9); static_assert(GFX6_3D_REG_INDEX(draw_initiator) == 0xA1FC); +static_assert(GFX6_3D_REG_INDEX(depth_control) == 0xA200); static_assert(GFX6_3D_REG_INDEX(clipper_control) == 0xA204); static_assert(GFX6_3D_REG_INDEX(viewport_control) == 0xA206); static_assert(GFX6_3D_REG_INDEX(vs_output_control) == 0xA207); diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 000063d53..8ca82f821 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -334,6 +334,19 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Float) { return vk::Format::eR32Sfloat; } + if (data_format == AmdGpu::DataFormat::Format16_16_16_16 && + num_format == AmdGpu::NumberFormat::Float) { + return vk::Format::eR16G16B16A16Sfloat; + } + if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Uint) { + return vk::Format::eR32Uint; + } + if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Sint) { + return vk::Format::eR32Sint; + } + if (data_format == AmdGpu::DataFormat::Format8_8 && num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eR8G8Unorm; + } UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index c1340d080..291d38fd2 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -60,13 +60,16 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { }); } if (regs.depth_control.depth_enable && regs.depth_buffer.Address() != 0) { + const bool is_clear = regs.depth_render_control.depth_clear_enable; const auto& image_view = texture_cache.DepthTarget(regs.depth_buffer, liverpool->last_db_extent); depth_attachment = { .imageView = *image_view.image_view, .imageLayout = vk::ImageLayout::eGeneral, - .loadOp = vk::AttachmentLoadOp::eLoad, - .storeOp = vk::AttachmentStoreOp::eStore, + .loadOp = is_clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, + .storeOp = is_clear ? vk::AttachmentStoreOp::eNone : vk::AttachmentStoreOp::eStore, + .clearValue = vk::ClearValue{.depthStencil = {.depth = regs.depth_clear, + .stencil = regs.stencil_clear}}, }; num_depth_attachments++; }