tu: Fix GRAS_BIN_FOVEAT* programming with more than 1 layer

Similar to when patching load/store coordinates, we have to convert the
layer to the view, splatting view 0 to all layers when there is more
than 1 layer and FDM-per-layer is not enabled.

Fixes upcoming new test
dEQP-VK.renderpasses.*.custom_resolve.*.fdm_nonsubsampled_multilayer_with_offset.

Fixes: b34b089ca1 ("tu: Use GRAS bin offset registers")
(cherry picked from commit b2c685af42)

Conflicts:
	src/freedreno/vulkan/tu_cmd_buffer.cc

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39003>
This commit is contained in:
Connor Abbott 2025-12-05 17:04:46 -05:00 committed by Dylan Baker
parent 34cda6974b
commit d0aed5d4b8
2 changed files with 15 additions and 6 deletions

View file

@ -1034,7 +1034,7 @@
"description": "tu: Fix GRAS_BIN_FOVEAT* programming with more than 1 layer",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "b34b089ca1327a5d48bc3cfceb9647c44763b52d",
"notes": null

View file

@ -1257,6 +1257,8 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
}
unsigned views = tu_fdm_num_layers(cmd);
unsigned layers = MAX2(cmd->state.pass->num_views,
cmd->state.framebuffer->layers);
bool bin_is_scaled = false;
if (fdm) {
@ -1271,7 +1273,7 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
bool bin_scale_en =
cmd->device->physical_device->info->a7xx.has_hw_bin_scaling &&
views <= MAX_HW_SCALED_VIEWS && !cmd->state.rp.shared_viewport &&
layers <= MAX_HW_SCALED_VIEWS && !cmd->state.rp.shared_viewport &&
bin_is_scaled;
/* We cannot support LRZ if we cannot use HW bin scaling and the bin is
@ -1386,16 +1388,23 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
if (bin_scale_en) {
VkExtent2D frag_areas[MAX_HW_SCALED_VIEWS];
for (unsigned i = 0; i < MAX_HW_SCALED_VIEWS; i++) {
if (i >= views) {
if (i >= layers) {
/* Make sure unused views aren't garbage */
frag_areas[i] = (VkExtent2D) {1, 1};
frag_offsets[i] = (VkOffset2D) { 0, 0 };
continue;
}
frag_areas[i] = tile->frag_areas[i];
frag_offsets[i].x = x1 - x1 / tile->frag_areas[i].width;
frag_offsets[i].y = y1 - y1 / tile->frag_areas[i].height;
/* The HW bin offset is always per-layer, whereas if there is
* more than 1 layer (i.e. layered rendering instead of
* multiview rendering) and FDM is not per-layer then all
* layers implicitly use the scale from FDM layer 0. We have to
* explicitly broadcast it here.
*/
unsigned view = MIN2(i, views - 1);
frag_areas[i] = tile->frag_areas[view];
frag_offsets[i].x = x1 - x1 / tile->frag_areas[view].width;
frag_offsets[i].y = y1 - y1 / tile->frag_areas[view].height;
}
tu_cs_emit_regs(cs, A7XX_GRAS_BIN_FOVEAT(