mesa/src/asahi/compiler/agx_lower_uniform_sources.c

62 lines
1.6 KiB
C

/*
* Copyright 2023 Alyssa Rosenzweig
* SPDX-License-Identifier: MIT
*/
#include "agx_builder.h"
#include "agx_compiler.h"
/*
* Not all instructions can take uniforms. Memory instructions can take
* uniforms, but only for their base (first) source and only in the
* low-half of the uniform file.
*
* This pass lowers invalid uniforms.
*/
static bool
should_lower(enum agx_opcode op, agx_index uniform, unsigned src_index)
{
if (uniform.type != AGX_INDEX_UNIFORM)
return false;
/* Some instructions only seem able to access uniforms in the low half */
bool high = uniform.value >= 256;
switch (op) {
case AGX_OPCODE_TEXTURE_LOAD:
case AGX_OPCODE_TEXTURE_SAMPLE:
return src_index != 1;
case AGX_OPCODE_DEVICE_LOAD:
return src_index != 0 || high;
case AGX_OPCODE_DEVICE_STORE:
case AGX_OPCODE_ATOMIC:
return src_index != 1 || high;
case AGX_OPCODE_LOCAL_LOAD:
return src_index != 0;
case AGX_OPCODE_LOCAL_STORE:
return src_index != 1;
case AGX_OPCODE_ZS_EMIT:
case AGX_OPCODE_ST_TILE:
case AGX_OPCODE_LD_TILE:
case AGX_OPCODE_BLOCK_IMAGE_STORE:
case AGX_OPCODE_UNIFORM_STORE:
case AGX_OPCODE_ST_VARY:
case AGX_OPCODE_LOCAL_ATOMIC:
return true;
default:
return false;
}
}
void
agx_lower_uniform_sources(agx_context *ctx)
{
agx_foreach_instr_global_safe(ctx, I) {
agx_builder b = agx_init_builder(ctx, agx_before_instr(I));
agx_foreach_src(I, s) {
if (should_lower(I->op, I->src[s], s))
I->src[s] = agx_mov(&b, I->src[s]);
}
}
}