mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 05:15:14 +00:00
[vulkan] Add resume/supend bits on renderpass
This commit is contained in:
@@ -197,7 +197,7 @@ public:
|
||||
}
|
||||
|
||||
if (!host_visible) {
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([src_buffer = staging.buffer, src_offset = staging.offset,
|
||||
dst_buffer = *buffer, size_bytes](vk::CommandBuffer cmdbuf) {
|
||||
const VkBufferCopy copy{
|
||||
@@ -454,7 +454,7 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer,
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) {
|
||||
if (barrier) {
|
||||
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER,
|
||||
@@ -475,7 +475,7 @@ void BufferCacheRuntime::PreCopyBarrier() {
|
||||
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, READ_BARRIER);
|
||||
@@ -489,7 +489,7 @@ void BufferCacheRuntime::PostCopyBarrier() {
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
};
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, vk::PIPELINE_STAGE_GRAPHICS_COMPUTE,
|
||||
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,
|
||||
};
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([dest_buffer, offset, size, value](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, READ_BARRIER);
|
||||
@@ -695,7 +695,7 @@ vk::Buffer BufferCacheRuntime::CreateNullBuffer() {
|
||||
ret.SetObjectNameEXT("Null buffer");
|
||||
}
|
||||
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.RequestOutsideRenderPassOperationContext(true);
|
||||
scheduler.Record([buffer = *ret](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.FillBuffer(buffer, 0, VK_WHOLE_SIZE, 0);
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
// Log render pass end
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogRenderPassEnd();
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
|
||||
/// Requests the current execution context to be able to execute operations only allowed outside
|
||||
/// of a renderpass.
|
||||
void RequestOutsideRenderPassOperationContext();
|
||||
void RequestOutsideRenderPassOperationContext(bool allow_suspend = false);
|
||||
|
||||
/// Returns true when a render pass is currently active in the scheduler state.
|
||||
bool IsRenderPassActive() const {
|
||||
@@ -254,6 +254,11 @@ private:
|
||||
VkExtent2D render_area = {0, 0};
|
||||
GraphicsPipeline* graphics_pipeline = nullptr;
|
||||
bool rendering = false;
|
||||
bool suspended = false;
|
||||
u32 num_color = 0;
|
||||
bool has_depth = false;
|
||||
bool has_stencil = false;
|
||||
u32 layer_count = 1;
|
||||
bool is_rescaling = false;
|
||||
bool rescaling_defined = false;
|
||||
bool needs_state_enable_refresh = false;
|
||||
@@ -284,6 +289,8 @@ private:
|
||||
|
||||
void EndPendingOperations();
|
||||
|
||||
void RecordDynamicBegin(bool resuming, bool suspending);
|
||||
|
||||
void EndRenderPass();
|
||||
|
||||
void AcquireNewChunk();
|
||||
|
||||
Reference in New Issue
Block a user