|
|
|
@ -107,7 +107,12 @@ void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, 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 = |
|
|
|
@ -116,58 +121,7 @@ void Scheduler::BeginRenderPassImpl(const Framebuffer* framebuffer, VkRenderPass |
|
|
|
GPU::Logging::GPULogger::GetInstance().LogRenderPassBegin(render_pass_info); |
|
|
|
} |
|
|
|
|
|
|
|
const u32 num_color = framebuffer->NumColorAttachments(); |
|
|
|
const bool has_depth = framebuffer->HasAspectDepthBit(); |
|
|
|
const bool has_stencil = framebuffer->HasAspectStencilBit(); |
|
|
|
const VkImageView depth_view = framebuffer->DepthAttachment(); |
|
|
|
const u32 layers = framebuffer->NumLayers(); |
|
|
|
std::array<VkRenderingAttachmentInfo, VideoCommon::NUM_RT> color_infos{}; |
|
|
|
for (u32 index = 0; index < num_color; ++index) { |
|
|
|
color_infos[index] = VkRenderingAttachmentInfo{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, |
|
|
|
.pNext = nullptr, |
|
|
|
.imageView = color_views[index], |
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.resolveMode = VK_RESOLVE_MODE_NONE, |
|
|
|
.resolveImageView = VK_NULL_HANDLE, |
|
|
|
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, |
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, |
|
|
|
.clearValue = {.color = {.float32 = {1.0f, 0.0f, 1.0f, 1.0f}}}, |
|
|
|
}; |
|
|
|
} |
|
|
|
const VkRenderingAttachmentInfo depth_info{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, |
|
|
|
.pNext = nullptr, |
|
|
|
.imageView = depth_view, |
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.resolveMode = VK_RESOLVE_MODE_NONE, |
|
|
|
.resolveImageView = VK_NULL_HANDLE, |
|
|
|
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, |
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, |
|
|
|
.clearValue = {}, |
|
|
|
}; |
|
|
|
Record([color_infos, depth_info, num_color, has_depth, has_stencil, layers, |
|
|
|
render_area](vk::CommandBuffer cmdbuf) { |
|
|
|
const VkRenderingInfo rendering_info{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, |
|
|
|
.pNext = nullptr, |
|
|
|
.flags = 0, |
|
|
|
.renderArea = |
|
|
|
{ |
|
|
|
.offset = {.x = 0, .y = 0}, |
|
|
|
.extent = render_area, |
|
|
|
}, |
|
|
|
.layerCount = layers, |
|
|
|
.viewMask = 0, |
|
|
|
.colorAttachmentCount = num_color, |
|
|
|
.pColorAttachments = color_infos.data(), |
|
|
|
.pDepthAttachment = has_depth ? &depth_info : nullptr, |
|
|
|
.pStencilAttachment = has_stencil ? &depth_info : nullptr, |
|
|
|
}; |
|
|
|
cmdbuf.BeginRendering(rendering_info); |
|
|
|
}); |
|
|
|
RecordDynamicBegin(false, true); |
|
|
|
num_renderpass_images = framebuffer->NumImages(); |
|
|
|
renderpass_images = framebuffer->Images(); |
|
|
|
renderpass_image_ranges = framebuffer->ImageRanges(); |
|
|
|
@ -281,9 +235,16 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) { |
|
|
|
attachment_views[index] = color_views[index]; |
|
|
|
} |
|
|
|
attachment_views[8] = framebuffer->DepthAttachment(); |
|
|
|
if (state.rendering && attachment_views == state.attachment_views && |
|
|
|
render_area.width == state.render_area.width && |
|
|
|
render_area.height == state.render_area.height) { |
|
|
|
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; |
|
|
|
return; |
|
|
|
} |
|
|
|
EndRenderPass(); |
|
|
|
@ -302,7 +263,16 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) { |
|
|
|
BeginRenderPassImpl(framebuffer, renderpass, nullptr, 0); |
|
|
|
} |
|
|
|
|
|
|
|
void Scheduler::RequestOutsideRenderPassOperationContext() { |
|
|
|
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; |
|
|
|
} |
|
|
|
EndRenderPass(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -466,6 +436,69 @@ void Scheduler::InvalidateState() { |
|
|
|
state_tracker.InvalidateCommandBufferState(); |
|
|
|
} |
|
|
|
|
|
|
|
void Scheduler::RecordDynamicBegin(bool resuming, bool suspending) { |
|
|
|
const std::array<VkImageView, 9> views = state.attachment_views; |
|
|
|
const u32 num_color = state.num_color; |
|
|
|
const bool has_depth = state.has_depth; |
|
|
|
const bool has_stencil = state.has_stencil; |
|
|
|
const u32 layers = state.layer_count; |
|
|
|
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) { |
|
|
|
std::array<VkRenderingAttachmentInfo, VideoCommon::NUM_RT> color_infos{}; |
|
|
|
for (u32 index = 0; index < num_color; ++index) { |
|
|
|
color_infos[index] = VkRenderingAttachmentInfo{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, |
|
|
|
.pNext = nullptr, |
|
|
|
.imageView = views[index], |
|
|
|
.imageLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
.resolveMode = VK_RESOLVE_MODE_NONE, |
|
|
|
.resolveImageView = VK_NULL_HANDLE, |
|
|
|
.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, |
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, |
|
|
|
.clearValue = {}, |
|
|
|
}; |
|
|
|
} |
|
|
|
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 = VK_ATTACHMENT_LOAD_OP_LOAD, |
|
|
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE, |
|
|
|
.clearValue = {}, |
|
|
|
}; |
|
|
|
const VkRenderingInfo rendering_info{ |
|
|
|
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO, |
|
|
|
.pNext = nullptr, |
|
|
|
.flags = flags, |
|
|
|
.renderArea = |
|
|
|
{ |
|
|
|
.offset = {.x = 0, .y = 0}, |
|
|
|
.extent = render_area, |
|
|
|
}, |
|
|
|
.layerCount = layers, |
|
|
|
.viewMask = 0, |
|
|
|
.colorAttachmentCount = num_color, |
|
|
|
.pColorAttachments = color_infos.data(), |
|
|
|
.pDepthAttachment = has_depth ? &depth_info : nullptr, |
|
|
|
.pStencilAttachment = has_stencil ? &depth_info : nullptr, |
|
|
|
}; |
|
|
|
cmdbuf.BeginRendering(rendering_info); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
void Scheduler::EndPendingOperations() { |
|
|
|
query_cache->CounterReset(VideoCommon::QueryType::ZPassPixelCount64); |
|
|
|
EndRenderPass(); |
|
|
|
@ -478,16 +511,29 @@ void Scheduler::EndRenderPass() |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount); |
|
|
|
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(); |
|
|
|
// 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); |
|
|
|
|
|
|
|
if (dynamic) { |
|
|
|
Record([](vk::CommandBuffer cmdbuf) { cmdbuf.EndRendering(); }); |
|
|
|
state.suspended = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
query_cache->CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, false); |
|
|
|
query_cache->NotifySegment(false); |
|
|
|
if (dynamic && state.suspended) { |
|
|
|
RecordDynamicBegin(true, false); |
|
|
|
} |
|
|
|
|
|
|
|
Record([num_images = num_renderpass_images, |
|
|
|
images = renderpass_images, |
|
|
|
@ -555,6 +601,7 @@ void Scheduler::EndRenderPass() |
|
|
|
state.framebuffer = VkFramebuffer{}; |
|
|
|
state.attachment_views = {}; |
|
|
|
state.rendering = false; |
|
|
|
state.suspended = false; |
|
|
|
num_renderpass_images = 0; |
|
|
|
} |
|
|
|
|
|
|
|
|