mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-06 14:09:58 +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,
|
const Region2D& dst_region, const Region2D& src_region,
|
||||||
Tegra::Engines::Fermi2D::Filter filter,
|
Tegra::Engines::Fermi2D::Filter filter,
|
||||||
Tegra::Engines::Fermi2D::Operation operation) {
|
Tegra::Engines::Fermi2D::Operation operation) {
|
||||||
if (!device.IsExtShaderStencilExportSupported()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
|
ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
|
||||||
ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
|
ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
|
||||||
|
const bool blit_stencil = device.IsExtShaderStencilExportSupported();
|
||||||
const BlitImagePipelineKey key{
|
const BlitImagePipelineKey key{
|
||||||
.renderpass = dst_framebuffer->RenderPass(),
|
.renderpass = dst_framebuffer->RenderPass(),
|
||||||
.operation = operation,
|
.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 VkSampler sampler = *nearest_sampler;
|
||||||
const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
|
|
||||||
const VkImageView src_depth_view = src_image_view.DepthView();
|
const VkImageView src_depth_view = src_image_view.DepthView();
|
||||||
const VkImageView src_stencil_view = src_image_view.StencilView();
|
|
||||||
|
|
||||||
RecordShaderReadBarrier(scheduler, src_image_view);
|
RecordShaderReadBarrier(scheduler, src_image_view);
|
||||||
scheduler.RequestRenderpass(dst_framebuffer);
|
scheduler.RequestRenderpass(dst_framebuffer);
|
||||||
scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
|
scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
|
||||||
src_stencil_view, this](vk::CommandBuffer cmdbuf) {
|
src_stencil_view, blit_stencil, this](vk::CommandBuffer cmdbuf) {
|
||||||
const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
|
VkDescriptorSet descriptor_set{};
|
||||||
UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
|
if (blit_stencil) {
|
||||||
src_stencil_view);
|
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.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass
|
|||||||
num_renderpass_images = framebuffer->NumImages();
|
num_renderpass_images = framebuffer->NumImages();
|
||||||
renderpass_images = framebuffer->Images();
|
renderpass_images = framebuffer->Images();
|
||||||
renderpass_image_ranges = framebuffer->ImageRanges();
|
renderpass_image_ranges = framebuffer->ImageRanges();
|
||||||
|
framebuffer->MarkResolveShadowsUpToDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::RealizeDeferredClear() {
|
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 &&
|
if (shadow.image && shadow.format == format && shadow.extent.width == extent.width &&
|
||||||
shadow.extent.height == extent.height && shadow.layers == layers &&
|
shadow.extent.height == extent.height && shadow.layers == layers &&
|
||||||
shadow.aspect_mask == aspect_mask) {
|
shadow.aspect_mask == aspect_mask) {
|
||||||
shadow.up_to_date = true;
|
|
||||||
return *shadow.view;
|
return *shadow.view;
|
||||||
}
|
}
|
||||||
VkImageUsageFlags shadow_usage =
|
VkImageUsageFlags shadow_usage =
|
||||||
@@ -1069,7 +1068,7 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
|||||||
shadow.extent = extent;
|
shadow.extent = extent;
|
||||||
shadow.layers = layers;
|
shadow.layers = layers;
|
||||||
shadow.aspect_mask = aspect_mask;
|
shadow.aspect_mask = aspect_mask;
|
||||||
shadow.up_to_date = true;
|
shadow.up_to_date = false;
|
||||||
return *shadow.view;
|
return *shadow.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,6 +1081,13 @@ const TextureCacheRuntime::ResolveShadow* TextureCacheRuntime::GetValidResolveSh
|
|||||||
return &it->second;
|
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) {
|
void TextureCacheRuntime::InvalidateResolveShadow(VkImage msaa_image) {
|
||||||
const auto it = resolve_shadows.find(msaa_image);
|
const auto it = resolve_shadows.find(msaa_image);
|
||||||
if (it != resolve_shadows.end()) {
|
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) {
|
if ((dst_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0) {
|
||||||
const bool copies_stencil = (dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 &&
|
const bool copies_stencil = (dst_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0 &&
|
||||||
device.IsExtShaderStencilExportSupported();
|
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,
|
blit_image_helper.CopyMSAADepth(render_pass_cache, dst.Handle(), dst.info.format,
|
||||||
src.Handle(), src.info.format, num_samples, copies,
|
src.Handle(), src.info.format, num_samples, copies,
|
||||||
copies_stencil, msaa_to_non_msaa);
|
copies_stencil, msaa_to_non_msaa);
|
||||||
@@ -3059,6 +3061,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
renderpass = runtime.render_pass_cache.Get(renderpass_key);
|
renderpass = runtime.render_pass_cache.Get(renderpass_key);
|
||||||
render_pass_key = renderpass_key;
|
render_pass_key = renderpass_key;
|
||||||
render_pass_cache = &runtime.render_pass_cache;
|
render_pass_cache = &runtime.render_pass_cache;
|
||||||
|
runtime_ptr = &runtime;
|
||||||
render_area.width = (std::min)(render_area.width, width);
|
render_area.width = (std::min)(render_area.width, width);
|
||||||
render_area.height = (std::min)(render_area.height, height);
|
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]];
|
const VkImage msaa_image = images[rt_map[index]];
|
||||||
attachments.push_back(runtime.GetOrCreateResolveShadow(
|
attachments.push_back(runtime.GetOrCreateResolveShadow(
|
||||||
msaa_image, vk_format, render_area, layers, VK_IMAGE_ASPECT_COLOR_BIT));
|
msaa_image, vk_format, render_area, layers, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||||
|
resolve_shadow_images[num_resolve_shadows++] = msaa_image;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
VkImageCreateInfo resolve_ci{
|
VkImageCreateInfo resolve_ci{
|
||||||
@@ -3127,6 +3131,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
|||||||
.format;
|
.format;
|
||||||
attachments.push_back(runtime.GetOrCreateResolveShadow(depth_image, vk_format, render_area,
|
attachments.push_back(runtime.GetOrCreateResolveShadow(depth_image, vk_format, render_area,
|
||||||
layers, depth_aspect_mask));
|
layers, depth_aspect_mask));
|
||||||
|
resolve_shadow_images[num_resolve_shadows++] = depth_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_color_buffers = static_cast<u32>(num_colors);
|
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,
|
VkRenderPass Framebuffer::RenderPassVariant(u32 color_clear_mask, bool depth_stencil_clear,
|
||||||
u32 color_discard_mask,
|
u32 color_discard_mask,
|
||||||
bool depth_stencil_discard) const {
|
bool depth_stencil_discard) const {
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ public:
|
|||||||
|
|
||||||
void InvalidateResolveShadow(VkImage msaa_image);
|
void InvalidateResolveShadow(VkImage msaa_image);
|
||||||
|
|
||||||
|
void MarkResolveShadowUpToDate(VkImage msaa_image);
|
||||||
|
|
||||||
void EraseResolveShadow(VkImage msaa_image);
|
void EraseResolveShadow(VkImage msaa_image);
|
||||||
|
|
||||||
std::span<const VkFormat> ViewFormats(PixelFormat format) {
|
std::span<const VkFormat> ViewFormats(PixelFormat format) {
|
||||||
@@ -257,6 +259,10 @@ public:
|
|||||||
return discard_msaa_depth_stencil;
|
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:
|
private:
|
||||||
static constexpr size_t NUM_MEMOIZED_RENDER_PASS_VARIANTS = 8;
|
static constexpr size_t NUM_MEMOIZED_RENDER_PASS_VARIANTS = 8;
|
||||||
|
|
||||||
@@ -274,6 +280,9 @@ private:
|
|||||||
bool is_rescaled{};
|
bool is_rescaled{};
|
||||||
std::vector<vk::Image> resolve_images;
|
std::vector<vk::Image> resolve_images;
|
||||||
std::vector<vk::ImageView> resolve_image_views;
|
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{};
|
RenderPassKey render_pass_key{};
|
||||||
RenderPassCache* render_pass_cache{nullptr};
|
RenderPassCache* render_pass_cache{nullptr};
|
||||||
bool discard_msaa_color{};
|
bool discard_msaa_color{};
|
||||||
|
|||||||
Reference in New Issue
Block a user