From 6010d7b8e8bee1bcea2b329cf6d3b44c5fc3ca66 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Fri, 25 Aug 2017 19:22:03 +0200 Subject: [PATCH] gallium: add PIPE_CAP_MAX_VARYINGS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Some NVIDIA hardware can accept 128 fragment shader input components, but only have up to 124 varying-interpolated input components. We add a new cap to express this cleanly. For most drivers, this will have the same value as PIPE_SHADER_CAP_MAX_INPUTS for the fragment shader. Fixes KHR-GL45.limits.max_fragment_input_components Signed-off-by: Karol Herbst [imirkin: rebased, improved docs/commit message] Signed-off-by: Ilia Mirkin Acked-by: Rob Clark Acked-by: Eric Anholt Reviewed-by: Marek Olšák Cc: 19.0 --- src/gallium/docs/source/screen.rst | 4 ++++ src/gallium/drivers/etnaviv/etnaviv_screen.c | 3 +++ .../drivers/freedreno/freedreno_screen.c | 3 +++ src/gallium/drivers/i915/i915_screen.c | 2 ++ src/gallium/drivers/llvmpipe/lp_screen.c | 2 ++ .../drivers/nouveau/nv30/nv30_screen.c | 3 +++ .../drivers/nouveau/nv50/nv50_screen.c | 2 ++ .../drivers/nouveau/nvc0/nvc0_screen.c | 19 +++++++------------ src/gallium/drivers/panfrost/pan_screen.c | 3 +++ src/gallium/drivers/r300/r300_screen.c | 3 +++ src/gallium/drivers/r600/r600_pipe.c | 3 +++ src/gallium/drivers/radeonsi/si_get.c | 3 +++ src/gallium/drivers/softpipe/sp_screen.c | 2 ++ src/gallium/drivers/svga/svga_screen.c | 2 ++ src/gallium/drivers/v3d/v3d_screen.c | 3 +++ src/gallium/drivers/vc4/vc4_screen.c | 3 +++ src/gallium/drivers/virgl/virgl_screen.c | 4 ++++ src/gallium/include/pipe/p_defines.h | 1 + src/mesa/state_tracker/st_extensions.c | 5 +---- 19 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 8bf4a1ab54b..85ca5e1f5ce 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -488,6 +488,10 @@ The integer capabilities: supports switching the format between sRGB and linear for a surface that is used as destination in draw and blit calls. * ``PIPE_CAP_NIR_COMPACT_ARRAYS``: True if the compiler backend supports NIR's compact array feature, for all shader stages. +* ``PIPE_CAP_MAX_VARYINGS``: The maximum number of fragment shader + varyings. This will generally correspond to + ``PIPE_SHADER_CAP_MAX_INPUTS`` for the fragment shader, but in some + cases may be a smaller number. .. _pipe_capf: diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c index fd320232528..35dcac1409b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c @@ -360,6 +360,9 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: return 0; + case PIPE_CAP_MAX_VARYINGS: + return screen->specs.max_varyings; + case PIPE_CAP_PCI_GROUP: case PIPE_CAP_PCI_BUS: case PIPE_CAP_PCI_DEVICE: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index e596a4e8462..c3b08ab0e0f 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -317,6 +317,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_VIEWPORTS: return 1; + case PIPE_CAP_MAX_VARYINGS: + return 16; + case PIPE_CAP_SHAREABLE_SHADERS: case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY: /* manage the variants for these ourself, to avoid breaking precompile: */ diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index a7b4a43c015..78707c66e62 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -402,6 +402,8 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) return 0; case PIPE_CAP_ENDIANNESS: return PIPE_ENDIAN_LITTLE; + case PIPE_CAP_MAX_VARYINGS: + return 10; case PIPE_CAP_VENDOR_ID: return 0x8086; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index c95016a6cbe..b55b4a3c4fe 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -310,6 +310,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_CLEAR_TEXTURE: return 1; + case PIPE_CAP_MAX_VARYINGS: + return 32; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 2b69a8f6968..53551ebc037 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -79,6 +79,9 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 2048; case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET: return 8 * 1024 * 1024; + case PIPE_CAP_MAX_VARYINGS: + return 8; + /* supported capabilities */ case PIPE_CAP_ANISOTROPIC_FILTER: case PIPE_CAP_POINT_SPRITE: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 85cb016e3c2..8e65eaf50b1 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -156,6 +156,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return NV50_MAX_WINDOW_RECTANGLES; case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET: return 16 * 1024 * 1024; + case PIPE_CAP_MAX_VARYINGS: + return 15; /* supported caps */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 6a79fd9a903..4a289557e3b 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -182,6 +182,13 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return class_3d >= GM200_3D_CLASS ? 8 : 0; case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET: return 64 * 1024 * 1024; + case PIPE_CAP_MAX_VARYINGS: + /* NOTE: These only count our slots for GENERIC varyings. + * The address space may be larger, but the actual hard limit seems to be + * less than what the address space layout permits, so don't add TEXCOORD, + * COLOR, etc. here. + */ + return 0x1f0 / 16; /* supported caps */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: @@ -394,18 +401,6 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: return 16; case PIPE_SHADER_CAP_MAX_INPUTS: - if (shader == PIPE_SHADER_VERTEX) - return 32; - /* NOTE: These only count our slots for GENERIC varyings. - * The address space may be larger, but the actual hard limit seems to be - * less than what the address space layout permits, so don't add TEXCOORD, - * COLOR, etc. here. - */ - if (shader == PIPE_SHADER_FRAGMENT) - return 0x1f0 / 16; - /* Actually this counts CLIPVERTEX, which occupies the last generic slot, - * and excludes 0x60 per-patch inputs. - */ return 0x200 / 16; case PIPE_SHADER_CAP_MAX_OUTPUTS: return 32; diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 5ee3b4c6006..3590b608818 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -250,6 +250,9 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: return 4; + case PIPE_CAP_MAX_VARYINGS: + return 16; + default: return u_pipe_screen_get_param_defaults(screen, param); } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 19d3a1bae30..be0b475e5ef 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -304,6 +304,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: return 2048; + case PIPE_CAP_MAX_VARYINGS: + return 10; + case PIPE_CAP_VENDOR_ID: return 0x1002; case PIPE_CAP_DEVICE_ID: diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index ade1a94ab32..41a878ab9d2 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -536,6 +536,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXEL_OFFSET: return 7; + case PIPE_CAP_MAX_VARYINGS: + return 32; + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600; case PIPE_CAP_ENDIANNESS: diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index bb2d8c09eb1..f8ca02d4fcf 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -254,6 +254,9 @@ static int si_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: return 30; + case PIPE_CAP_MAX_VARYINGS: + return 32; + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: return sscreen->info.chip_class <= VI ? PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 : 0; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 44e48cc7ee4..6931b52dc9f 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -265,6 +265,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_CLEAR_TEXTURE: return 1; + case PIPE_CAP_MAX_VARYINGS: + return TGSI_EXEC_MAX_INPUT_ATTRIBS; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 95dde8b0897..6cb5a14f5b0 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -350,6 +350,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: return sws->have_sm4_1 ? 1 : 0; /* only single-channel textures */ + case PIPE_CAP_MAX_VARYINGS: + return sws->have_vgpu10 ? VGPU10_MAX_FS_INPUTS : 10; /* Unsupported features */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index bed2c63a64d..c539daf02b9 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -177,6 +177,9 @@ v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: return 4; + case PIPE_CAP_MAX_VARYINGS: + return V3D_MAX_FS_INPUTS / 4; + /* Texturing. */ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index e7f7c82c271..acb4a1feb0d 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -178,6 +178,9 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Note: Not supported in hardware, just faking it. */ return 5; + case PIPE_CAP_MAX_VARYINGS: + return 8; + case PIPE_CAP_VENDOR_ID: return 0x14E4; case PIPE_CAP_ACCELERATED: diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index 72afd4d95f0..6cc73538a36 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -260,6 +260,10 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; /* TODO: need to introduce a hw-cap for this */ case PIPE_CAP_QUERY_BUFFER_OBJECT: return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_QBO; + case PIPE_CAP_MAX_VARYINGS: + if (vscreen->caps.caps.v1.glsl_level < 150) + return vscreen->caps.caps.v2.max_vertex_attribs; + return 32; case PIPE_CAP_TEXTURE_GATHER_SM5: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: case PIPE_CAP_FAKE_SW_MSAA: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8413a8e639c..e2b0104ce43 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -857,6 +857,7 @@ enum pipe_cap PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND, PIPE_CAP_DEST_SURFACE_SRGB_CONTROL, PIPE_CAP_NIR_COMPACT_ARRAYS, + PIPE_CAP_MAX_VARYINGS, }; /** diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index c1a528551cd..2dbda83ca10 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -365,10 +365,7 @@ void st_init_limits(struct pipe_screen *screen, c->Program[MESA_SHADER_VERTEX].MaxAttribs = MIN2(c->Program[MESA_SHADER_VERTEX].MaxAttribs, 16); - /* PIPE_SHADER_CAP_MAX_INPUTS for the FS specifies the maximum number - * of inputs. It's always 2 colors + N generic inputs. */ - c->MaxVarying = screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, - PIPE_SHADER_CAP_MAX_INPUTS); + c->MaxVarying = screen->get_param(screen, PIPE_CAP_MAX_VARYINGS); c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING); c->MaxGeometryOutputVertices = screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES); -- 2.30.2