From 79e97714a2cb215d4f94523da68089dca68e20dd Mon Sep 17 00:00:00 2001 From: Jose Maria Casanova Crespo Date: Tue, 7 Oct 2025 19:30:42 +0200 Subject: [PATCH] v3d: Enables GL_ARB_clip_control for v71+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on current v3dv support for clip control v1: original version (Andrew Copland) v2: update docs, really enable extension (Alejandro PiƱeiro) v3: adjusted viewport and its dirty flag (Chema Casanova) --- docs/features.txt | 2 +- src/gallium/drivers/v3d/v3d_screen.c | 1 + src/gallium/drivers/v3d/v3dx_emit.c | 14 +++++++------- src/gallium/drivers/v3d/v3dx_state.c | 9 +++++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index e0a296d30c0..47a501c625c 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -214,7 +214,7 @@ GL 4.4, GLSL 4.40 -- all DONE: freedreno/a6xx, nvc0, r600, radeonsi, llvmpipe, v GL 4.5, GLSL 4.50 -- all DONE: freedreno/a6xx, nvc0, r600, radeonsi, llvmpipe, virgl, zink, iris, crocus/gen7.5+, d3d12, asahi GL_ARB_ES3_1_compatibility DONE (freedreno/a6xx, softpipe) - GL_ARB_clip_control DONE (freedreno, nv50, softpipe, lima, panfrost, crocus) + GL_ARB_clip_control DONE (freedreno, nv50, softpipe, lima, panfrost, crocus, v3d) GL_ARB_conditional_render_inverted DONE (freedreno, nv50, softpipe, panfrost, crocus/gen6+, svga) GL_ARB_cull_distance DONE (freedreno/a6xx, nv50, softpipe, crocus/gen6+) GL_ARB_derivative_control DONE (freedreno/a3xx+, nv50, softpipe, crocus/gen7+, svga) diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 14768516894..5d182fb335e 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -372,6 +372,7 @@ v3d_init_screen_caps(struct v3d_screen *screen) caps->clip_planes = 0; caps->depth_clip_disable = screen->devinfo.ver >= 71; + caps->clip_halfz = screen->devinfo.ver >= 71; caps->min_line_width = caps->min_line_width_aa = diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c index 0980707cb77..dd1135dd149 100644 --- a/src/gallium/drivers/v3d/v3dx_emit.c +++ b/src/gallium/drivers/v3d/v3dx_emit.c @@ -23,6 +23,7 @@ #include "util/format/u_format.h" #include "util/half_float.h" +#include "util/u_viewport.h" #include "v3d_context.h" #include "broadcom/common/v3d_macros.h" #include "broadcom/cle/v3dx_pack.h" @@ -392,9 +393,11 @@ v3dX(emit_state)(struct pipe_context *pctx) } #if V3D_VERSION >= 71 + uint32_t z_clip_mode = v3d->rasterizer->base.clip_halfz ? + V3D_Z_CLIP_MODE_ZERO_TO_ONE : V3D_Z_CLIP_MODE_MIN_ONE_TO_ONE; config.z_clipping_mode = v3d->rasterizer->base.depth_clip_near || v3d->rasterizer->base.depth_clip_far ? - V3D_Z_CLIP_MODE_MIN_ONE_TO_ONE : V3D_Z_CLIP_MODE_NONE; + z_clip_mode : V3D_Z_CLIP_MODE_NONE; config.z_clamp_mode = v3d->rasterizer->base.depth_clamp; #endif @@ -465,12 +468,9 @@ v3dX(emit_state)(struct pipe_context *pctx) v3d->viewport.scale[2]; } cl_emit(&job->bcl, CLIPPER_Z_MIN_MAX_CLIPPING_PLANES, clip) { - float z1 = (v3d->viewport.translate[2] - - v3d->viewport.scale[2]); - float z2 = (v3d->viewport.translate[2] + - v3d->viewport.scale[2]); - clip.minimum_zw = MIN2(z1, z2); - clip.maximum_zw = MAX2(z1, z2); + util_viewport_zmin_zmax(&v3d->viewport, + v3d->rasterizer->base.clip_halfz, + &clip.minimum_zw, &clip.maximum_zw); } cl_emit(&job->bcl, VIEWPORT_OFFSET, vp) { diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c index 3d547a401f7..f22a43aa750 100644 --- a/src/gallium/drivers/v3d/v3dx_state.c +++ b/src/gallium/drivers/v3d/v3dx_state.c @@ -328,9 +328,14 @@ v3d_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso) { struct v3d_context *v3d = v3d_context(pctx); struct v3d_rasterizer_state *rasterizer = hwcso; - if (v3d->rasterizer == NULL || rasterizer == NULL || - v3d->rasterizer->base.scissor != rasterizer->base.scissor) { + if (v3d->rasterizer == NULL || rasterizer == NULL) { v3d->dirty |= V3D_DIRTY_RASTERIZER_SCISSOR; + v3d->dirty |= V3D_DIRTY_VIEWPORT; + } else { + if (v3d->rasterizer->base.scissor != rasterizer->base.scissor) + v3d->dirty |= V3D_DIRTY_RASTERIZER_SCISSOR; + if (v3d->rasterizer->base.clip_halfz != rasterizer->base.clip_halfz) + v3d->dirty |= V3D_DIRTY_VIEWPORT; } v3d->rasterizer = hwcso; v3d->dirty |= V3D_DIRTY_RASTERIZER;