mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Fixes and optimizations to mobile renderer
* Only apply final actions to attachments used in the last pass. * Fixes to draw list final action (was using continue instead of read/drop). * Profiling regions inside draw lists now properly throw errors. * Ability to enable gpu profile printing from project settings. (used to debug).
This commit is contained in:
parent
18bd0fee5a
commit
ca117910da
8 changed files with 140 additions and 67 deletions
|
@ -3299,13 +3299,25 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
// Also, each UNDEFINED will do an immediate layout transition (write), s.t. we must ensure execution synchronization vs.
|
||||
// the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
|
||||
// stage
|
||||
|
||||
switch (is_depth ? p_initial_depth_action : p_initial_action) {
|
||||
case INITIAL_ACTION_CLEAR_REGION:
|
||||
case INITIAL_ACTION_CLEAR: {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
|
||||
dependency_from_external.srcStageMask |= reading_stages;
|
||||
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
} else if (p_attachments[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
dependency_from_external.srcStageMask |= reading_stages;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
|
||||
dependency_from_external.srcStageMask |= reading_stages;
|
||||
}
|
||||
} break;
|
||||
case INITIAL_ACTION_KEEP: {
|
||||
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
|
@ -3363,7 +3375,58 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
}
|
||||
}
|
||||
|
||||
switch (is_depth ? p_final_depth_action : p_final_action) {
|
||||
bool used_last = false;
|
||||
|
||||
{
|
||||
int last_pass = p_passes.size() - 1;
|
||||
|
||||
if (is_depth) {
|
||||
//likely missing depth resolve?
|
||||
if (p_passes[last_pass].depth_attachment == i) {
|
||||
used_last = true;
|
||||
}
|
||||
} else {
|
||||
if (p_passes[last_pass].resolve_attachments.size()) {
|
||||
//if using resolve attachments, check resolve attachments
|
||||
for (int j = 0; j < p_passes[last_pass].resolve_attachments.size(); j++) {
|
||||
if (p_passes[last_pass].resolve_attachments[j] == i) {
|
||||
used_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < p_passes[last_pass].color_attachments.size(); j++) {
|
||||
if (p_passes[last_pass].color_attachments[j] == i) {
|
||||
used_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!used_last) {
|
||||
for (int j = 0; j < p_passes[last_pass].preserve_attachments.size(); j++) {
|
||||
if (p_passes[last_pass].preserve_attachments[j] == i) {
|
||||
used_last = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FinalAction final_action = p_final_action;
|
||||
FinalAction final_depth_action = p_final_depth_action;
|
||||
|
||||
if (!used_last) {
|
||||
if (is_depth) {
|
||||
final_depth_action = FINAL_ACTION_DISCARD;
|
||||
|
||||
} else {
|
||||
final_action = FINAL_ACTION_DISCARD;
|
||||
}
|
||||
}
|
||||
|
||||
switch (is_depth ? final_depth_action : final_action) {
|
||||
case FINAL_ACTION_READ: {
|
||||
if (p_attachments[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
|
@ -3516,21 +3579,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
resolve_references.push_back(reference);
|
||||
}
|
||||
|
||||
LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
|
||||
|
||||
for (int j = 0; j < pass->preserve_attachments.size(); j++) {
|
||||
int32_t attachment = pass->preserve_attachments[j];
|
||||
|
||||
ERR_FAIL_COND_V_MSG(attachment == FramebufferPass::ATTACHMENT_UNUSED, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + "). Preserve attachments can't be unused.");
|
||||
|
||||
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + ").");
|
||||
ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass.");
|
||||
|
||||
attachment_last_pass[attachment] = i;
|
||||
|
||||
preserve_references.push_back(attachment);
|
||||
}
|
||||
|
||||
VkAttachmentReference &depth_stencil_reference = depth_reference_array[i];
|
||||
|
||||
if (pass->depth_attachment != FramebufferPass::ATTACHMENT_UNUSED) {
|
||||
|
@ -3554,6 +3602,22 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
|||
depth_stencil_reference.layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
LocalVector<uint32_t> &preserve_references = preserve_reference_array[i];
|
||||
|
||||
for (int j = 0; j < pass->preserve_attachments.size(); j++) {
|
||||
int32_t attachment = pass->preserve_attachments[j];
|
||||
|
||||
ERR_FAIL_COND_V_MSG(attachment == FramebufferPass::ATTACHMENT_UNUSED, VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + "). Preserve attachments can't be unused.");
|
||||
|
||||
ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), preserve attachment (" + itos(j) + ").");
|
||||
|
||||
if (attachment_last_pass[attachment] != i) {
|
||||
//preserve can still be used to keep depth or color from being discarded after use
|
||||
attachment_last_pass[attachment] = i;
|
||||
preserve_references.push_back(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
VkSubpassDescription &subpass = subpasses[i];
|
||||
subpass.flags = 0;
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
|
@ -8864,6 +8928,7 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
|
|||
}
|
||||
|
||||
void RenderingDeviceVulkan::capture_timestamp(const String &p_name) {
|
||||
ERR_FAIL_COND_MSG(draw_list != nullptr, "Capturing timestamps during draw list creation is not allowed. Offending timestap was: " + p_name);
|
||||
ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements);
|
||||
|
||||
//this should be optional for profiling, else it will slow things down
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue