mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-20 06:53:11 +00:00
[TEST] Ensure resolve shadow reads on msaa + shader extencil fallback
This commit is contained in:
@@ -844,28 +844,40 @@ void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
|
||||
const Region2D& dst_region, const Region2D& src_region,
|
||||
Tegra::Engines::Fermi2D::Filter filter,
|
||||
Tegra::Engines::Fermi2D::Operation operation) {
|
||||
if (!device.IsExtShaderStencilExportSupported()) {
|
||||
return;
|
||||
}
|
||||
ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
|
||||
ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
|
||||
const bool blit_stencil = device.IsExtShaderStencilExportSupported();
|
||||
const BlitImagePipelineKey key{
|
||||
.renderpass = dst_framebuffer->RenderPass(),
|
||||
.operation = operation,
|
||||
};
|
||||
const VkPipelineLayout layout = *two_textures_pipeline_layout;
|
||||
VkPipelineLayout layout{};
|
||||
VkPipeline pipeline{};
|
||||
VkImageView src_stencil_view = VK_NULL_HANDLE;
|
||||
if (blit_stencil) {
|
||||
layout = *two_textures_pipeline_layout;
|
||||
pipeline = FindOrEmplaceDepthStencilPipeline(key);
|
||||
src_stencil_view = src_image_view.StencilView();
|
||||
} else {
|
||||
layout = *one_texture_pipeline_layout;
|
||||
pipeline = FindOrEmplaceBlitDepthPipeline(key.renderpass);
|
||||
}
|
||||
const VkSampler sampler = *nearest_sampler;
|
||||
const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
|
||||
const VkImageView src_depth_view = src_image_view.DepthView();
|
||||
const VkImageView src_stencil_view = src_image_view.StencilView();
|
||||
|
||||
RecordShaderReadBarrier(scheduler, src_image_view);
|
||||
scheduler.RequestRenderpass(dst_framebuffer);
|
||||
scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
|
||||
src_stencil_view, this](vk::CommandBuffer cmdbuf) {
|
||||
const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
|
||||
UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
|
||||
src_stencil_view);
|
||||
src_stencil_view, blit_stencil, this](vk::CommandBuffer cmdbuf) {
|
||||
VkDescriptorSet descriptor_set{};
|
||||
if (blit_stencil) {
|
||||
descriptor_set = two_textures_descriptor_allocator.Commit();
|
||||
UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
|
||||
src_stencil_view);
|
||||
} else {
|
||||
descriptor_set = one_texture_descriptor_allocator.Commit();
|
||||
UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_depth_view);
|
||||
}
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
|
||||
nullptr);
|
||||
|
||||
@@ -132,6 +132,7 @@ void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass
|
||||
num_renderpass_images = framebuffer->NumImages();
|
||||
renderpass_images = framebuffer->Images();
|
||||
renderpass_image_ranges = framebuffer->ImageRanges();
|
||||
framebuffer->MarkResolveShadowsUpToDate();
|
||||
}
|
||||
|
||||
void Scheduler::RealizeDeferredClear() {
|
||||
|
||||
@@ -1019,7 +1019,6 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
||||
if (shadow.image && shadow.format == format && shadow.extent.width == extent.width &&
|
||||
shadow.extent.height == extent.height && shadow.layers == layers &&
|
||||
shadow.aspect_mask == aspect_mask) {
|
||||
shadow.up_to_date = true;
|
||||
return *shadow.view;
|
||||
}
|
||||
VkImageUsageFlags shadow_usage =
|
||||
@@ -1069,7 +1068,7 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
||||
shadow.extent = extent;
|
||||
shadow.layers = layers;
|
||||
shadow.aspect_mask = aspect_mask;
|
||||
shadow.up_to_date = true;
|
||||
shadow.up_to_date = false;
|
||||
return *shadow.view;
|
||||
}
|
||||
|
||||
@@ -1082,6 +1081,13 @@ const TextureCacheRuntime::ResolveShadow* TextureCacheRuntime::GetValidResolveSh
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void TextureCacheRuntime::MarkResolveShadowUpToDate(VkImage msaa_image) {
|
||||
const auto it = resolve_shadows.find(msaa_image);
|
||||
if (it != resolve_shadows.end()) {
|
||||
it->second.up_to_date = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCacheRuntime::InvalidateResolveShadow(VkImage msaa_image) {
|
||||
const auto it = resolve_shadows.find(msaa_image);
|
||||
if (it != resolve_shadows.end()) {
|
||||
@@ -1753,10 +1759,6 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
if ((dst_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0) {
|
||||
const bool copies_stencil = (dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 &&
|
||||
device.IsExtShaderStencilExportSupported();
|
||||
if ((dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 && !copies_stencil) {
|
||||
UNIMPLEMENTED_MSG("Copying images with different samples is not supported.");
|
||||
return;
|
||||
}
|
||||
blit_image_helper.CopyMSAADepth(render_pass_cache, dst.Handle(), dst.info.format,
|
||||
src.Handle(), src.info.format, num_samples, copies,
|
||||
copies_stencil, msaa_to_non_msaa);
|
||||
@@ -3059,6 +3061,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
renderpass = runtime.render_pass_cache.Get(renderpass_key);
|
||||
render_pass_key = renderpass_key;
|
||||
render_pass_cache = &runtime.render_pass_cache;
|
||||
runtime_ptr = &runtime;
|
||||
render_area.width = (std::min)(render_area.width, width);
|
||||
render_area.height = (std::min)(render_area.height, height);
|
||||
|
||||
@@ -3075,6 +3078,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
const VkImage msaa_image = images[rt_map[index]];
|
||||
attachments.push_back(runtime.GetOrCreateResolveShadow(
|
||||
msaa_image, vk_format, render_area, layers, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||
resolve_shadow_images[num_resolve_shadows++] = msaa_image;
|
||||
continue;
|
||||
}
|
||||
VkImageCreateInfo resolve_ci{
|
||||
@@ -3127,6 +3131,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
.format;
|
||||
attachments.push_back(runtime.GetOrCreateResolveShadow(depth_image, vk_format, render_area,
|
||||
layers, depth_aspect_mask));
|
||||
resolve_shadow_images[num_resolve_shadows++] = depth_image;
|
||||
}
|
||||
|
||||
num_color_buffers = static_cast<u32>(num_colors);
|
||||
@@ -3143,6 +3148,15 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
});
|
||||
}
|
||||
|
||||
void Framebuffer::MarkResolveShadowsUpToDate() const {
|
||||
if (runtime_ptr == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (u32 index = 0; index < num_resolve_shadows; ++index) {
|
||||
runtime_ptr->MarkResolveShadowUpToDate(resolve_shadow_images[index]);
|
||||
}
|
||||
}
|
||||
|
||||
VkRenderPass Framebuffer::RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear,
|
||||
u32 color_discard_mask,
|
||||
bool depth_stencil_discard) const {
|
||||
|
||||
@@ -131,6 +131,8 @@ public:
|
||||
|
||||
void InvalidateResolveShadow(VkImage msaa_image);
|
||||
|
||||
void MarkResolveShadowUpToDate(VkImage msaa_image);
|
||||
|
||||
void EraseResolveShadow(VkImage msaa_image);
|
||||
|
||||
std::span<const VkFormat> ViewFormats(PixelFormat format) {
|
||||
@@ -257,6 +259,10 @@ public:
|
||||
return discard_msaa_depth_stencil;
|
||||
}
|
||||
|
||||
/// Records that a render pass has begun, so its resolve attachments will hold valid contents
|
||||
/// once it ends.
|
||||
void MarkResolveShadowsUpToDate() const;
|
||||
|
||||
private:
|
||||
static constexpr size_t NUM_MEMOIZED_RENDER_PASS_VARIANTS = 8;
|
||||
|
||||
@@ -274,6 +280,9 @@ private:
|
||||
bool is_rescaled{};
|
||||
std::vector<vk::Image> resolve_images;
|
||||
std::vector<vk::ImageView> resolve_image_views;
|
||||
std::array<VkImage, 9> resolve_shadow_images{};
|
||||
u32 num_resolve_shadows = 0;
|
||||
TextureCacheRuntime* runtime_ptr{nullptr};
|
||||
RenderPassKey render_pass_key{};
|
||||
RenderPassCache* render_pass_cache{nullptr};
|
||||
bool discard_msaa_color{};
|
||||
|
||||
Reference in New Issue
Block a user