mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 22:38:05 +02:00
venus: move feedback on empty last batch to prior batch
For submissions with an empty last batch containing no cmd buffers but with semaphores as zink does, adding feedback to that batch would make it no longer empty and increase submission overhead on some drivers. Since feedback order is enforced by barriers, the feedback cmds can instead be appended to the previous batch (if it exists) so that the last batch remains empty. Signed-off-by: Juston Li <justonli@google.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27830>
This commit is contained in:
parent
0586a3fb22
commit
e57cf175e2
3 changed files with 85 additions and 2 deletions
|
|
@ -395,6 +395,11 @@ vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
|
|||
instance->enable_wsi_multi_plane_modifiers ? "yes" : "no");
|
||||
}
|
||||
|
||||
const char *engine_name = instance->base.base.app_info.engine_name;
|
||||
if (engine_name) {
|
||||
instance->engine_is_zink = strcmp(engine_name, "mesa zink") == 0;
|
||||
}
|
||||
|
||||
*pInstance = instance_handle;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ struct vn_instance {
|
|||
uint32_t renderer_api_version;
|
||||
uint32_t renderer_version;
|
||||
|
||||
bool engine_is_zink;
|
||||
|
||||
struct {
|
||||
mtx_t mutex;
|
||||
bool initialized;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "vn_device.h"
|
||||
#include "vn_device_memory.h"
|
||||
#include "vn_feedback.h"
|
||||
#include "vn_instance.h"
|
||||
#include "vn_physical_device.h"
|
||||
#include "vn_query_pool.h"
|
||||
#include "vn_renderer.h"
|
||||
|
|
@ -42,6 +43,7 @@ struct vn_queue_submission {
|
|||
|
||||
uint32_t cmd_count;
|
||||
uint32_t feedback_types;
|
||||
bool has_zink_sync_batch;
|
||||
const struct vn_device_memory *wsi_mem;
|
||||
struct vn_sync_payload_external external_payload;
|
||||
|
||||
|
|
@ -256,6 +258,62 @@ vn_get_signal_semaphore_counter(struct vn_queue_submission *submit,
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
vn_has_zink_sync_batch(struct vn_queue_submission *submit)
|
||||
{
|
||||
struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
|
||||
struct vn_device *dev = (void *)queue->base.base.base.device;
|
||||
struct vn_instance *instance = dev->instance;
|
||||
const uint32_t last_batch_index = submit->batch_count - 1;
|
||||
|
||||
if (!instance->engine_is_zink)
|
||||
return false;
|
||||
|
||||
if (!submit->batch_count || !last_batch_index ||
|
||||
vn_get_cmd_count(submit, last_batch_index))
|
||||
return false;
|
||||
|
||||
if (vn_get_wait_semaphore_count(submit, last_batch_index))
|
||||
return false;
|
||||
|
||||
const uint32_t signal_count =
|
||||
vn_get_signal_semaphore_count(submit, last_batch_index);
|
||||
for (uint32_t i = 0; i < signal_count; i++) {
|
||||
struct vn_semaphore *sem = vn_semaphore_from_handle(
|
||||
vn_get_signal_semaphore(submit, last_batch_index, i));
|
||||
if (sem->feedback.slot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
vn_fix_batch_cmd_count_for_zink_sync(struct vn_queue_submission *submit,
|
||||
uint32_t batch_index,
|
||||
uint32_t new_cmd_count)
|
||||
{
|
||||
/* If the last batch is a zink sync batch which is empty but contains
|
||||
* feedback, append the feedback to the previous batch instead so that
|
||||
* the last batch remains empty for perf.
|
||||
*/
|
||||
if (batch_index == submit->batch_count - 1 &&
|
||||
submit->has_zink_sync_batch) {
|
||||
if (submit->batch_type == VK_STRUCTURE_TYPE_SUBMIT_INFO_2) {
|
||||
VkSubmitInfo2 *batch =
|
||||
&submit->temp.submit2_batches[batch_index - 1];
|
||||
assert(batch->pCommandBufferInfos);
|
||||
batch->commandBufferInfoCount += new_cmd_count;
|
||||
} else {
|
||||
VkSubmitInfo *batch = &submit->temp.submit_batches[batch_index - 1];
|
||||
assert(batch->pCommandBuffers);
|
||||
batch->commandBufferCount += new_cmd_count;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
vn_semaphore_wait_external(struct vn_device *dev, struct vn_semaphore *sem);
|
||||
|
||||
|
|
@ -340,8 +398,16 @@ vn_queue_submission_count_batch_feedback(struct vn_queue_submission *submit,
|
|||
submit->cmd_count++;
|
||||
}
|
||||
|
||||
if (feedback_types)
|
||||
/* Space to copy the original cmds to append feedback to it.
|
||||
* If the last batch is a zink sync batch which is an empty batch with
|
||||
* sem feedback, feedback will be appended to the second to last batch
|
||||
* so also need to copy the second to last batch's original cmds even
|
||||
* if it doesn't have feedback itself.
|
||||
*/
|
||||
if (feedback_types || (batch_index == submit->batch_count - 2 &&
|
||||
submit->has_zink_sync_batch)) {
|
||||
submit->cmd_count += cmd_count;
|
||||
}
|
||||
}
|
||||
|
||||
submit->feedback_types |= feedback_types;
|
||||
|
|
@ -357,6 +423,9 @@ vn_queue_submission_prepare(struct vn_queue_submission *submit)
|
|||
if (fence && fence->feedback.slot)
|
||||
submit->feedback_types |= VN_FEEDBACK_TYPE_FENCE;
|
||||
|
||||
if (submit->batch_type != VK_STRUCTURE_TYPE_BIND_SPARSE_INFO)
|
||||
submit->has_zink_sync_batch = vn_has_zink_sync_batch(submit);
|
||||
|
||||
submit->external_payload.ring_idx = queue->ring_idx;
|
||||
|
||||
submit->wsi_mem = NULL;
|
||||
|
|
@ -640,6 +709,9 @@ vn_queue_submission_add_feedback_cmds(struct vn_queue_submission *submit,
|
|||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
if (vn_fix_batch_cmd_count_for_zink_sync(submit, batch_index,
|
||||
new_cmd_count))
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (feedback_types & VN_FEEDBACK_TYPE_FENCE) {
|
||||
|
|
@ -696,8 +768,12 @@ vn_queue_submission_setup_batch(struct vn_queue_submission *submit,
|
|||
|
||||
/* If the batch has qfb, sfb or ffb, copy the original commands and append
|
||||
* feedback cmds.
|
||||
* If this is the second to last batch and the last batch a zink sync batch
|
||||
* which is empty but has feedback, also copy the original commands for
|
||||
* this batch so that the last batch's feedback can be appended to it.
|
||||
*/
|
||||
if (extra_cmd_count) {
|
||||
if (extra_cmd_count || (batch_index == submit->batch_count - 2 &&
|
||||
submit->has_zink_sync_batch)) {
|
||||
const size_t cmd_size = vn_get_cmd_size(submit);
|
||||
const size_t total_cmd_size = cmd_count * cmd_size;
|
||||
/* copy only needed for non-empty batches */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue