Browse Source

[TEST] Wire MSAA resolve to dynamic rendering native resolve

tiled-gpu
CamilleLaVey 2 weeks ago
parent
commit
e058a15074
  1. 25
      src/video_core/renderer_vulkan/vk_scheduler.cpp
  2. 3
      src/video_core/renderer_vulkan/vk_scheduler.h
  3. 64
      src/video_core/renderer_vulkan/vk_texture_cache.cpp
  4. 11
      src/video_core/renderer_vulkan/vk_texture_cache.h

25
src/video_core/renderer_vulkan/vk_scheduler.cpp

@ -104,6 +104,9 @@ void Scheduler::BeginDynamicRendering(const Framebuffer* framebuffer, const Defe
state.renderpass = VkRenderPass{}; state.renderpass = VkRenderPass{};
state.framebuffer = VkFramebuffer{}; state.framebuffer = VkFramebuffer{};
state.attachment_views = attachment_views; state.attachment_views = attachment_views;
state.color_resolve_views = framebuffer->ColorResolveAttachments();
state.color_resolve_modes = framebuffer->ColorResolveModes();
state.discards_msaa_color = framebuffer->DiscardsMsaaColor();
state.render_area = render_area; state.render_area = render_area;
state.num_color = framebuffer->NumColorAttachments(); state.num_color = framebuffer->NumColorAttachments();
state.has_depth = framebuffer->HasAspectDepthBit(); state.has_depth = framebuffer->HasAspectDepthBit();
@ -432,31 +435,41 @@ void Scheduler::InvalidateState() {
void Scheduler::RecordDynamicBegin(const DeferredClear* clear) { void Scheduler::RecordDynamicBegin(const DeferredClear* clear) {
const std::array<VkImageView, 9> views = state.attachment_views; const std::array<VkImageView, 9> views = state.attachment_views;
const std::array<VkImageView, 8> resolve_views = state.color_resolve_views;
const std::array<VkResolveModeFlagBits, 8> resolve_modes = state.color_resolve_modes;
const u32 num_color = state.num_color; const u32 num_color = state.num_color;
const bool has_depth = state.has_depth; const bool has_depth = state.has_depth;
const bool has_stencil = state.has_stencil; const bool has_stencil = state.has_stencil;
const u32 layers = state.layer_count; const u32 layers = state.layer_count;
const VkExtent2D render_area = state.render_area; const VkExtent2D render_area = state.render_area;
const u32 color_clear_mask = clear ? clear->color_clear_mask : 0u; const u32 color_clear_mask = clear ? clear->color_clear_mask : 0u;
const u32 color_discard_mask =
clear != nullptr && state.discards_msaa_color ? clear->color_clear_mask : 0u;
const std::array<VkClearValue, 8> color_clear_values = const std::array<VkClearValue, 8> color_clear_values =
clear ? clear->color_values : std::array<VkClearValue, 8>{}; clear ? clear->color_values : std::array<VkClearValue, 8>{};
const bool ds_clear = clear != nullptr && clear->depth_stencil; const bool ds_clear = clear != nullptr && clear->depth_stencil;
const VkClearValue ds_clear_value = clear ? clear->depth_stencil_value : VkClearValue{}; const VkClearValue ds_clear_value = clear ? clear->depth_stencil_value : VkClearValue{};
Record([views, num_color, has_depth, has_stencil, layers, render_area, color_clear_mask,
color_clear_values, ds_clear, ds_clear_value](vk::CommandBuffer cmdbuf) {
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](vk::CommandBuffer cmdbuf) {
std::array<VkRenderingAttachmentInfo, VideoCommon::NUM_RT> color_infos{}; std::array<VkRenderingAttachmentInfo, VideoCommon::NUM_RT> color_infos{};
for (u32 index = 0; index < num_color; ++index) { for (u32 index = 0; index < num_color; ++index) {
const bool clear_slot = ((color_clear_mask >> index) & 1u) != 0; const bool clear_slot = ((color_clear_mask >> index) & 1u) != 0;
const VkImageView resolve_view = resolve_views[index];
const bool has_resolve = resolve_view != VK_NULL_HANDLE;
const bool discard_slot = has_resolve && ((color_discard_mask >> index) & 1u) != 0;
color_infos[index] = VkRenderingAttachmentInfo{ color_infos[index] = VkRenderingAttachmentInfo{
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
.pNext = nullptr, .pNext = nullptr,
.imageView = views[index], .imageView = views[index],
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
.resolveMode = VK_RESOLVE_MODE_NONE,
.resolveImageView = VK_NULL_HANDLE,
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.resolveMode = has_resolve ? resolve_modes[index] : VK_RESOLVE_MODE_NONE,
.resolveImageView = resolve_view,
.resolveImageLayout =
has_resolve ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED,
.loadOp = clear_slot ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, .loadOp = clear_slot ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.storeOp = discard_slot ? VK_ATTACHMENT_STORE_OP_DONT_CARE
: VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = clear_slot ? color_clear_values[index] : VkClearValue{}, .clearValue = clear_slot ? color_clear_values[index] : VkClearValue{},
}; };
} }

3
src/video_core/renderer_vulkan/vk_scheduler.h

@ -251,9 +251,12 @@ private:
VkRenderPass renderpass{}; VkRenderPass renderpass{};
VkFramebuffer framebuffer{}; VkFramebuffer framebuffer{};
std::array<VkImageView, 9> attachment_views{}; std::array<VkImageView, 9> attachment_views{};
std::array<VkImageView, 8> color_resolve_views{};
std::array<VkResolveModeFlagBits, 8> color_resolve_modes{};
VkExtent2D render_area = {0, 0}; VkExtent2D render_area = {0, 0};
GraphicsPipeline* graphics_pipeline = nullptr; GraphicsPipeline* graphics_pipeline = nullptr;
bool rendering = false; bool rendering = false;
bool discards_msaa_color = false;
u32 num_color = 0; u32 num_color = 0;
bool has_depth = false; bool has_depth = false;
bool has_stencil = false; bool has_stencil = false;

64
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -1041,6 +1041,31 @@ VkImageView TextureCacheRuntime::GetOrCreateResolveShadow(VkImage msaa_image, Vk
shadow.extent = extent; shadow.extent = extent;
shadow.layers = layers; shadow.layers = layers;
shadow.up_to_date = true; shadow.up_to_date = true;
if (device.IsKhrDynamicRenderingSupported()) {
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([image = *shadow.image, layers](vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = 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,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = layers,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, barrier);
});
}
return *shadow.view; return *shadow.view;
} }
@ -2760,8 +2785,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
} }
renderpass_key.samples = samples; renderpass_key.samples = samples;
const bool do_resolve_color = const bool do_resolve_color =
samples != VK_SAMPLE_COUNT_1_BIT && num_colors > 0 && runtime.device.IsTiler() &&
!runtime.device.IsKhrDynamicRenderingSupported();
samples != VK_SAMPLE_COUNT_1_BIT && num_colors > 0 && runtime.device.IsTiler();
renderpass_key.resolve_color = do_resolve_color; renderpass_key.resolve_color = do_resolve_color;
discard_msaa_color = discard_msaa_color =
@ -2781,10 +2805,15 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
} }
const VkFormat vk_format = const VkFormat vk_format =
MaxwellToVK::SurfaceFormat(runtime.device, FormatType::Optimal, true, format).format; MaxwellToVK::SurfaceFormat(runtime.device, FormatType::Optimal, true, format).format;
color_resolve_modes[index] = VideoCore::Surface::IsPixelFormatInteger(format)
? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT
: VK_RESOLVE_MODE_AVERAGE_BIT;
if (ENABLE_MSAA_RESOLVE_CONSUME) { if (ENABLE_MSAA_RESOLVE_CONSUME) {
const VkImage msaa_image = images[rt_map[index]]; const VkImage msaa_image = images[rt_map[index]];
attachments.push_back(runtime.GetOrCreateResolveShadow(msaa_image, vk_format,
render_area, layers));
const VkImageView shadow_view = runtime.GetOrCreateResolveShadow(
msaa_image, vk_format, render_area, layers);
color_resolve_attachments[index] = shadow_view;
attachments.push_back(shadow_view);
continue; continue;
} }
VkImageCreateInfo resolve_ci{ VkImageCreateInfo resolve_ci{
@ -2823,6 +2852,33 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
.layerCount = layers, .layerCount = layers,
}, },
}); });
if (runtime.device.IsKhrDynamicRenderingSupported()) {
runtime.scheduler.RequestOutsideRenderPassOperationContext();
runtime.scheduler.Record([image = *resolve_image, layers](vk::CommandBuffer cmdbuf) {
const VkImageMemoryBarrier barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = 0,
.dstAccessMask = 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,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = layers,
},
};
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
barrier);
});
}
color_resolve_attachments[index] = *resolve_view;
attachments.push_back(*resolve_view); attachments.push_back(*resolve_view);
resolve_images.push_back(std::move(resolve_image)); resolve_images.push_back(std::move(resolve_image));
resolve_image_views.push_back(std::move(resolve_view)); resolve_image_views.push_back(std::move(resolve_view));

11
src/video_core/renderer_vulkan/vk_texture_cache.h

@ -207,6 +207,15 @@ public:
return color_attachment_formats; return color_attachment_formats;
} }
[[nodiscard]] const std::array<VkImageView, NUM_RT>& ColorResolveAttachments() const noexcept {
return color_resolve_attachments;
}
[[nodiscard]] const std::array<VkResolveModeFlagBits, NUM_RT>& ColorResolveModes()
const noexcept {
return color_resolve_modes;
}
[[nodiscard]] VkImageView DepthAttachment() const noexcept { [[nodiscard]] VkImageView DepthAttachment() const noexcept {
return depth_attachment; return depth_attachment;
} }
@ -283,6 +292,8 @@ private:
std::array<size_t, NUM_RT> rt_map{}; std::array<size_t, NUM_RT> rt_map{};
std::array<VkImageView, NUM_RT> color_attachments{}; std::array<VkImageView, NUM_RT> color_attachments{};
std::array<VkFormat, NUM_RT> color_attachment_formats{}; std::array<VkFormat, NUM_RT> color_attachment_formats{};
std::array<VkImageView, NUM_RT> color_resolve_attachments{};
std::array<VkResolveModeFlagBits, NUM_RT> color_resolve_modes{};
VkImageView depth_attachment{}; VkImageView depth_attachment{};
VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED; VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED;
u32 num_color_attachments = 0; u32 num_color_attachments = 0;

Loading…
Cancel
Save