From a29b5857f7dbdf3e8d1ffb11145bcf809bdfdd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Tue, 1 Apr 2025 13:03:19 +0200 Subject: [PATCH] nir/xfb: Preserve some xfb information when gathering from intrinsics. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to remember which streamout buffers and streams were enabled, even if the shader doesn't actually write any outputs to them, because the API requires that we count vertices created by this shader towards queries against those streams. That information can be gathered by nir_gather_xfb_info_with_varyings from the original NIR I/O variables that we get from the frontend, but it isn't included in any intrinsics so would be otherwise lost here. Cc: mesa-stable Reviewed-by: Marek Olšák Reviewed-by: Samuel Pitoiset Part-of: --- src/compiler/nir/nir_gather_xfb_info.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/compiler/nir/nir_gather_xfb_info.c b/src/compiler/nir/nir_gather_xfb_info.c index 0e23a9fe1a2..0565900fb05 100644 --- a/src/compiler/nir/nir_gather_xfb_info.c +++ b/src/compiler/nir/nir_gather_xfb_info.c @@ -447,6 +447,31 @@ nir_gather_xfb_info_from_intrinsics(nir_shader *nir) for (unsigned i = 0; i < count; i++) info->buffers[outputs[i].buffer].varying_count++; + /* Preserve some info from the pre-existing xfb info if the shader had any. */ + if (nir->xfb_info) { + /* We need to remember which streamout buffers and streams were enabled, + * even if the shader doesn't actually write any outputs to them, + * because the API requires that we count vertices created by this shader + * towards queries against those streams. + * + * That information can be gathered by nir_gather_xfb_info_with_varyings + * from the original NIR I/O variables that we get from the frontend, + * but it isn't included in any intrinsics so would be otherwise lost here. + * + * Illustrated by the following test cases: + * dEQP-VK.transform_feedback.simple.multiquery_omit_write_* + */ + const uint32_t buffers_not_written = nir->xfb_info->buffers_written & ~info->buffers_written; + u_foreach_bit(buffer, buffers_not_written) { + const uint32_t stream = nir->xfb_info->buffer_to_stream[buffer]; + info->streams_written |= BITFIELD_BIT(stream); + info->buffers_written |= BITFIELD_BIT(buffer); + info->buffer_to_stream[buffer] = stream; + info->buffers[buffer].stride = nir->xfb_info->buffers[buffer].stride; + info->buffers[buffer].varying_count = 0; + } + } + /* Replace original xfb info. */ ralloc_free(nir->xfb_info); nir->xfb_info = info;