pan/midgard: Introduce quirks checks

Rather than open-coding checks on gpu_id in the compiler, let's track
quirks applying to whatever we're compiling for, to allow us to manage
the complexity of many heterogenous GPUs in the compiler.

It was discovered that a workaround used on T720 is also required on
T820 (and presumably T830), so let's fix this. This will also decrease
friction as we continue improving T720 support.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
This commit is contained in:
Alyssa Rosenzweig 2019-11-19 20:55:42 -05:00 committed by Tomeu Vizoso
parent 614fba0ce1
commit fcf144d96a
5 changed files with 92 additions and 10 deletions

View File

@ -294,7 +294,8 @@ typedef struct compiler_context {
/* Bitmask of valid metadata */
unsigned metadata;
unsigned gpu_id;
/* Model-specific quirk set */
uint32_t quirks;
} compiler_context;
/* Per-block live_in/live_out */

View File

@ -34,6 +34,7 @@
#include "midgard.h"
#include "midgard-parse.h"
#include "midgard_ops.h"
#include "midgard_quirks.h"
#include "disassemble.h"
#include "helpers.h"
#include "util/half_float.h"
@ -1514,11 +1515,12 @@ disassemble_midgard(uint8_t *code, size_t size, unsigned gpu_id, gl_shader_stage
switch (midgard_word_types[tag]) {
case midgard_word_type_texture: {
/* Texturing uses ldst/work space on T720 */
bool has_texture_pipeline = gpu_id != 0x0720;
bool interpipe_aliasing =
midgard_get_quirks(gpu_id) & MIDGARD_INTERPIPE_REG_ALIASING;
print_texture_word(&words[i], tabs,
has_texture_pipeline ? REG_TEX_BASE : 0,
has_texture_pipeline ? REG_TEX_BASE : REGISTER_LDST_BASE);
interpipe_aliasing ? 0 : REG_TEX_BASE,
interpipe_aliasing ? REGISTER_LDST_BASE : REG_TEX_BASE);
break;
}

View File

@ -48,6 +48,7 @@
#include "midgard_ops.h"
#include "helpers.h"
#include "compiler.h"
#include "midgard_quirks.h"
#include "disassemble.h"
@ -1493,7 +1494,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
* 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 ?
@ -1815,7 +1816,7 @@ emit_tex(compiler_context *ctx, nir_tex_instr *instr)
bool is_vertex = ctx->stage == MESA_SHADER_VERTEX;
if (is_vertex && instr->op == nir_texop_tex && ctx->gpu_id >= 0x750)
if (is_vertex && instr->op == nir_texop_tex && ctx->quirks & MIDGARD_EXPLICIT_LOD)
instr->op = nir_texop_txl;
switch (instr->op) {
@ -2414,7 +2415,7 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
ctx->stage = nir->info.stage;
ctx->is_blend = is_blend;
ctx->alpha_ref = program->alpha_ref;
ctx->gpu_id = gpu_id;
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

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2019 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.
*/
#ifndef __MDG_QUIRKS_H
#define __MDG_QUIRKS_H
/* Model-specific quirks requiring compiler workarounds/etc. Quirks
* may be errata requiring a workaround, or features. We're trying to be
* quirk-positive here; quirky is the best! */
/* Whether an explicit LOD is required via textureLod in a vertex shader. If
* set, vertex texturing will *always* textureLod. If unset, normal texture ops
* may be emitted in a vertex shader */
#define MIDGARD_EXPLICIT_LOD (1 << 0)
/* Whether output texture registers (normally r28/r29) overlap with work
* registers r0/r1 and input texture registers (also normally r28/r29) overlap
* with load/store registers r26/r27. This constrains register allocation
* considerably but is a space-saving measure on small Midgards. It's worth
* noting if you try to access r28/r29, it may still work, but you'll mess up
* the interference. Corresponds to BASE_HW_FEATURE_INTERPIPE_REG_ALIASING in
* kbase. */
#define MIDGARD_INTERPIPE_REG_ALIASING (1 << 1)
/* Whether we should use old-style blend opcodes */
#define MIDGARD_OLD_BLEND (1 << 2)
static inline unsigned
midgard_get_quirks(unsigned gpu_id)
{
switch (gpu_id) {
case 0x600:
case 0x620:
return MIDGARD_OLD_BLEND;
case 0x720:
return MIDGARD_INTERPIPE_REG_ALIASING |
MIDGARD_OLD_BLEND;
case 0x820:
case 0x830:
return MIDGARD_INTERPIPE_REG_ALIASING;
case 0x750:
case 0x860:
case 0x880:
return MIDGARD_EXPLICIT_LOD;
default:
unreachable("Invalid Midgard GPU ID");
}
}
#endif

View File

@ -27,6 +27,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "lcra.h"
#include "midgard_quirks.h"
struct phys_reg {
/* Physical register: 0-31 */
@ -441,12 +442,12 @@ allocate_registers(compiler_context *ctx, bool *spilled)
lcra_set_disjoint_class(l, REG_CLASS_TEXR, REG_CLASS_TEXW);
/* To save space on T720, we don't have real texture registers.
/* To save space on T*20, we don't have real texture registers.
* Instead, tex inputs reuse the load/store pipeline registers, and
* tex outputs use work r0/r1. Note we still use TEXR/TEXW classes,
* noting that this handles interferences and sizes correctly. */
if (ctx->gpu_id == 0x0720) {
if (ctx->quirks & MIDGARD_INTERPIPE_REG_ALIASING) {
l->class_start[REG_CLASS_TEXR] = l->class_start[REG_CLASS_LDST];
l->class_start[REG_CLASS_TEXW] = l->class_start[REG_CLASS_WORK];
}