From e749f67f8989874f6795d95422c1f3eb4d2706ba Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 1 Jun 2022 20:41:58 -0400 Subject: [PATCH] mesa,gallium: Make point coord origin a CAP MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit When lower_wpos_pntc is used, the state tracker inserts code to transform gl_PointCoord.y according to a uniform, to account for API-requested point coordinate origin and framebuffer orientation. With the transformation, driver-supplied point coordinates are expected to have an upper left origin. If the hardware point coordinate supports (only) a lower left origin, the backend has to use lower_wpos_pntc and then lower *again* to flip back. This ends up transforming twice, which is wasteful: a = load point coord Y with lower left origin a' = 1.0 - a a'' = uniform_transform(a') However, lower_wpos_pntc is quite capable of transforming for a lower left origin too, it just needs to flip the transformation. Add a CAP specifying the point coordinate origin convention, rather than assuming upper-left. This simplifies the Asahi code greatly. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Erik Faye-Lund Reviewed-by: Marek Olšák Part-of: --- docs/gallium/screen.rst | 2 ++ src/gallium/auxiliary/util/u_screen.c | 5 +++++ src/gallium/drivers/nouveau/nv50/nv50_screen.c | 1 + src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 1 + src/gallium/include/pipe/p_defines.h | 1 + src/mesa/main/consts_exts.h | 3 +++ src/mesa/program/prog_statevars.c | 3 ++- src/mesa/state_tracker/st_context.c | 3 +++ 8 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 8a04124..5a4b5d6 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -72,6 +72,8 @@ The integer capabilities: pixel-center fragment convention is supported. * ``PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER``: Whether the integer pixel-center fragment convention is supported. +* ``PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT``: Whether point coordinates use the + upper-left origin convention. Otherwise the lower-left convention is used. * ``PIPE_CAP_DEPTH_CLIP_DISABLE``: Whether the driver is capable of disabling depth clipping (through pipe_rasterizer_state). * ``PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE``: Whether the driver is capable of diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c index daf6bb3..9dde621 100644 --- a/src/gallium/auxiliary/util/u_screen.c +++ b/src/gallium/auxiliary/util/u_screen.c @@ -74,6 +74,11 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; + + case PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT: + return 1; + case PIPE_CAP_DEPTH_CLIP_DISABLE: case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: case PIPE_CAP_DEPTH_CLAMP_ENABLE: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 066b1ec..22387f9 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -219,6 +219,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: case PIPE_CAP_VS_INSTANCEID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index f52ba0a..1806020 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -244,6 +244,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_INDEP_BLEND_FUNC: case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: case PIPE_CAP_VS_INSTANCEID: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index c19e33d..b4a668c 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -766,6 +766,7 @@ enum pipe_cap PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT, PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER, PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER, + PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT, PIPE_CAP_DEPTH_CLIP_DISABLE, PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE, PIPE_CAP_DEPTH_CLAMP_ENABLE, diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h index 747912d..1afe0ee 100644 --- a/src/mesa/main/consts_exts.h +++ b/src/mesa/main/consts_exts.h @@ -996,5 +996,8 @@ struct gl_constants /** Use hardware accelerated GL_SELECT */ bool HardwareAcceleratedSelect; + + /** Origin of point coordinates. True if upper left, false if lower left. */ + bool PointCoordOriginUpperLeft; }; #endif diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c index 8fb74e5..a87177d 100644 --- a/src/mesa/program/prog_statevars.c +++ b/src/mesa/program/prog_statevars.c @@ -743,7 +743,8 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[], case STATE_FB_PNTC_Y_TRANSFORM: { - bool flip_y = (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) ^ + bool flip_y = (ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ + (ctx->Const.PointCoordOriginUpperLeft) ^ (ctx->DrawBuffer->FlipY); value[0] = flip_y ? -1.0F : 1.0F; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 921e251..c5cdadb 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -682,6 +682,9 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe, ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA); + ctx->Const.PointCoordOriginUpperLeft = + screen->get_param(screen, PIPE_CAP_POINT_COORD_ORIGIN_UPPER_LEFT); + ctx->Const.NoClippingOnCopyTex = screen->get_param(screen, PIPE_CAP_NO_CLIP_ON_COPY_TEX); -- 2.7.4