Browse Source

[TEST] 2nd stage on dynamic rendering implementation

tiled-gpu
CamilleLaVey 2 weeks ago
parent
commit
9694216ad7
  1. 28
      src/video_core/renderer_vulkan/blit_image.cpp
  2. 18
      src/video_core/renderer_vulkan/blit_image.h
  3. 12
      src/video_core/renderer_vulkan/vk_buffer_cache.cpp
  4. 1
      src/video_core/renderer_vulkan/vk_rasterizer.cpp
  5. 151
      src/video_core/renderer_vulkan/vk_scheduler.cpp
  6. 8
      src/video_core/renderer_vulkan/vk_scheduler.h
  7. 3
      src/video_core/renderer_vulkan/vk_texture_cache.cpp

28
src/video_core/renderer_vulkan/blit_image.cpp

@ -709,10 +709,12 @@ void BlitImageHelper::BlitColorMSAA(const Framebuffer* dst_framebuffer,
const BlitMSAAPipelineKey key{ const BlitMSAAPipelineKey key{
.renderpass = dst_framebuffer->RenderPass(), .renderpass = dst_framebuffer->RenderPass(),
.samples = dst_framebuffer->Samples(), .samples = dst_framebuffer->Samples(),
.color_formats = dst_framebuffer->ColorAttachmentFormats(),
.depth_format = dst_framebuffer->DepthAttachmentFormat(),
}; };
const VkPipelineLayout layout = *one_texture_pipeline_layout; const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
const VkPipeline pipeline = FindOrEmplaceBlitColorMSAAPipeline(key);
const VkPipeline pipeline = FindOrEmplaceBlitColorMSAAPipeline(key, dst_framebuffer);
const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D); const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
RecordShaderReadBarrier(scheduler, src_image_view); RecordShaderReadBarrier(scheduler, src_image_view);
@ -736,7 +738,7 @@ void BlitImageHelper::ResolveDepthStencil(const Framebuffer* dst_framebuffer,
const bool resolve_stencil = const bool resolve_stencil =
dst_framebuffer->HasAspectStencilBit() && device.IsExtShaderStencilExportSupported(); dst_framebuffer->HasAspectStencilBit() && device.IsExtShaderStencilExportSupported();
const VkPipeline pipeline = const VkPipeline pipeline =
FindOrEmplaceResolveDepthStencilPipeline(dst_framebuffer->RenderPass(), resolve_stencil);
FindOrEmplaceResolveDepthStencilPipeline(dst_framebuffer, resolve_stencil);
const VkPipelineLayout layout = const VkPipelineLayout layout =
resolve_stencil ? *two_textures_pipeline_layout : *one_texture_pipeline_layout; resolve_stencil ? *two_textures_pipeline_layout : *one_texture_pipeline_layout;
const VkSampler sampler = *nearest_sampler; const VkSampler sampler = *nearest_sampler;
@ -1382,12 +1384,14 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
return *clear_stencil_pipelines.back(); return *clear_stencil_pipelines.back();
} }
VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key) {
VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key,
const Framebuffer* framebuffer) {
const auto it = std::ranges::find(blit_msaa_color_keys, key); const auto it = std::ranges::find(blit_msaa_color_keys, key);
if (it != blit_msaa_color_keys.end()) { if (it != blit_msaa_color_keys.end()) {
return *blit_msaa_color_pipelines[std::distance(blit_msaa_color_keys.begin(), it)]; return *blit_msaa_color_pipelines[std::distance(blit_msaa_color_keys.begin(), it)];
} }
blit_msaa_color_keys.push_back(key); blit_msaa_color_keys.push_back(key);
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
const std::array stages = MakeStages(*full_screen_vert, *blit_color_msaa_frag); const std::array stages = MakeStages(*full_screen_vert, *blit_color_msaa_frag);
const VkPipelineMultisampleStateCreateInfo multisample_ci{ const VkPipelineMultisampleStateCreateInfo multisample_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
@ -1403,7 +1407,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPip
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
blit_msaa_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ blit_msaa_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.pNext = key.renderpass ? nullptr : &rendering_ci,
.flags = 0, .flags = 0,
.stageCount = static_cast<u32>(stages.size()), .stageCount = static_cast<u32>(stages.size()),
.pStages = stages.data(), .pStages = stages.data(),
@ -1425,22 +1429,28 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPip
return *blit_msaa_color_pipelines.back(); return *blit_msaa_color_pipelines.back();
} }
VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(VkRenderPass renderpass,
bool resolve_stencil) {
VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(
const Framebuffer* framebuffer, bool resolve_stencil) {
const VkRenderPass renderpass = framebuffer->RenderPass();
const ResolveDepthStencilPipelineKey key{
.renderpass = renderpass,
.depth_format = framebuffer->DepthAttachmentFormat(),
};
auto& keys = resolve_stencil ? resolve_depth_stencil_keys : resolve_depth_keys; auto& keys = resolve_stencil ? resolve_depth_stencil_keys : resolve_depth_keys;
auto& pipelines = resolve_stencil ? resolve_depth_stencil_pipelines : resolve_depth_pipelines; auto& pipelines = resolve_stencil ? resolve_depth_stencil_pipelines : resolve_depth_pipelines;
const auto it = std::ranges::find(keys, renderpass);
const auto it = std::ranges::find(keys, key);
if (it != keys.end()) { if (it != keys.end()) {
return *pipelines[std::distance(keys.begin(), it)]; return *pipelines[std::distance(keys.begin(), it)];
} }
keys.push_back(renderpass);
keys.push_back(key);
const VkPipelineRenderingCreateInfo rendering_ci = MakePipelineRenderingCreateInfo(framebuffer);
const std::array stages = const std::array stages =
MakeStages(*full_screen_vert, MakeStages(*full_screen_vert,
resolve_stencil ? *blit_depth_stencil_msaa_frag : *blit_depth_msaa_frag); resolve_stencil ? *blit_depth_stencil_msaa_frag : *blit_depth_msaa_frag);
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device); const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({ pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.pNext = nullptr,
.pNext = renderpass ? nullptr : &rendering_ci,
.flags = 0, .flags = 0,
.stageCount = static_cast<u32>(stages.size()), .stageCount = static_cast<u32>(stages.size()),
.pStages = stages.data(), .pStages = stages.data(),

18
src/video_core/renderer_vulkan/blit_image.h

@ -62,6 +62,15 @@ struct BlitMSAAPipelineKey {
VkRenderPass renderpass; VkRenderPass renderpass;
VkSampleCountFlagBits samples; VkSampleCountFlagBits samples;
std::array<VkFormat, VideoCommon::NUM_RT> color_formats;
VkFormat depth_format;
};
struct ResolveDepthStencilPipelineKey {
constexpr auto operator<=>(const ResolveDepthStencilPipelineKey&) const noexcept = default;
VkRenderPass renderpass;
VkFormat depth_format;
}; };
class BlitImageHelper { class BlitImageHelper {
@ -138,8 +147,9 @@ private:
[[nodiscard]] VkPipeline FindOrEmplaceClearStencilPipeline( [[nodiscard]] VkPipeline FindOrEmplaceClearStencilPipeline(
const BlitDepthStencilPipelineKey& key, const Framebuffer* framebuffer); const BlitDepthStencilPipelineKey& key, const Framebuffer* framebuffer);
[[nodiscard]] VkPipeline FindOrEmplaceMSAACopyPipeline(const MSAACopyPipelineKey& key); [[nodiscard]] VkPipeline FindOrEmplaceMSAACopyPipeline(const MSAACopyPipelineKey& key);
[[nodiscard]] VkPipeline FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key);
[[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline(VkRenderPass renderpass,
[[nodiscard]] VkPipeline FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPipelineKey& key,
const Framebuffer* framebuffer);
[[nodiscard]] VkPipeline FindOrEmplaceResolveDepthStencilPipeline(const Framebuffer* framebuffer,
bool resolve_stencil); bool resolve_stencil);
void ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer, void ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer* framebuffer,
@ -203,9 +213,9 @@ private:
std::vector<vk::Pipeline> msaa_copy_pipelines; std::vector<vk::Pipeline> msaa_copy_pipelines;
std::vector<BlitMSAAPipelineKey> blit_msaa_color_keys; std::vector<BlitMSAAPipelineKey> blit_msaa_color_keys;
std::vector<vk::Pipeline> blit_msaa_color_pipelines; std::vector<vk::Pipeline> blit_msaa_color_pipelines;
std::vector<VkRenderPass> resolve_depth_keys;
std::vector<ResolveDepthStencilPipelineKey> resolve_depth_keys;
std::vector<vk::Pipeline> resolve_depth_pipelines; std::vector<vk::Pipeline> resolve_depth_pipelines;
std::vector<VkRenderPass> resolve_depth_stencil_keys;
std::vector<ResolveDepthStencilPipelineKey> resolve_depth_stencil_keys;
std::vector<vk::Pipeline> resolve_depth_stencil_pipelines; std::vector<vk::Pipeline> resolve_depth_stencil_pipelines;
struct MSAACopyResources { struct MSAACopyResources {
u64 tick; u64 tick;

12
src/video_core/renderer_vulkan/vk_buffer_cache.cpp

@ -197,7 +197,7 @@ public:
} }
if (!host_visible) { if (!host_visible) {
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer = staging.buffer, src_offset = staging.offset, scheduler.Record([src_buffer = staging.buffer, src_offset = staging.offset,
dst_buffer = *buffer, size_bytes](vk::CommandBuffer cmdbuf) { dst_buffer = *buffer, size_bytes](vk::CommandBuffer cmdbuf) {
const VkBufferCopy copy{ const VkBufferCopy copy{
@ -454,7 +454,7 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
return; return;
} }
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) { scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) {
if (barrier) { if (barrier) {
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
@ -475,7 +475,7 @@ void BufferCacheRuntime::PreCopyBarrier() {
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
}; };
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) { scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT, cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER); 0, READ_BARRIER);
@ -489,7 +489,7 @@ void BufferCacheRuntime::PostCopyBarrier() {
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
}; };
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([](vk::CommandBuffer cmdbuf) { scheduler.Record([](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
0, WRITE_BARRIER); 0, WRITE_BARRIER);
@ -513,7 +513,7 @@ void BufferCacheRuntime::ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t si
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
}; };
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) { scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) {
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT, cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, READ_BARRIER); 0, READ_BARRIER);
@ -695,7 +695,7 @@ vk::Buffer BufferCacheRuntime::CreateNullBuffer() {
ret.SetObjectNameEXT("Null buffer"); ret.SetObjectNameEXT("Null buffer");
} }
scheduler.RequestOutsideRenderPassOperationContext(true);
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([buffer = *ret](vk::CommandBuffer cmdbuf) { scheduler.Record([buffer = *ret](vk::CommandBuffer cmdbuf) {
cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0); cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0);
}); });

1
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@ -423,7 +423,6 @@ void RasterizerVulkan::Clear(u32 layer_count) {
const bool can_defer_clear = ENABLE_DEFERRED_CLEAR && !regs.clear_control.use_scissor && const bool can_defer_clear = ENABLE_DEFERRED_CLEAR && !regs.clear_control.use_scissor &&
regs.clear_surface.layer == 0 && regs.clear_surface.layer == 0 &&
!scheduler.IsRenderPassActive() && !scheduler.IsRenderPassActive() &&
!device.IsKhrDynamicRenderingSupported() &&
(!use_color || color_full_channels) && ds_deferrable; (!use_color || color_full_channels) && ds_deferrable;
if (!can_defer_clear) { if (!can_defer_clear) {
scheduler.RequestRenderpass(framebuffer); scheduler.RequestRenderpass(framebuffer);

151
src/video_core/renderer_vulkan/vk_scheduler.cpp

@ -93,40 +93,44 @@ void Scheduler::DispatchWork() {
} }
} }
void Scheduler::BeginDynamicRendering(const Framebuffer* framebuffer, const DeferredClear* clear) {
const VkExtent2D render_area = framebuffer->RenderArea();
std::array<VkImageView, 9> attachment_views{};
const auto& color_views = framebuffer->ColorAttachments();
for (size_t index = 0; index < color_views.size(); ++index) {
attachment_views[index] = color_views[index];
}
attachment_views[8] = framebuffer->DepthAttachment();
state.renderpass = VkRenderPass{};
state.framebuffer = VkFramebuffer{};
state.attachment_views = attachment_views;
state.render_area = render_area;
state.num_color = framebuffer->NumColorAttachments();
state.has_depth = framebuffer->HasAspectDepthBit();
state.has_stencil = framebuffer->HasAspectStencilBit();
state.layer_count = framebuffer->NumLayers();
state.rendering = true;
if (GPU::Logging::IsActive() && Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string render_pass_info =
fmt::format("renderArea={}x{}, numImages={}", render_area.width, render_area.height,
framebuffer->NumImages());
GPU::Logging::GPULogger::GetInstance().LogRenderPassBegin(render_pass_info);
}
RecordDynamicBegin(clear);
num_renderpass_images = framebuffer->NumImages();
renderpass_images = framebuffer->Images();
renderpass_image_ranges = framebuffer->ImageRanges();
}
void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass, void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass,
const VkClearValue* clear_values, u32 clear_value_count) { const VkClearValue* clear_values, u32 clear_value_count) {
const VkExtent2D render_area = framebuffer->RenderArea();
if (device.IsKhrDynamicRenderingSupported()) { if (device.IsKhrDynamicRenderingSupported()) {
std::array<VkImageView, 9> attachment_views{};
const auto& color_views = framebuffer->ColorAttachments();
for (size_t index = 0; index < color_views.size(); ++index) {
attachment_views[index] = color_views[index];
}
attachment_views[8] = framebuffer->DepthAttachment();
state.renderpass = VkRenderPass{};
state.framebuffer = VkFramebuffer{};
state.attachment_views = attachment_views;
state.render_area = render_area;
state.num_color = framebuffer->NumColorAttachments();
state.has_depth = framebuffer->HasAspectDepthBit();
state.has_stencil = framebuffer->HasAspectStencilBit();
state.layer_count = framebuffer->NumLayers();
state.rendering = true;
state.suspended = false;
if (GPU::Logging::IsActive() && Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string render_pass_info =
fmt::format("renderArea={}x{}, numImages={}", render_area.width, render_area.height,
framebuffer->NumImages());
GPU::Logging::GPULogger::GetInstance().LogRenderPassBegin(render_pass_info);
}
RecordDynamicBegin(false, true);
num_renderpass_images = framebuffer->NumImages();
renderpass_images = framebuffer->Images();
renderpass_image_ranges = framebuffer->ImageRanges();
BeginDynamicRendering(framebuffer, nullptr);
return; return;
} }
const VkExtent2D render_area = framebuffer->RenderArea();
const VkFramebuffer framebuffer_handle = framebuffer->Handle(); const VkFramebuffer framebuffer_handle = framebuffer->Handle();
state.renderpass = renderpass; state.renderpass = renderpass;
state.framebuffer = framebuffer_handle; state.framebuffer = framebuffer_handle;
@ -173,6 +177,12 @@ void Scheduler::RealizeDeferredClear() {
const DeferredClear dc = deferred_clear; const DeferredClear dc = deferred_clear;
deferred_clear = {}; deferred_clear = {};
if (device.IsKhrDynamicRenderingSupported()) {
EndRenderPass();
BeginDynamicRendering(dc.framebuffer, &dc);
return;
}
std::array<VkClearValue, 9> clear_values{}; std::array<VkClearValue, 9> clear_values{};
u32 count = 0; u32 count = 0;
const RenderPassKey& base = dc.framebuffer->RenderPassKeyBase(); const RenderPassKey& base = dc.framebuffer->RenderPassKeyBase();
@ -235,20 +245,13 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
attachment_views[index] = color_views[index]; attachment_views[index] = color_views[index];
} }
attachment_views[8] = framebuffer->DepthAttachment(); attachment_views[8] = framebuffer->DepthAttachment();
const bool same_target = state.rendering &&
attachment_views == state.attachment_views &&
render_area.width == state.render_area.width &&
render_area.height == state.render_area.height;
if (same_target && !state.suspended) {
return;
}
if (same_target && state.suspended) {
RecordDynamicBegin(true, true);
state.suspended = false;
if (state.rendering && attachment_views == state.attachment_views &&
render_area.width == state.render_area.width &&
render_area.height == state.render_area.height) {
return; return;
} }
EndRenderPass(); EndRenderPass();
BeginRenderPassImpl(framebuffer, VkRenderPass{}, nullptr, 0);
BeginDynamicRendering(framebuffer, nullptr);
return; return;
} }
const VkRenderPass renderpass = framebuffer->RenderPass(); const VkRenderPass renderpass = framebuffer->RenderPass();
@ -263,16 +266,7 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
BeginRenderPassImpl(framebuffer, renderpass, nullptr, 0); BeginRenderPassImpl(framebuffer, renderpass, nullptr, 0);
} }
void Scheduler::RequestOutsideRenderPassOperationContext(bool allow_suspend) {
if (allow_suspend && device.IsKhrDynamicRenderingSupported() && state.rendering &&
!state.suspended) {
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
query_cache->NotifySegment(false);
Record([](vk::CommandBuffer cmdbuf) { cmdbuf.EndRendering(); });
state.suspended = true;
return;
}
void Scheduler::RequestOutsideRenderPassOperationContext() {
EndRenderPass(); EndRenderPass();
} }
@ -436,24 +430,23 @@ void Scheduler::InvalidateState() {
state_tracker.InvalidateCommandBufferState(); state_tracker.InvalidateCommandBufferState();
} }
void Scheduler::RecordDynamicBegin(bool resuming, bool suspending) {
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 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;
VkRenderingFlags flags = 0;
if (resuming) {
flags |= VK_RENDERING_RESUMING_BIT;
}
if (suspending) {
flags |= VK_RENDERING_SUSPENDING_BIT;
}
Record([views, num_color, has_depth, has_stencil, layers, render_area,
flags](vk::CommandBuffer cmdbuf) {
const u32 color_clear_mask = clear ? clear->color_clear_mask : 0u;
const std::array<VkClearValue, 8> color_clear_values =
clear ? clear->color_values : std::array<VkClearValue, 8>{};
const bool ds_clear = clear != nullptr && clear->depth_stencil;
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) {
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;
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,
@ -462,9 +455,9 @@ void Scheduler::RecordDynamicBegin(bool resuming, bool suspending) {
.resolveMode = VK_RESOLVE_MODE_NONE, .resolveMode = VK_RESOLVE_MODE_NONE,
.resolveImageView = VK_NULL_HANDLE, .resolveImageView = VK_NULL_HANDLE,
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.loadOp = 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 = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = {},
.clearValue = clear_slot ? color_clear_values[index] : VkClearValue{},
}; };
} }
const VkRenderingAttachmentInfo depth_info{ const VkRenderingAttachmentInfo depth_info{
@ -475,14 +468,14 @@ void Scheduler::RecordDynamicBegin(bool resuming, bool suspending) {
.resolveMode = VK_RESOLVE_MODE_NONE, .resolveMode = VK_RESOLVE_MODE_NONE,
.resolveImageView = VK_NULL_HANDLE, .resolveImageView = VK_NULL_HANDLE,
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, .resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
.loadOp = ds_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.clearValue = {},
.clearValue = ds_clear ? ds_clear_value : VkClearValue{},
}; };
const VkRenderingInfo rendering_info{ const VkRenderingInfo rendering_info{
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = flags,
.flags = 0,
.renderArea = .renderArea =
{ {
.offset = {.x = 0, .y = 0}, .offset = {.x = 0, .y = 0},
@ -511,29 +504,16 @@ void Scheduler::EndRenderPass()
return; return;
} }
const bool dynamic = device.IsKhrDynamicRenderingSupported();
if (!state.suspended) {
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
// Log render pass end
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
GPU::Logging::GPULogger::GetInstance().LogRenderPassEnd();
}
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
query_cache->NotifySegment(false);
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
if (dynamic) {
Record([](vk::CommandBuffer cmdbuf) { cmdbuf.EndRendering(); });
state.suspended = true;
}
// Log render pass end
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
GPU::Logging::GPULogger::GetInstance().LogRenderPassEnd();
} }
if (dynamic && state.suspended) {
RecordDynamicBegin(true, false);
}
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false);
query_cache->NotifySegment(false);
Record([num_images = num_renderpass_images, Record([num_images = num_renderpass_images,
images = renderpass_images, images = renderpass_images,
@ -601,7 +581,6 @@ void Scheduler::EndRenderPass()
state.framebuffer = VkFramebuffer{}; state.framebuffer = VkFramebuffer{};
state.attachment_views = {}; state.attachment_views = {};
state.rendering = false; state.rendering = false;
state.suspended = false;
num_renderpass_images = 0; num_renderpass_images = 0;
} }

8
src/video_core/renderer_vulkan/vk_scheduler.h

@ -67,7 +67,7 @@ public:
/// Requests the current execution context to be able to execute operations only allowed outside /// Requests the current execution context to be able to execute operations only allowed outside
/// of a renderpass. /// of a renderpass.
void RequestOutsideRenderPassOperationContext(bool allow_suspend = false);
void RequestOutsideRenderPassOperationContext();
/// Returns true when a render pass is currently active in the scheduler state. /// Returns true when a render pass is currently active in the scheduler state.
bool IsRenderPassActive() const { bool IsRenderPassActive() const {
@ -254,7 +254,6 @@ private:
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 suspended = 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;
@ -276,6 +275,9 @@ private:
void BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass, void BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass renderpass,
const VkClearValue* clear_values, u32 clear_value_count); const VkClearValue* clear_values, u32 clear_value_count);
/// Begins a dynamic rendering pass, optionally realizing a deferred clear via load ops.
void BeginDynamicRendering(const Framebuffer* framebuffer, const DeferredClear* clear);
/// If a deferred clear is pending. /// If a deferred clear is pending.
void RealizeDeferredClear(); void RealizeDeferredClear();
@ -289,7 +291,7 @@ private:
void EndPendingOperations(); void EndPendingOperations();
void RecordDynamicBegin(bool resuming, bool suspending);
void RecordDynamicBegin(const DeferredClear* clear);
void EndRenderPass(); void EndRenderPass();

3
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@ -2760,7 +2760,8 @@ 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();
samples != VK_SAMPLE_COUNT_1_BIT && num_colors > 0 && runtime.device.IsTiler() &&
!runtime.device.IsKhrDynamicRenderingSupported();
renderpass_key.resolve_color = do_resolve_color; renderpass_key.resolve_color = do_resolve_color;
discard_msaa_color = discard_msaa_color =

Loading…
Cancel
Save