mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-12 05:20:17 +00:00
gpu: Change sorting for ops
The previous algorithm would reverse the order of subpasses, whcih leads to unexpected behavior if dependent subpasses are not added as children of a subpass, but just as a previous subpass - like when a subpass is used multiple times later. An example for this is a shadow node with multiple shadows - the source of the shadow is used by the multiple shadows. So ensure that adjacent subpasses stay in the same order.
This commit is contained in:
parent
30e9d98f0d
commit
7431a58617
@ -216,6 +216,8 @@ gsk_gpu_frame_sort_render_pass (GskGpuFrame *self,
|
||||
GskGpuOp *op,
|
||||
SortData *sort_data)
|
||||
{
|
||||
SortData subpasses = { { NULL, NULL }, { NULL, NULL } };
|
||||
|
||||
while (op)
|
||||
{
|
||||
switch (op->op_class->stage)
|
||||
@ -240,40 +242,30 @@ gsk_gpu_frame_sort_render_pass (GskGpuFrame *self,
|
||||
break;
|
||||
|
||||
case GSK_GPU_STAGE_PASS:
|
||||
if (sort_data->command.first == NULL)
|
||||
sort_data->command.first = op;
|
||||
if (subpasses.command.first == NULL)
|
||||
subpasses.command.first = op;
|
||||
else
|
||||
sort_data->command.last->next = op;
|
||||
sort_data->command.last = op;
|
||||
subpasses.command.last->next = op;
|
||||
subpasses.command.last = op;
|
||||
op = op->next;
|
||||
break;
|
||||
|
||||
case GSK_GPU_STAGE_BEGIN_PASS:
|
||||
{
|
||||
SortData pass_data = { { NULL, NULL }, { op, op } };
|
||||
if (subpasses.command.first == NULL)
|
||||
subpasses.command.first = op;
|
||||
else
|
||||
subpasses.command.last->next = op;
|
||||
subpasses.command.last = op;
|
||||
|
||||
op = gsk_gpu_frame_sort_render_pass (self, op->next, &pass_data);
|
||||
|
||||
if (pass_data.upload.first)
|
||||
{
|
||||
if (sort_data->upload.last == NULL)
|
||||
sort_data->upload.last = pass_data.upload.last;
|
||||
else
|
||||
pass_data.upload.last->next = sort_data->upload.first;
|
||||
sort_data->upload.first = pass_data.upload.first;
|
||||
}
|
||||
if (sort_data->command.last == NULL)
|
||||
sort_data->command.last = pass_data.command.last;
|
||||
else
|
||||
pass_data.command.last->next = sort_data->command.first;
|
||||
sort_data->command.first = pass_data.command.first;
|
||||
}
|
||||
/* append subpass to existing subpasses */
|
||||
op = gsk_gpu_frame_sort_render_pass (self, op->next, &subpasses);
|
||||
break;
|
||||
|
||||
case GSK_GPU_STAGE_END_PASS:
|
||||
sort_data->command.last->next = op;
|
||||
sort_data->command.last = op;
|
||||
return op->next;
|
||||
op = op->next;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@ -281,6 +273,25 @@ gsk_gpu_frame_sort_render_pass (GskGpuFrame *self,
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/* prepend subpasses to the current pass */
|
||||
if (subpasses.upload.first)
|
||||
{
|
||||
if (sort_data->upload.first != NULL)
|
||||
subpasses.upload.last->next = sort_data->upload.first;
|
||||
else
|
||||
sort_data->upload.last = subpasses.upload.last;
|
||||
sort_data->upload.first = subpasses.upload.first;
|
||||
}
|
||||
if (subpasses.command.first)
|
||||
{
|
||||
if (sort_data->command.first != NULL)
|
||||
subpasses.command.last->next = sort_data->command.first;
|
||||
else
|
||||
sort_data->command.last = subpasses.command.last;
|
||||
sort_data->command.first = subpasses.command.first;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user