mesa/src/panfrost/util/pan_lower_xfb.c
Alyssa Rosenzweig 15257b65c6 treewide: use nir_metadata_control_flow
Via Coccinelle patch:

    @@
    @@

    -nir_metadata_block_index | nir_metadata_dominance
    +nir_metadata_control_flow

...plus some manual fixups for call sites missed by coccinelle.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Acked-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Juan A. Suarez Romero <jasuarez@igalia.com> [broadcom]
Acked-by: Vasily Khoruzhick <anarsoul@gmail.com> [lima]
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29745>
2024-06-17 16:28:14 -04:00

105 lines
3.6 KiB
C

/*
* Copyright (C) 2022 Collabora Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "compiler/nir/nir_builder.h"
#include "pan_ir.h"
static void
lower_xfb_output(nir_builder *b, nir_intrinsic_instr *intr,
unsigned start_component, unsigned num_components,
unsigned buffer, unsigned offset_words)
{
assert(buffer < MAX_XFB_BUFFERS);
assert(nir_intrinsic_component(intr) == 0); // TODO
/* Transform feedback info in units of words, convert to bytes. */
uint16_t stride = b->shader->info.xfb_stride[buffer] * 4;
assert(stride != 0);
uint16_t offset = offset_words * 4;
nir_def *index = nir_iadd(
b, nir_imul(b, nir_load_instance_id(b), nir_load_num_vertices(b)),
nir_load_vertex_id_zero_base(b));
BITSET_SET(b->shader->info.system_values_read,
SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
BITSET_SET(b->shader->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID);
nir_def *buf = nir_load_xfb_address(b, 64, .base = buffer);
nir_def *addr = nir_iadd(
b, buf,
nir_u2u64(b, nir_iadd_imm(b, nir_imul_imm(b, index, stride), offset)));
nir_def *src = intr->src[0].ssa;
nir_def *value =
nir_channels(b, src, BITFIELD_MASK(num_components) << start_component);
nir_store_global(b, addr, 4, value, BITFIELD_MASK(num_components));
}
static bool
lower_xfb(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *data)
{
/* In transform feedback programs, vertex ID becomes zero-based, so apply
* that lowering even on Valhall.
*/
if (intr->intrinsic == nir_intrinsic_load_vertex_id) {
b->cursor = nir_instr_remove(&intr->instr);
nir_def *repl =
nir_iadd(b, nir_load_vertex_id_zero_base(b), nir_load_first_vertex(b));
nir_def_rewrite_uses(&intr->def, repl);
return true;
}
if (intr->intrinsic != nir_intrinsic_store_output)
return false;
bool progress = false;
b->cursor = nir_before_instr(&intr->instr);
for (unsigned i = 0; i < 2; ++i) {
nir_io_xfb xfb =
i ? nir_intrinsic_io_xfb2(intr) : nir_intrinsic_io_xfb(intr);
for (unsigned j = 0; j < 2; ++j) {
if (!xfb.out[j].num_components)
continue;
lower_xfb_output(b, intr, i * 2 + j, xfb.out[j].num_components,
xfb.out[j].buffer, xfb.out[j].offset);
progress = true;
}
}
nir_instr_remove(&intr->instr);
return progress;
}
bool
pan_lower_xfb(nir_shader *nir)
{
return nir_shader_intrinsics_pass(
nir, lower_xfb, nir_metadata_control_flow, NULL);
}