#include "midgard_ops.h"
#include "helpers.h"
#include "compiler.h"
+#include "midgard_quirks.h"
#include "disassemble.h"
return PAN_SYSVAL(SSBO, uindex);
}
+static int
+midgard_sysval_for_sampler(nir_intrinsic_instr *instr)
+{
+ /* TODO: indirect samplers !!! */
+ nir_src index = instr->src[0];
+ assert(nir_src_is_const(index));
+ uint32_t uindex = nir_src_as_uint(index);
+
+ return PAN_SYSVAL(SAMPLER, uindex);
+}
+
static int
midgard_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr)
{
case nir_intrinsic_load_ssbo:
case nir_intrinsic_store_ssbo:
return midgard_sysval_for_ssbo(instr);
+ case nir_intrinsic_load_sampler_lod_parameters_pan:
+ return midgard_sysval_for_sampler(instr);
default:
return ~0;
}
/* Flushes undefined values to zero */
static void
-optimise_nir(nir_shader *nir)
+optimise_nir(nir_shader *nir, unsigned quirks)
{
bool progress;
unsigned lower_flrp =
nir_lower_tex_options lower_tex_options = {
.lower_txs_lod = true,
- .lower_txp = ~0
+ .lower_txp = ~0,
+ .lower_tex_without_implicit_lod =
+ (quirks & MIDGARD_EXPLICIT_LOD),
};
NIR_PASS(progress, nir, nir_lower_tex, &lower_tex_options);
+ /* T720 is broken. */
+
+ if (quirks & MIDGARD_BROKEN_LOD)
+ NIR_PASS_V(nir, midgard_nir_lod_errata);
+
do {
progress = false;
{
/* TODO: half-floats */
- midgard_instruction ins = m_ld_ubo_int4(dest, offset);
-
- /* TODO: Don't split */
- ins.load_store.varying_parameters = (offset & 0x7F) << 3;
- ins.load_store.address = offset >> 7;
+ midgard_instruction ins = m_ld_ubo_int4(dest, 0);
+ ins.constants[0] = offset;
mir_set_intr_mask(instr, &ins, true);
if (indirect_offset) {
* different semantics than T760 and up */
midgard_instruction ld = m_ld_color_buffer_8(reg, 0);
- bool old_blend = ctx->gpu_id < 0x750;
+ bool old_blend = ctx->quirks & MIDGARD_OLD_BLEND;
if (instr->intrinsic == nir_intrinsic_load_output_u8_as_fp16_pan) {
ld.load_store.op = old_blend ?
case nir_intrinsic_store_raw_output_pan:
assert (ctx->stage == MESA_SHADER_FRAGMENT);
reg = nir_src_index(ctx, &instr->src[0]);
- emit_fragment_store(ctx, reg, 0);
+
+ if (ctx->quirks & MIDGARD_OLD_BLEND) {
+ /* Suppose reg = qr0.xyzw. That means 4 8-bit ---> 1 32-bit. So
+ * reg = r0.x. We want to splatter. So we can do a 32-bit move
+ * of:
+ *
+ * imov r0.xyzw, r0.xxxx
+ */
+
+ unsigned expanded = make_compiler_temp(ctx);
+
+ midgard_instruction splatter = v_mov(reg, expanded);
+
+ for (unsigned c = 0; c < 16; ++c)
+ splatter.swizzle[1][c] = 0;
+
+ emit_mir_instruction(ctx, splatter);
+ emit_fragment_store(ctx, expanded, ctx->blend_rt);
+ } else
+ emit_fragment_store(ctx, reg, ctx->blend_rt);
break;
case nir_intrinsic_load_viewport_scale:
case nir_intrinsic_load_viewport_offset:
case nir_intrinsic_load_num_work_groups:
+ case nir_intrinsic_load_sampler_lod_parameters_pan:
emit_sysval_read(ctx, &instr->instr, ~0, 3);
break;
static void
emit_tex(compiler_context *ctx, nir_tex_instr *instr)
{
- /* Fixup op, since only textureLod is permitted in VS on later Midgard
- * but NIR can give generic tex in some cases (which confuses the
- * hardware). Interestingly, early Midgard lines up with NIR */
-
- bool is_vertex = ctx->stage == MESA_SHADER_VERTEX;
-
- if (is_vertex && instr->op == nir_texop_tex && ctx->gpu_id >= 0x750)
- instr->op = nir_texop_txl;
-
switch (instr->op) {
case nir_texop_tex:
case nir_texop_txb:
}
int
-midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_blend, unsigned gpu_id)
+midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_blend, unsigned blend_rt, unsigned gpu_id)
{
struct util_dynarray *compiled = &program->compiled;
ctx->stage = nir->info.stage;
ctx->is_blend = is_blend;
ctx->alpha_ref = program->alpha_ref;
- ctx->gpu_id = gpu_id;
+ ctx->blend_rt = blend_rt;
+ ctx->quirks = midgard_get_quirks(gpu_id);
/* Start off with a safe cutoff, allowing usage of all 16 work
* registers. Later, we'll promote uniform reads to uniform registers
/* Optimisation passes */
- optimise_nir(nir);
+ optimise_nir(nir, ctx->quirks);
if (midgard_debug & MIDGARD_DBG_SHADERS) {
nir_print_shader(nir, stdout);
/* Schedule! */
schedule_program(ctx);
+ mir_ra(ctx);
/* Now that all the bundles are scheduled and we can calculate block
* sizes, emit actual branch instructions rather than placeholders */