asahi: Don't use OpenGL clip bit

This lets us implement clip control.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26056>
This commit is contained in:
Alyssa Rosenzweig 2023-11-05 12:23:38 -04:00 committed by Marge Bot
parent 695aef7f5a
commit fdb995c204
3 changed files with 47 additions and 1 deletions

View file

@ -14,7 +14,7 @@
enum agx_dbg {
AGX_DBG_TRACE = BITFIELD_BIT(0),
/* bit 1 unused */
AGX_DBG_NOCLIPCTRL = BITFIELD_BIT(1),
AGX_DBG_NO16 = BITFIELD_BIT(2),
AGX_DBG_DIRTY = BITFIELD_BIT(3),
AGX_DBG_PRECOMPILE = BITFIELD_BIT(4),

View file

@ -69,6 +69,7 @@ static const struct debug_named_value agx_debug_options[] = {
{"smalltile", AGX_DBG_SMALLTILE,"Force 16x16 tiles"},
{"nomsaa", AGX_DBG_NOMSAA, "Force disable MSAA"},
{"noshadow", AGX_DBG_NOSHADOW, "Force disable resource shadowing"},
{"noclipctrl",AGX_DBG_NOCLIPCTRL,"Disable ARB_clip_control"},
DEBUG_NAMED_VALUE_END
};
/* clang-format on */

View file

@ -47,6 +47,9 @@
#include "agx_disk_cache.h"
#include "agx_nir_lower_gs.h"
#include "agx_tilebuffer.h"
#include "nir_builder.h"
#include "nir_intrinsics.h"
#include "nir_intrinsics_indices.h"
#include "pool.h"
void
@ -974,6 +977,16 @@ agx_get_scissor_extents(const struct pipe_viewport_state *vp,
}
}
static bool
should_lower_clip_m1_1(struct agx_device *dev, bool clip_halfz)
{
/* If ARB_clip_control is enabled, we use [0, 1] clipping in the hardware
* and lower [-1, 1] clipping in the vertex shader.
*/
bool clip_ctrl = !(dev->debug & AGX_DBG_NOCLIPCTRL);
return clip_ctrl && !clip_halfz;
}
static void
agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch,
uint8_t **out, const struct pipe_viewport_state *vp,
@ -1032,6 +1045,11 @@ agx_upload_viewport_scissor(struct agx_pool *pool, struct agx_batch *batch,
cfg.scale_x = vp->scale[0];
cfg.scale_y = vp->scale[1];
cfg.scale_z = vp->scale[2];
if (should_lower_clip_m1_1(pool->dev, false /* clip_halfz */)) {
cfg.translate_z -= cfg.scale_z;
cfg.scale_z *= 2;
}
}
agx_ppp_fini(out, &ppp);
@ -1577,6 +1595,28 @@ agx_link_varyings_vs_fs(struct agx_pool *pool, struct agx_varyings_vs *vs,
return ptr.gpu;
}
/* nir_lower_clip_halfz analogue for lowered I/O */
static bool
agx_nir_lower_clip_m1_1(nir_builder *b, nir_intrinsic_instr *intr,
UNUSED void *data)
{
if (intr->intrinsic != nir_intrinsic_store_output)
return false;
if (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_POS)
return false;
assert(nir_intrinsic_component(intr) == 0 && "not yet scalarized");
b->cursor = nir_before_instr(&intr->instr);
nir_def *pos = intr->src[0].ssa;
nir_def *z = nir_channel(b, pos, 2);
nir_def *w = nir_channel(b, pos, 3);
nir_def *new_z = nir_fmul_imm(b, nir_fadd(b, z, w), 0.5f);
nir_src_rewrite(&intr->src[0], nir_vector_insert_imm(b, pos, new_z, 2));
return true;
}
/*
* Compile a NIR shader. The only lowering left at this point is sysvals. The
* shader key should have already been applied. agx_compile_variant may call
@ -1642,6 +1682,11 @@ agx_compile_variant(struct agx_device *dev, struct pipe_context *pctx,
struct asahi_vs_shader_key *key = &key_->vs;
NIR_PASS_V(nir, agx_nir_lower_vbo, &key->vbuf);
if (should_lower_clip_m1_1(dev, false /* clip_halfz */)) {
NIR_PASS_V(nir, nir_shader_intrinsics_pass, agx_nir_lower_clip_m1_1,
nir_metadata_block_index | nir_metadata_dominance, NULL);
}
} else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
struct asahi_gs_shader_key *key = &key_->gs;