mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-16 05:21:22 +00:00
[TEST] depth stencil resolve implementation + fixes
This commit is contained in:
@@ -107,6 +107,9 @@ void Scheduler::BeginDynamicRendering(const Framebuffer* framebuffer, const Defe
|
||||
state.attachment_views = attachment_views;
|
||||
state.color_resolve_views = framebuffer->ColorResolveAttachments();
|
||||
state.color_resolve_modes = framebuffer->ColorResolveModes();
|
||||
state.depth_resolve_view = framebuffer->DepthResolveAttachment();
|
||||
state.depth_resolve_mode = framebuffer->DepthResolveMode();
|
||||
state.stencil_resolve_mode = framebuffer->StencilResolveMode();
|
||||
state.discards_msaa_color = framebuffer->DiscardsMsaaColor();
|
||||
state.discards_msaa_depth = framebuffer->DiscardsMsaaDepth();
|
||||
state.render_area = render_area;
|
||||
@@ -453,9 +456,13 @@ void Scheduler::RecordDynamicBegin(const DeferredClear* clear) {
|
||||
const bool ds_clear = clear != nullptr && clear->depth_stencil;
|
||||
const VkClearValue ds_clear_value = clear ? clear->depth_stencil_value : VkClearValue{};
|
||||
const bool ds_discard = state.discards_msaa_depth;
|
||||
const VkImageView ds_resolve_view = state.depth_resolve_view;
|
||||
const VkResolveModeFlagBits depth_resolve_mode = state.depth_resolve_mode;
|
||||
const VkResolveModeFlagBits stencil_resolve_mode = state.stencil_resolve_mode;
|
||||
Record([views, resolve_views, resolve_modes, num_color, has_depth, has_stencil, layers,
|
||||
render_area, color_clear_mask, color_discard_mask, color_clear_values, ds_clear,
|
||||
ds_clear_value, ds_discard](vk::CommandBuffer cmdbuf) {
|
||||
ds_clear_value, ds_discard, ds_resolve_view, depth_resolve_mode,
|
||||
stencil_resolve_mode](vk::CommandBuffer cmdbuf) {
|
||||
std::array<VkRenderingAttachmentInfo, VideoCommon::NUM_RT> color_infos{};
|
||||
for (u32 index = 0; index < num_color; ++index) {
|
||||
const bool clear_slot = ((color_clear_mask >> index) & 1u) != 0;
|
||||
@@ -477,17 +484,37 @@ void Scheduler::RecordDynamicBegin(const DeferredClear* clear) {
|
||||
.clearValue = clear_slot ? color_clear_values[index] : VkClearValue{},
|
||||
};
|
||||
}
|
||||
const bool has_ds_resolve = ds_resolve_view != VK_NULL_HANDLE;
|
||||
const VkAttachmentLoadOp ds_load_op = ds_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR
|
||||
: ds_discard ? VK_ATTACHMENT_LOAD_OP_DONT_CARE
|
||||
: VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
const VkAttachmentStoreOp ds_store_op =
|
||||
ds_discard ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
|
||||
const VkRenderingAttachmentInfo depth_info{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.pNext = nullptr,
|
||||
.imageView = views[8],
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = VK_RESOLVE_MODE_NONE,
|
||||
.resolveImageView = VK_NULL_HANDLE,
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.loadOp = ds_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
|
||||
.storeOp = ds_discard ? VK_ATTACHMENT_STORE_OP_DONT_CARE
|
||||
: VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.resolveMode = has_ds_resolve ? depth_resolve_mode : VK_RESOLVE_MODE_NONE,
|
||||
.resolveImageView = has_ds_resolve ? ds_resolve_view : VK_NULL_HANDLE,
|
||||
.resolveImageLayout =
|
||||
has_ds_resolve ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.loadOp = ds_load_op,
|
||||
.storeOp = ds_store_op,
|
||||
.clearValue = ds_clear ? ds_clear_value : VkClearValue{},
|
||||
};
|
||||
// Stencil gets its own struct because its resolve mode may differ from depth's.
|
||||
const VkRenderingAttachmentInfo stencil_info{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.pNext = nullptr,
|
||||
.imageView = views[8],
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.resolveMode = has_ds_resolve ? stencil_resolve_mode : VK_RESOLVE_MODE_NONE,
|
||||
.resolveImageView = has_ds_resolve ? ds_resolve_view : VK_NULL_HANDLE,
|
||||
.resolveImageLayout =
|
||||
has_ds_resolve ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.loadOp = ds_load_op,
|
||||
.storeOp = ds_store_op,
|
||||
.clearValue = ds_clear ? ds_clear_value : VkClearValue{},
|
||||
};
|
||||
const VkRenderingInfo rendering_info{
|
||||
@@ -504,7 +531,7 @@ void Scheduler::RecordDynamicBegin(const DeferredClear* clear) {
|
||||
.colorAttachmentCount = num_color,
|
||||
.pColorAttachments = color_infos.data(),
|
||||
.pDepthAttachment = has_depth ? &depth_info : nullptr,
|
||||
.pStencilAttachment = has_stencil ? &depth_info : nullptr,
|
||||
.pStencilAttachment = has_stencil ? &stencil_info : nullptr,
|
||||
};
|
||||
cmdbuf.BeginRendering(rendering_info);
|
||||
});
|
||||
|
||||
@@ -270,6 +270,9 @@ private:
|
||||
std::array<VkImageView, 9> attachment_views{};
|
||||
std::array<VkImageView, 8> color_resolve_views{};
|
||||
std::array<VkResolveModeFlagBits, 8> color_resolve_modes{};
|
||||
VkImageView depth_resolve_view{};
|
||||
VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE;
|
||||
VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE;
|
||||
VkExtent2D render_area = {0, 0};
|
||||
GraphicsPipeline* graphics_pipeline = nullptr;
|
||||
bool rendering = false;
|
||||
|
||||
@@ -1005,7 +1005,10 @@ VkBuffer TextureCacheRuntime::GetTemporaryBuffer(size_t needed_size) {
|
||||
}
|
||||
|
||||
VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, VkFormat format,
|
||||
VkExtent2D extent, u32 layers) {
|
||||
VkExtent2D extent, u32 layers,
|
||||
VkImageAspectFlags aspect) {
|
||||
const bool is_depth_stencil =
|
||||
(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0;
|
||||
ResolveShadow& shadow = resolve_shadows[msaa_image];
|
||||
if (shadow.image && shadow.format == format && shadow.extent.width == extent.width &&
|
||||
shadow.extent.height == extent.height && shadow.layers == layers) {
|
||||
@@ -1023,8 +1026,9 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
||||
.arrayLayers = layers,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
.usage = (is_depth_stencil ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||
: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) |
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.pQueueFamilyIndices = nullptr,
|
||||
@@ -1039,7 +1043,7 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
||||
.format = format,
|
||||
.components{},
|
||||
.subresourceRange{
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
@@ -1052,28 +1056,33 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
|
||||
shadow.up_to_date = true;
|
||||
if (device.IsKhrDynamicRenderingSupported()) {
|
||||
scheduler.RecordWithUploadBuffer(
|
||||
[image = *shadow.image, layers](vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) {
|
||||
[image = *shadow.image, layers, aspect, is_depth_stencil](
|
||||
vk::CommandBuffer, vk::CommandBuffer upload_cmdbuf) {
|
||||
const VkImageMemoryBarrier barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = is_depth_stencil
|
||||
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
|
||||
: VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange{
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = layers,
|
||||
},
|
||||
};
|
||||
upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
|
||||
barrier);
|
||||
upload_cmdbuf.PipelineBarrier(
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
is_depth_stencil ? VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
: VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
0, barrier);
|
||||
});
|
||||
}
|
||||
return *shadow.view;
|
||||
@@ -1668,18 +1677,6 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
std::span<const VideoCommon::ImageCopy> copies) {
|
||||
const bool msaa_to_non_msaa = src.info.num_samples > 1 && dst.info.num_samples == 1;
|
||||
const u32 num_samples = msaa_to_non_msaa ? src.info.num_samples : dst.info.num_samples;
|
||||
if (dst.AspectMask() != VK_IMAGE_ASPECT_COLOR_BIT ||
|
||||
VideoCore::Surface::IsPixelFormatInteger(dst.info.format)) {
|
||||
const u64 key{(static_cast<u64>(dst.AspectMask()) << 32) |
|
||||
static_cast<u64>(dst.info.format)};
|
||||
if (unsupported_msaa_resolves.insert(key).second) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"MSAA resolve unsupported: format={}, aspect={:#x}, samples {}->{}",
|
||||
dst.info.format, dst.AspectMask(), src.info.num_samples,
|
||||
dst.info.num_samples);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ENABLE_MSAA_RESOLVE_CONSUME && msaa_to_non_msaa && copies.size() == 1 &&
|
||||
src.info.format == dst.info.format) {
|
||||
const VideoCommon::ImageCopy& copy = copies.front();
|
||||
@@ -1690,16 +1687,19 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
static_cast<u32>(copy.extent.height) <= shadow->extent.height) {
|
||||
const VkImage shadow_image = *shadow->image;
|
||||
const VkImage dst_image = dst.Handle();
|
||||
const VkImageAspectFlags aspect = dst.AspectMask();
|
||||
const bool is_depth_stencil =
|
||||
(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0;
|
||||
const VkImageCopy region{
|
||||
.srcSubresource{
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.aspectMask = aspect,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = static_cast<u32>(copy.src_subresource.base_layer),
|
||||
.layerCount = static_cast<u32>(copy.src_subresource.num_layers),
|
||||
},
|
||||
.srcOffset = {0, 0, 0},
|
||||
.dstSubresource{
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.aspectMask = aspect,
|
||||
.mipLevel = static_cast<u32>(copy.dst_subresource.base_level),
|
||||
.baseArrayLayer = static_cast<u32>(copy.dst_subresource.base_layer),
|
||||
.layerCount = static_cast<u32>(copy.dst_subresource.num_layers),
|
||||
@@ -1708,34 +1708,38 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
.extent = {copy.extent.width, copy.extent.height, 1},
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([shadow_image, dst_image, region](vk::CommandBuffer cmdbuf) {
|
||||
scheduler.Record([shadow_image, dst_image, region, aspect,
|
||||
is_depth_stencil](vk::CommandBuffer cmdbuf) {
|
||||
const VkAccessFlags attachment_write =
|
||||
is_depth_stencil ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
|
||||
: VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
const std::array pre_barriers{
|
||||
VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccessMask = attachment_write,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = shadow_image,
|
||||
.subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
.subresourceRange{aspect, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
VK_REMAINING_ARRAY_LAYERS},
|
||||
},
|
||||
VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.srcAccessMask =
|
||||
VK_ACCESS_SHADER_WRITE_BIT | attachment_write |
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = dst_image,
|
||||
.subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
.subresourceRange{aspect, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
VK_REMAINING_ARRAY_LAYERS},
|
||||
},
|
||||
};
|
||||
@@ -1750,7 +1754,7 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = shadow_image,
|
||||
.subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
.subresourceRange{aspect, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
VK_REMAINING_ARRAY_LAYERS},
|
||||
},
|
||||
VkImageMemoryBarrier{
|
||||
@@ -1760,17 +1764,20 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = dst_image,
|
||||
.subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
.subresourceRange{aspect, 0, VK_REMAINING_MIP_LEVELS, 0,
|
||||
VK_REMAINING_ARRAY_LAYERS},
|
||||
},
|
||||
};
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, nullptr, nullptr,
|
||||
pre_barriers);
|
||||
@@ -1783,6 +1790,18 @@ void TextureCacheRuntime::CopyImageMSAA(Image& dst, Image& src,
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (dst.AspectMask() != VK_IMAGE_ASPECT_COLOR_BIT ||
|
||||
VideoCore::Surface::IsPixelFormatInteger(dst.info.format)) {
|
||||
const u64 key{(static_cast<u64>(dst.AspectMask()) << 32) |
|
||||
static_cast<u64>(dst.info.format)};
|
||||
if (unsupported_msaa_resolves.insert(key).second) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"MSAA resolve unsupported: format={}, aspect={:#x}, samples {}->{}",
|
||||
dst.info.format, dst.AspectMask(), src.info.num_samples,
|
||||
dst.info.num_samples);
|
||||
}
|
||||
return;
|
||||
}
|
||||
blit_image_helper.CopyMSAA(render_pass_cache, dst.Handle(), dst.info.format, src.Handle(),
|
||||
src.info.format, num_samples, copies, msaa_to_non_msaa);
|
||||
}
|
||||
@@ -2806,10 +2825,21 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
samples != VK_SAMPLE_COUNT_1_BIT && num_colors > 0 && runtime.device.IsTiler();
|
||||
renderpass_key.resolve_color = do_resolve_color;
|
||||
|
||||
const VkResolveModeFlagBits depth_mode = runtime.device.GetDepthResolveMode();
|
||||
const VkResolveModeFlagBits stencil_mode = runtime.device.GetStencilResolveMode();
|
||||
const bool resolve_modes_compatible =
|
||||
depth_mode != VK_RESOLVE_MODE_NONE &&
|
||||
(!has_stencil || (stencil_mode != VK_RESOLVE_MODE_NONE &&
|
||||
(runtime.device.IsIndependentResolveSupported() ||
|
||||
depth_mode == stencil_mode)));
|
||||
const bool do_resolve_depth =
|
||||
samples != VK_SAMPLE_COUNT_1_BIT && has_depth && runtime.device.IsTiler() &&
|
||||
runtime.device.IsKhrDynamicRenderingSupported() && resolve_modes_compatible;
|
||||
|
||||
discard_msaa_color =
|
||||
ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_COLOR_DISCARD && do_resolve_color;
|
||||
discard_msaa_depth = ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_DEPTH_DISCARD &&
|
||||
samples != VK_SAMPLE_COUNT_1_BIT && has_depth && runtime.device.IsTiler();
|
||||
discard_msaa_depth =
|
||||
ENABLE_MSAA_RESOLVE_CONSUME && ENABLE_MSAA_DEPTH_DISCARD && do_resolve_depth;
|
||||
|
||||
render_pass_key = renderpass_key;
|
||||
render_pass_cache = &runtime.render_pass_cache;
|
||||
@@ -2831,7 +2861,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
if (ENABLE_MSAA_RESOLVE_CONSUME) {
|
||||
const VkImage msaa_image = images[rt_map[index]];
|
||||
const VkImageView shadow_view = runtime.GetOrCreateResolveShadow(
|
||||
msaa_image, vk_format, render_area, layers);
|
||||
msaa_image, vk_format, render_area, layers, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
color_resolve_attachments[index] = shadow_view;
|
||||
attachments.push_back(shadow_view);
|
||||
continue;
|
||||
@@ -2905,6 +2935,22 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||
}
|
||||
}
|
||||
|
||||
if (do_resolve_depth && depth_buffer != nullptr) {
|
||||
const u32 layers = static_cast<u32>((std::max)(num_layers, 1));
|
||||
VkImageAspectFlags aspect = 0;
|
||||
if (has_depth) {
|
||||
aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
if (has_stencil) {
|
||||
aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
depth_resolve_attachment =
|
||||
runtime.GetOrCreateResolveShadow(depth_buffer->ImageHandle(), depth_attachment_format,
|
||||
render_area, layers, aspect);
|
||||
depth_resolve_mode = depth_mode;
|
||||
stencil_resolve_mode = has_stencil ? stencil_mode : VK_RESOLVE_MODE_NONE;
|
||||
}
|
||||
|
||||
num_color_buffers = static_cast<u32>(num_colors);
|
||||
layer_count = static_cast<u32>((std::max)(num_layers, 1));
|
||||
if (runtime.device.IsKhrDynamicRenderingSupported()) {
|
||||
|
||||
@@ -133,7 +133,8 @@ public:
|
||||
};
|
||||
|
||||
[[nodiscard]] VkImageView GetOrCreateResolveShadow(VkImage msaa_image, VkFormat format,
|
||||
VkExtent2D extent, u32 layers);
|
||||
VkExtent2D extent, u32 layers,
|
||||
VkImageAspectFlags aspect);
|
||||
|
||||
[[nodiscard]] const ResolveShadow* GetValidResolveShadow(VkImage msaa_image) const;
|
||||
|
||||
@@ -233,6 +234,18 @@ public:
|
||||
return depth_attachment;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkImageView DepthResolveAttachment() const noexcept {
|
||||
return depth_resolve_attachment;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkResolveModeFlagBits DepthResolveMode() const noexcept {
|
||||
return depth_resolve_mode;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkResolveModeFlagBits StencilResolveMode() const noexcept {
|
||||
return stencil_resolve_mode;
|
||||
}
|
||||
|
||||
[[nodiscard]] VkFormat DepthAttachmentFormat() const noexcept {
|
||||
return depth_attachment_format;
|
||||
}
|
||||
@@ -312,6 +325,9 @@ private:
|
||||
std::array<VkImageView, NUM_RT> color_resolve_attachments{};
|
||||
std::array<VkResolveModeFlagBits, NUM_RT> color_resolve_modes{};
|
||||
VkImageView depth_attachment{};
|
||||
VkImageView depth_resolve_attachment{};
|
||||
VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE;
|
||||
VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE;
|
||||
VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED;
|
||||
u32 num_color_attachments = 0;
|
||||
u32 layer_count = 1;
|
||||
|
||||
@@ -1120,6 +1120,11 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES_KHR;
|
||||
SetNext(next, properties.maintenance5);
|
||||
}
|
||||
if (instance_version >= VK_API_VERSION_1_2) {
|
||||
properties.depth_stencil_resolve.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
|
||||
SetNext(next, properties.depth_stencil_resolve);
|
||||
}
|
||||
|
||||
// Perform the property fetch.
|
||||
physical.GetProperties2(properties2);
|
||||
|
||||
@@ -1006,6 +1006,26 @@ FN_MAX_LIMIT_LIST
|
||||
return ENABLE_DYNAMIC_RENDERING && extensions.dynamic_rendering;
|
||||
}
|
||||
|
||||
/// Returns the resolve mode to use for multisampled depth.
|
||||
VkResolveModeFlagBits GetDepthResolveMode() const {
|
||||
return PickResolveMode(properties.depth_stencil_resolve.supportedDepthResolveModes);
|
||||
}
|
||||
|
||||
/// Same as GetDepthResolveMode, for the stencil aspect.
|
||||
VkResolveModeFlagBits GetStencilResolveMode() const {
|
||||
return PickResolveMode(properties.depth_stencil_resolve.supportedStencilResolveModes);
|
||||
}
|
||||
|
||||
/// Returns true if depth and stencil may resolve with independent modes.
|
||||
bool IsIndependentResolveSupported() const {
|
||||
return properties.depth_stencil_resolve.independentResolve == VK_TRUE;
|
||||
}
|
||||
|
||||
/// Returns true if one aspect may resolve while the other does not.
|
||||
bool IsIndependentResolveNoneSupported() const {
|
||||
return properties.depth_stencil_resolve.independentResolveNone == VK_TRUE;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_KHR_maintenance4.
|
||||
bool IsKhrMaintenance4Supported() const {
|
||||
return extensions.maintenance4;
|
||||
@@ -1087,6 +1107,22 @@ FN_MAX_LIMIT_LIST
|
||||
void ShutdownGPULogging();
|
||||
|
||||
private:
|
||||
/// Picks a usable resolve mode out of a supported-modes mask. SAMPLE_ZERO is preferred because
|
||||
/// it is the only mode the spec guarantees whenever any depth/stencil resolve is supported,
|
||||
/// and averaging depth samples is not meaningful for depth testing anyway.
|
||||
static VkResolveModeFlagBits PickResolveMode(VkResolveModeFlags supported) {
|
||||
if ((supported & VK_RESOLVE_MODE_SAMPLE_ZERO_BIT) != 0) {
|
||||
return VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
|
||||
}
|
||||
if ((supported & VK_RESOLVE_MODE_MIN_BIT) != 0) {
|
||||
return VK_RESOLVE_MODE_MIN_BIT;
|
||||
}
|
||||
if ((supported & VK_RESOLVE_MODE_MAX_BIT) != 0) {
|
||||
return VK_RESOLVE_MODE_MAX_BIT;
|
||||
}
|
||||
return VK_RESOLVE_MODE_NONE;
|
||||
}
|
||||
|
||||
/// Checks if the physical device is suitable and configures the object state
|
||||
/// with all necessary info about its properties.
|
||||
bool GetSuitability(bool requires_swapchain);
|
||||
@@ -1176,6 +1212,7 @@ private:
|
||||
VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control{};
|
||||
VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback{};
|
||||
VkPhysicalDeviceMaintenance5PropertiesKHR maintenance5{};
|
||||
VkPhysicalDeviceDepthStencilResolveProperties depth_stencil_resolve{};
|
||||
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user