[Freedreno] [PATCH] freedreno: moved get_param to generation specific files

Khaled Emara ekhaled1836 at gmail.com
Tue Apr 9 09:37:06 UTC 2019


According to the TODO: moved get_param to generation specific code.
---
 .../drivers/freedreno/a2xx/fd2_screen.c       | 207 ++++++++++++++-
 .../drivers/freedreno/a2xx/fd2_screen.h       |   4 +-
 .../drivers/freedreno/a3xx/fd3_screen.c       | 210 ++++++++++++++-
 .../drivers/freedreno/a3xx/fd3_screen.h       |   4 +-
 .../drivers/freedreno/a4xx/fd4_screen.c       | 210 ++++++++++++++-
 .../drivers/freedreno/a4xx/fd4_screen.h       |   4 +-
 .../drivers/freedreno/a5xx/fd5_screen.c       | 211 ++++++++++++++-
 .../drivers/freedreno/a5xx/fd5_screen.h       |   4 +-
 .../drivers/freedreno/a6xx/fd6_screen.c       | 211 ++++++++++++++-
 .../drivers/freedreno/a6xx/fd6_screen.h       |   4 +-
 .../drivers/freedreno/freedreno_screen.c      | 245 +-----------------
 11 files changed, 1064 insertions(+), 250 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
index f0253238123..0efe46436ac 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.c
@@ -26,12 +26,17 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
+#include "util/u_screen.h"
+
+#include "freedreno_screen.h"
 
 #include "fd2_screen.h"
 #include "fd2_context.h"
 #include "fd2_util.h"
 #include "fd2_resource.h"
 
+static bool glsl120 = false;
+
 static boolean
 fd2_screen_is_format_supported(struct pipe_screen *pscreen,
 		enum pipe_format format,
@@ -105,17 +110,217 @@ fd2_screen_is_format_supported(struct pipe_screen *pscreen,
 	return retval == usage;
 }
 
+static int
+fd2_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+	struct fd_screen *screen = fd_screen(pscreen);
+
+	/* this is probably not totally correct.. but it's a start: */
+	switch (param) {
+	/* Supported features (boolean caps). */
+	case PIPE_CAP_NPOT_TEXTURES:
+	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_ANISOTROPIC_FILTER:
+	case PIPE_CAP_POINT_SPRITE:
+	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+	case PIPE_CAP_TEXTURE_SWIZZLE:
+	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
+	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+	case PIPE_CAP_STRING_MARKER:
+	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
+	case PIPE_CAP_TEXTURE_BARRIER:
+	case PIPE_CAP_INVALIDATE_BUFFER:
+	case PIPE_CAP_PACKED_UNIFORMS:
+		return 1;
+
+	case PIPE_CAP_VERTEXID_NOBASE:
+		return 0;
+
+	case PIPE_CAP_COMPUTE:
+		return 0;
+
+	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+	case PIPE_CAP_PCI_GROUP:
+	case PIPE_CAP_PCI_BUS:
+	case PIPE_CAP_PCI_DEVICE:
+	case PIPE_CAP_PCI_FUNCTION:
+	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+		return 0;
+
+	case PIPE_CAP_SM3:
+	case PIPE_CAP_PRIMITIVE_RESTART:
+	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+	case PIPE_CAP_INDEP_BLEND_ENABLE:
+	case PIPE_CAP_INDEP_BLEND_FUNC:
+	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+	case PIPE_CAP_CONDITIONAL_RENDER:
+	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+	case PIPE_CAP_CLIP_HALFZ:
+		return 0;
+
+	case PIPE_CAP_FAKE_SW_MSAA:
+		return 1;
+
+	case PIPE_CAP_TEXTURE_MULTISAMPLE:
+		return 0;
+
+	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
+		return 0;
+
+	case PIPE_CAP_DEPTH_CLIP_DISABLE:
+		return 0;
+
+	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
+		return 0;
+
+	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+		return 0;
+	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+		/* We could possibly emulate more by pretending 2d/rect textures and
+		 * splitting high bits of index into 2nd dimension..
+		 */
+		return 0;
+
+	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
+	case PIPE_CAP_CUBE_MAP_ARRAY:
+	case PIPE_CAP_SAMPLER_VIEW_TARGET:
+	case PIPE_CAP_TEXTURE_QUERY_LOD:
+		return 0;
+
+	case PIPE_CAP_START_INSTANCE:
+		/* Note that a5xx can do this, it just can't (at least with
+		 * current firmware) do draw_indirect with base_instance.
+		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
+		 * gl42), hide base_instance on a5xx.  :-/
+		 */
+		return 0;
+
+	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_GLSL_FEATURE_LEVEL:
+	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+		return 120;
+
+	case PIPE_CAP_ESSL_FEATURE_LEVEL:
+		return 120;
+
+	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+		return 0;
+
+	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+		return 0;
+
+	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
+	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
+		return 0;
+
+	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+		return 0;
+
+	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
+		return screen->priority_mask;
+
+	case PIPE_CAP_DRAW_INDIRECT:
+		return 0;
+
+	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+		return 0;
+
+	case PIPE_CAP_LOAD_CONSTBUF:
+		/* name is confusing, but this turns on std430 packing */
+		return 0;
+
+	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: */
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+		return 0;
+
+	/* Stream output. */
+	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+		return 0;
+	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+		return 0;
+	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+		return 0;
+
+	/* Texturing. */
+	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+		return MAX_MIP_LEVELS;
+	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+		return 11;
+
+	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+		return 0;
+
+	/* Render targets. */
+	case PIPE_CAP_MAX_RENDER_TARGETS:
+		return screen->max_rts;
+	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+		return 0;
+
+	/* Queries. */
+	case PIPE_CAP_OCCLUSION_QUERY:
+		return 0;
+	case PIPE_CAP_QUERY_TIMESTAMP:
+	case PIPE_CAP_QUERY_TIME_ELAPSED:
+		/* only a4xx, requires new enough kernel so we know max_freq: */
+		return 0;
+
+	case PIPE_CAP_VENDOR_ID:
+		return 0x5143;
+	case PIPE_CAP_DEVICE_ID:
+		return 0xFFFFFFFF;
+	case PIPE_CAP_ACCELERATED:
+		return 1;
+	case PIPE_CAP_VIDEO_MEMORY:
+		DBG("FINISHME: The value returned is incorrect\n");
+		return 10;
+	case PIPE_CAP_UMA:
+		return 1;
+	case PIPE_CAP_NATIVE_FENCE_FD:
+		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	default:
+		return u_pipe_screen_get_param_defaults(pscreen, param);
+	}
+}
+
 extern const struct fd_perfcntr_group a2xx_perfcntr_groups[];
 extern const unsigned a2xx_num_perfcntr_groups;
 
 void
-fd2_screen_init(struct pipe_screen *pscreen)
+fd2_screen_init(struct pipe_screen *pscreen, bool is_glsl120)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
 
+	glsl120 = is_glsl120;
+
 	screen->max_rts = 1;
 	pscreen->context_create = fd2_context_create;
 	pscreen->is_format_supported = fd2_screen_is_format_supported;
+	pscreen->get_param = fd2_screen_get_param;
 	screen->setup_slices = fd2_setup_slices;
 
 	if (fd_mesa_debug & FD_DBG_PERFC) {
diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_screen.h b/src/gallium/drivers/freedreno/a2xx/fd2_screen.h
index dbe3367b66e..bab6ebe921e 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_screen.h
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_screen.h
@@ -29,6 +29,8 @@
 
 #include "pipe/p_screen.h"
 
-void fd2_screen_init(struct pipe_screen *pscreen);
+#include <stdbool.h>
+
+void fd2_screen_init(struct pipe_screen *pscreen, bool is_glsl120);
 
 #endif /* FD2_SCREEN_H_ */
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_screen.c b/src/gallium/drivers/freedreno/a3xx/fd3_screen.c
index 7ed57d2de5a..d55dfb984ae 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_screen.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_screen.c
@@ -26,6 +26,9 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
+#include "util/u_screen.h"
+
+#include "freedreno_screen.h"
 
 #include "fd3_screen.h"
 #include "fd3_context.h"
@@ -33,6 +36,8 @@
 
 #include "ir3/ir3_compiler.h"
 
+static bool glsl120 = false;
+
 static boolean
 fd3_screen_is_format_supported(struct pipe_screen *pscreen,
 		enum pipe_format format,
@@ -98,12 +103,215 @@ fd3_screen_is_format_supported(struct pipe_screen *pscreen,
 	return retval == usage;
 }
 
+static int
+fd3_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+	struct fd_screen *screen = fd_screen(pscreen);
+
+	/* this is probably not totally correct.. but it's a start: */
+	switch (param) {
+	/* Supported features (boolean caps). */
+	case PIPE_CAP_NPOT_TEXTURES:
+	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_ANISOTROPIC_FILTER:
+	case PIPE_CAP_POINT_SPRITE:
+	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+	case PIPE_CAP_TEXTURE_SWIZZLE:
+	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
+	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+	case PIPE_CAP_STRING_MARKER:
+	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
+	case PIPE_CAP_TEXTURE_BARRIER:
+	case PIPE_CAP_INVALIDATE_BUFFER:
+	case PIPE_CAP_PACKED_UNIFORMS:
+		return 1;
+
+	case PIPE_CAP_VERTEXID_NOBASE:
+		return 1;
+
+	case PIPE_CAP_COMPUTE:
+		return 0;
+
+	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+	case PIPE_CAP_PCI_GROUP:
+	case PIPE_CAP_PCI_BUS:
+	case PIPE_CAP_PCI_DEVICE:
+	case PIPE_CAP_PCI_FUNCTION:
+	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+		return 0;
+
+	case PIPE_CAP_SM3:
+	case PIPE_CAP_PRIMITIVE_RESTART:
+	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+	case PIPE_CAP_INDEP_BLEND_ENABLE:
+	case PIPE_CAP_INDEP_BLEND_FUNC:
+	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+	case PIPE_CAP_CONDITIONAL_RENDER:
+	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+	case PIPE_CAP_CLIP_HALFZ:
+		return 1;
+
+	case PIPE_CAP_FAKE_SW_MSAA:
+		return 1;
+
+	case PIPE_CAP_TEXTURE_MULTISAMPLE:
+		return 0;
+
+	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
+		return 0;
+
+	case PIPE_CAP_DEPTH_CLIP_DISABLE:
+		return 1;
+
+	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
+		return 0;
+
+	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+		return 16;
+	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+		/* We could possibly emulate more by pretending 2d/rect textures and
+		 * splitting high bits of index into 2nd dimension..
+		 */
+		return 8192;
+
+	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
+	case PIPE_CAP_CUBE_MAP_ARRAY:
+	case PIPE_CAP_SAMPLER_VIEW_TARGET:
+	case PIPE_CAP_TEXTURE_QUERY_LOD:
+		return 0;
+
+	case PIPE_CAP_START_INSTANCE:
+		/* Note that a5xx can do this, it just can't (at least with
+		 * current firmware) do draw_indirect with base_instance.
+		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
+		 * gl42), hide base_instance on a5xx.  :-/
+		 */
+		return 0;
+
+	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_GLSL_FEATURE_LEVEL:
+	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+		if (glsl120)
+			return 120;
+		return 140;
+
+	case PIPE_CAP_ESSL_FEATURE_LEVEL:
+		return 300;
+
+	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+		return 0;
+
+	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+		return 0;
+
+	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
+	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
+		return 0;
+
+	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+		return 0;
+
+	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
+		return screen->priority_mask;
+
+	case PIPE_CAP_DRAW_INDIRECT:
+		return 0;
+
+	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+		return 0;
+
+	case PIPE_CAP_LOAD_CONSTBUF:
+		/* name is confusing, but this turns on std430 packing */
+		return 1;
+
+	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: */
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+		return 1;
+
+	/* Stream output. */
+	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+		return PIPE_MAX_SO_BUFFERS;
+	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+		return 1;
+	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+		return 16 * 4;   /* should only be shader out limit? */
+
+	/* Texturing. */
+	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+		return MAX_MIP_LEVELS;
+	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+		return 11;
+
+	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+		return 256;
+
+	/* Render targets. */
+	case PIPE_CAP_MAX_RENDER_TARGETS:
+		return screen->max_rts;
+	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+		return 1;
+
+	/* Queries. */
+	case PIPE_CAP_OCCLUSION_QUERY:
+		return 1;
+	case PIPE_CAP_QUERY_TIMESTAMP:
+	case PIPE_CAP_QUERY_TIME_ELAPSED:
+		/* only a4xx, requires new enough kernel so we know max_freq: */
+		return 0;
+
+	case PIPE_CAP_VENDOR_ID:
+		return 0x5143;
+	case PIPE_CAP_DEVICE_ID:
+		return 0xFFFFFFFF;
+	case PIPE_CAP_ACCELERATED:
+		return 1;
+	case PIPE_CAP_VIDEO_MEMORY:
+		DBG("FINISHME: The value returned is incorrect\n");
+		return 10;
+	case PIPE_CAP_UMA:
+		return 1;
+	case PIPE_CAP_NATIVE_FENCE_FD:
+		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	default:
+		return u_pipe_screen_get_param_defaults(pscreen, param);
+	}
+}
+
 void
-fd3_screen_init(struct pipe_screen *pscreen)
+fd3_screen_init(struct pipe_screen *pscreen, bool is_glsl120)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
+
+	glsl120 = is_glsl120;
+
 	screen->max_rts = A3XX_MAX_RENDER_TARGETS;
 	screen->compiler = ir3_compiler_create(screen->dev, screen->gpu_id);
 	pscreen->context_create = fd3_context_create;
 	pscreen->is_format_supported = fd3_screen_is_format_supported;
+	pscreen->get_param = fd3_screen_get_param;
 }
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_screen.h b/src/gallium/drivers/freedreno/a3xx/fd3_screen.h
index 3eb68f8bf0d..7f988f9211b 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_screen.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_screen.h
@@ -29,6 +29,8 @@
 
 #include "pipe/p_screen.h"
 
-void fd3_screen_init(struct pipe_screen *pscreen);
+#include <stdbool.h>
+
+void fd3_screen_init(struct pipe_screen *pscreen, bool is_glsl120);
 
 #endif /* FD3_SCREEN_H_ */
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c
index 961e907b779..f661ba85417 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_screen.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_screen.c
@@ -26,6 +26,9 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
+#include "util/u_screen.h"
+
+#include "freedreno_screen.h"
 
 #include "fd4_screen.h"
 #include "fd4_context.h"
@@ -33,6 +36,8 @@
 
 #include "ir3/ir3_compiler.h"
 
+static bool glsl120 = false;
+
 static boolean
 fd4_screen_is_format_supported(struct pipe_screen *pscreen,
 		enum pipe_format format,
@@ -102,12 +107,215 @@ fd4_screen_is_format_supported(struct pipe_screen *pscreen,
 	return retval == usage;
 }
 
+static int
+fd4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+	struct fd_screen *screen = fd_screen(pscreen);
+
+	/* this is probably not totally correct.. but it's a start: */
+	switch (param) {
+	/* Supported features (boolean caps). */
+	case PIPE_CAP_NPOT_TEXTURES:
+	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_ANISOTROPIC_FILTER:
+	case PIPE_CAP_POINT_SPRITE:
+	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+	case PIPE_CAP_TEXTURE_SWIZZLE:
+	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
+	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+	case PIPE_CAP_STRING_MARKER:
+	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
+	case PIPE_CAP_TEXTURE_BARRIER:
+	case PIPE_CAP_INVALIDATE_BUFFER:
+	case PIPE_CAP_PACKED_UNIFORMS:
+		return 1;
+
+	case PIPE_CAP_VERTEXID_NOBASE:
+		return 1;
+
+	case PIPE_CAP_COMPUTE:
+		return 0;
+
+	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+	case PIPE_CAP_PCI_GROUP:
+	case PIPE_CAP_PCI_BUS:
+	case PIPE_CAP_PCI_DEVICE:
+	case PIPE_CAP_PCI_FUNCTION:
+	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+		return 0;
+
+	case PIPE_CAP_SM3:
+	case PIPE_CAP_PRIMITIVE_RESTART:
+	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+	case PIPE_CAP_INDEP_BLEND_ENABLE:
+	case PIPE_CAP_INDEP_BLEND_FUNC:
+	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+	case PIPE_CAP_CONDITIONAL_RENDER:
+	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+	case PIPE_CAP_CLIP_HALFZ:
+		return 1;
+
+	case PIPE_CAP_FAKE_SW_MSAA:
+		return 1;
+
+	case PIPE_CAP_TEXTURE_MULTISAMPLE:
+		return 0;
+
+	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
+		return 0;
+
+	case PIPE_CAP_DEPTH_CLIP_DISABLE:
+		return 1;
+
+	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
+		return 0;
+
+	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+		return 32;
+	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+		/* We could possibly emulate more by pretending 2d/rect textures and
+		 * splitting high bits of index into 2nd dimension..
+		 */
+		return 16384;
+
+	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
+	case PIPE_CAP_CUBE_MAP_ARRAY:
+	case PIPE_CAP_SAMPLER_VIEW_TARGET:
+	case PIPE_CAP_TEXTURE_QUERY_LOD:
+		return 1;
+
+	case PIPE_CAP_START_INSTANCE:
+		/* Note that a5xx can do this, it just can't (at least with
+		 * current firmware) do draw_indirect with base_instance.
+		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
+		 * gl42), hide base_instance on a5xx.  :-/
+		 */
+		return 1;
+
+	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_GLSL_FEATURE_LEVEL:
+	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+		if (glsl120)
+			return 120;
+		return 140;
+
+	case PIPE_CAP_ESSL_FEATURE_LEVEL:
+		return 300;
+
+	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+		return 0;
+
+	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+		return 4;
+
+	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
+	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
+		return 0;
+
+	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+		return 0;
+
+	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
+		return screen->priority_mask;
+
+	case PIPE_CAP_DRAW_INDIRECT:
+		return 1;
+
+	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+		return 1;
+
+	case PIPE_CAP_LOAD_CONSTBUF:
+		/* name is confusing, but this turns on std430 packing */
+		return 1;
+
+	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: */
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+		return 1;
+
+	/* Stream output. */
+	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+		return PIPE_MAX_SO_BUFFERS;
+	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+		return 1;
+	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+		return 16 * 4;   /* should only be shader out limit? */
+
+	/* Texturing. */
+	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+		return MAX_MIP_LEVELS;
+	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+		return 11;
+
+	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+		return 256;
+
+	/* Render targets. */
+	case PIPE_CAP_MAX_RENDER_TARGETS:
+		return screen->max_rts;
+	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+		return 0;
+
+	/* Queries. */
+	case PIPE_CAP_OCCLUSION_QUERY:
+		return 1;
+	case PIPE_CAP_QUERY_TIMESTAMP:
+	case PIPE_CAP_QUERY_TIME_ELAPSED:
+		/* only a4xx, requires new enough kernel so we know max_freq: */
+		return screen->max_freq > 0;
+
+	case PIPE_CAP_VENDOR_ID:
+		return 0x5143;
+	case PIPE_CAP_DEVICE_ID:
+		return 0xFFFFFFFF;
+	case PIPE_CAP_ACCELERATED:
+		return 1;
+	case PIPE_CAP_VIDEO_MEMORY:
+		DBG("FINISHME: The value returned is incorrect\n");
+		return 10;
+	case PIPE_CAP_UMA:
+		return 1;
+	case PIPE_CAP_NATIVE_FENCE_FD:
+		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	default:
+		return u_pipe_screen_get_param_defaults(pscreen, param);
+	}
+}
+
 void
-fd4_screen_init(struct pipe_screen *pscreen)
+fd4_screen_init(struct pipe_screen *pscreen, bool is_glsl120)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
+
+	glsl120 = is_glsl120;
+
 	screen->max_rts = A4XX_MAX_RENDER_TARGETS;
 	screen->compiler = ir3_compiler_create(screen->dev, screen->gpu_id);
 	pscreen->context_create = fd4_context_create;
 	pscreen->is_format_supported = fd4_screen_is_format_supported;
+	pscreen->get_param = fd4_screen_get_param;
 }
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_screen.h b/src/gallium/drivers/freedreno/a4xx/fd4_screen.h
index c291bf7ef01..fca44d010ea 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_screen.h
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_screen.h
@@ -29,6 +29,8 @@
 
 #include "pipe/p_screen.h"
 
-void fd4_screen_init(struct pipe_screen *pscreen);
+#include <stdbool.h>
+
+void fd4_screen_init(struct pipe_screen *pscreen, bool is_glsl120);
 
 #endif /* FD4_SCREEN_H_ */
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_screen.c b/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
index db961790879..2a28ec1b23c 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
@@ -26,6 +26,9 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
+#include "util/u_screen.h"
+
+#include "freedreno_screen.h"
 
 #include "fd5_screen.h"
 #include "fd5_blitter.h"
@@ -35,6 +38,8 @@
 
 #include "ir3/ir3_compiler.h"
 
+static bool glsl120 = false;
+
 static bool
 valid_sample_count(unsigned sample_count)
 {
@@ -120,17 +125,221 @@ fd5_screen_is_format_supported(struct pipe_screen *pscreen,
 	return retval == usage;
 }
 
+static int
+fd5_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+	struct fd_screen *screen = fd_screen(pscreen);
+
+	/* this is probably not totally correct.. but it's a start: */
+	switch (param) {
+	/* Supported features (boolean caps). */
+	case PIPE_CAP_NPOT_TEXTURES:
+	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_ANISOTROPIC_FILTER:
+	case PIPE_CAP_POINT_SPRITE:
+	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+	case PIPE_CAP_TEXTURE_SWIZZLE:
+	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
+	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+	case PIPE_CAP_STRING_MARKER:
+	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
+	case PIPE_CAP_TEXTURE_BARRIER:
+	case PIPE_CAP_INVALIDATE_BUFFER:
+	case PIPE_CAP_PACKED_UNIFORMS:
+		return 1;
+
+	case PIPE_CAP_VERTEXID_NOBASE:
+		return 0;
+
+	case PIPE_CAP_COMPUTE:
+		return 1;
+
+	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+	case PIPE_CAP_PCI_GROUP:
+	case PIPE_CAP_PCI_BUS:
+	case PIPE_CAP_PCI_DEVICE:
+	case PIPE_CAP_PCI_FUNCTION:
+	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+		return 0;
+
+	case PIPE_CAP_SM3:
+	case PIPE_CAP_PRIMITIVE_RESTART:
+	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+	case PIPE_CAP_INDEP_BLEND_ENABLE:
+	case PIPE_CAP_INDEP_BLEND_FUNC:
+	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+	case PIPE_CAP_CONDITIONAL_RENDER:
+	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+	case PIPE_CAP_CLIP_HALFZ:
+		return 1;
+
+	case PIPE_CAP_FAKE_SW_MSAA:
+		return 0;
+
+	case PIPE_CAP_TEXTURE_MULTISAMPLE:
+		return 1;
+
+	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
+		return 0;
+
+	case PIPE_CAP_DEPTH_CLIP_DISABLE:
+		return 0;
+
+	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
+		return 1;
+
+	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+		return 32;
+	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+		/* We could possibly emulate more by pretending 2d/rect textures and
+		 * splitting high bits of index into 2nd dimension..
+		 */
+		return 16384;
+
+	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
+	case PIPE_CAP_CUBE_MAP_ARRAY:
+	case PIPE_CAP_SAMPLER_VIEW_TARGET:
+	case PIPE_CAP_TEXTURE_QUERY_LOD:
+		return 1;
+
+	case PIPE_CAP_START_INSTANCE:
+		/* Note that a5xx can do this, it just can't (at least with
+		 * current firmware) do draw_indirect with base_instance.
+		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
+		 * gl42), hide base_instance on a5xx.  :-/
+		 */
+		return 0;
+
+	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_GLSL_FEATURE_LEVEL:
+	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+		if (glsl120)
+			return 120;
+		return 140;
+
+	case PIPE_CAP_ESSL_FEATURE_LEVEL:
+		/* we can probably enable 320 for a5xx too, but need to test: */
+		return 310;
+
+	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+		return 4;
+
+	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+		return 4;
+
+	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
+	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
+		return 0;
+
+	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+		return 0;
+
+	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
+		return screen->priority_mask;
+
+	case PIPE_CAP_DRAW_INDIRECT:
+		return 1;
+
+	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+		return 1;
+
+	case PIPE_CAP_LOAD_CONSTBUF:
+		/* name is confusing, but this turns on std430 packing */
+		return 1;
+
+	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: */
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+		return 1;
+
+	/* Stream output. */
+	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+		return PIPE_MAX_SO_BUFFERS;
+	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+		return 1;
+	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+		return 16 * 4;   /* should only be shader out limit? */
+
+	/* Texturing. */
+	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+		return MAX_MIP_LEVELS;
+	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+		return 11;
+
+	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+		return 256;
+
+	/* Render targets. */
+	case PIPE_CAP_MAX_RENDER_TARGETS:
+		return screen->max_rts;
+	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+		return 0;
+
+	/* Queries. */
+	case PIPE_CAP_OCCLUSION_QUERY:
+		return 1;
+	case PIPE_CAP_QUERY_TIMESTAMP:
+	case PIPE_CAP_QUERY_TIME_ELAPSED:
+		/* only a4xx, requires new enough kernel so we know max_freq: */
+		return screen->max_freq > 0;
+
+	case PIPE_CAP_VENDOR_ID:
+		return 0x5143;
+	case PIPE_CAP_DEVICE_ID:
+		return 0xFFFFFFFF;
+	case PIPE_CAP_ACCELERATED:
+		return 1;
+	case PIPE_CAP_VIDEO_MEMORY:
+		DBG("FINISHME: The value returned is incorrect\n");
+		return 10;
+	case PIPE_CAP_UMA:
+		return 1;
+	case PIPE_CAP_NATIVE_FENCE_FD:
+		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	default:
+		return u_pipe_screen_get_param_defaults(pscreen, param);
+	}
+}
+
 extern const struct fd_perfcntr_group a5xx_perfcntr_groups[];
 extern const unsigned a5xx_num_perfcntr_groups;
 
 void
-fd5_screen_init(struct pipe_screen *pscreen)
+fd5_screen_init(struct pipe_screen *pscreen, bool is_glsl120)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
+
+	glsl120 = is_glsl120;
+	
 	screen->max_rts = A5XX_MAX_RENDER_TARGETS;
 	screen->compiler = ir3_compiler_create(screen->dev, screen->gpu_id);
 	pscreen->context_create = fd5_context_create;
 	pscreen->is_format_supported = fd5_screen_is_format_supported;
+	pscreen->get_param = fd5_screen_get_param;
 
 	screen->setup_slices = fd5_setup_slices;
 	if (fd_mesa_debug & FD_DBG_TTILE)
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_screen.h b/src/gallium/drivers/freedreno/a5xx/fd5_screen.h
index 0a65b3b0737..a964060afb2 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_screen.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_screen.h
@@ -29,11 +29,13 @@
 
 #include "pipe/p_screen.h"
 
+#include <stdbool.h>
+
 #include "freedreno_util.h"
 
 #include "a5xx.xml.h"
 
-void fd5_screen_init(struct pipe_screen *pscreen);
+void fd5_screen_init(struct pipe_screen *pscreen, bool is_glsl120);
 
 static inline void
 emit_marker5(struct fd_ringbuffer *ring, int scratch_idx)
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_screen.c b/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
index e04984a3036..8a07a241ac9 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
@@ -28,6 +28,9 @@
 #include "drm-uapi/drm_fourcc.h"
 #include "pipe/p_screen.h"
 #include "util/u_format.h"
+#include "util/u_screen.h"
+
+#include "freedreno_screen.h"
 
 #include "fd6_screen.h"
 #include "fd6_blitter.h"
@@ -37,6 +40,8 @@
 
 #include "ir3/ir3_compiler.h"
 
+static bool glsl120 = false;
+
 static bool
 valid_sample_count(unsigned sample_count)
 {
@@ -126,17 +131,221 @@ fd6_screen_is_format_supported(struct pipe_screen *pscreen,
 	return retval == usage;
 }
 
+static int
+fd6_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
+{
+	struct fd_screen *screen = fd_screen(pscreen);
+
+	/* this is probably not totally correct.. but it's a start: */
+	switch (param) {
+	/* Supported features (boolean caps). */
+	case PIPE_CAP_NPOT_TEXTURES:
+	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
+	case PIPE_CAP_ANISOTROPIC_FILTER:
+	case PIPE_CAP_POINT_SPRITE:
+	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+	case PIPE_CAP_TEXTURE_SWIZZLE:
+	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
+	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP:
+	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+	case PIPE_CAP_STRING_MARKER:
+	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
+	case PIPE_CAP_TEXTURE_BARRIER:
+	case PIPE_CAP_INVALIDATE_BUFFER:
+	case PIPE_CAP_PACKED_UNIFORMS:
+		return 1;
+
+	case PIPE_CAP_VERTEXID_NOBASE:
+		return 0;
+
+	case PIPE_CAP_COMPUTE:
+		return 1;
+
+	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
+	case PIPE_CAP_PCI_GROUP:
+	case PIPE_CAP_PCI_BUS:
+	case PIPE_CAP_PCI_DEVICE:
+	case PIPE_CAP_PCI_FUNCTION:
+	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
+		return 0;
+
+	case PIPE_CAP_SM3:
+	case PIPE_CAP_PRIMITIVE_RESTART:
+	case PIPE_CAP_TGSI_INSTANCEID:
+	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+	case PIPE_CAP_INDEP_BLEND_ENABLE:
+	case PIPE_CAP_INDEP_BLEND_FUNC:
+	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
+	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
+	case PIPE_CAP_CONDITIONAL_RENDER:
+	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
+	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
+	case PIPE_CAP_CLIP_HALFZ:
+		return 1;
+
+	case PIPE_CAP_FAKE_SW_MSAA:
+		return 0;
+
+	case PIPE_CAP_TEXTURE_MULTISAMPLE:
+		return 1;
+
+	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
+		return 1;
+
+	case PIPE_CAP_DEPTH_CLIP_DISABLE:
+		return 0;
+
+	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
+		return 1;
+
+	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
+		/* We could possibly emulate more by pretending 2d/rect textures and
+		 * splitting high bits of index into 2nd dimension..
+		 */
+		return 1 << 27;
+
+	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
+	case PIPE_CAP_CUBE_MAP_ARRAY:
+	case PIPE_CAP_SAMPLER_VIEW_TARGET:
+	case PIPE_CAP_TEXTURE_QUERY_LOD:
+		return 1;
+
+	case PIPE_CAP_START_INSTANCE:
+		/* Note that a5xx can do this, it just can't (at least with
+		 * current firmware) do draw_indirect with base_instance.
+		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
+		 * gl42), hide base_instance on a5xx.  :-/
+		 */
+		return 0;
+
+	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_GLSL_FEATURE_LEVEL:
+	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
+		if (glsl120)
+			return 120;
+		return 140;
+
+	case PIPE_CAP_ESSL_FEATURE_LEVEL:
+		/* we can probably enable 320 for a5xx too, but need to test: */
+		return 320;
+
+	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
+		return 64;
+
+	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
+		return 4;
+
+	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
+	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
+		return 0;
+
+	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
+		return 0;
+
+	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
+		return screen->priority_mask;
+
+	case PIPE_CAP_DRAW_INDIRECT:
+		return 1;
+
+	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
+		return 1;
+
+	case PIPE_CAP_LOAD_CONSTBUF:
+		/* name is confusing, but this turns on std430 packing */
+		return 1;
+
+	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: */
+	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+		return 1;
+
+	/* Stream output. */
+	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+		return PIPE_MAX_SO_BUFFERS;
+	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
+	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
+		return 1;
+	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+		return 16 * 4;   /* should only be shader out limit? */
+
+	/* Texturing. */
+	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+		return MAX_MIP_LEVELS;
+	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+		return 11;
+
+	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
+		return 256;
+
+	/* Render targets. */
+	case PIPE_CAP_MAX_RENDER_TARGETS:
+		return screen->max_rts;
+	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+		return 0;
+
+	/* Queries. */
+	case PIPE_CAP_OCCLUSION_QUERY:
+		return 1;
+	case PIPE_CAP_QUERY_TIMESTAMP:
+	case PIPE_CAP_QUERY_TIME_ELAPSED:
+		/* only a4xx, requires new enough kernel so we know max_freq: */
+		return screen->max_freq > 0;
+
+	case PIPE_CAP_VENDOR_ID:
+		return 0x5143;
+	case PIPE_CAP_DEVICE_ID:
+		return 0xFFFFFFFF;
+	case PIPE_CAP_ACCELERATED:
+		return 1;
+	case PIPE_CAP_VIDEO_MEMORY:
+		DBG("FINISHME: The value returned is incorrect\n");
+		return 10;
+	case PIPE_CAP_UMA:
+		return 1;
+	case PIPE_CAP_NATIVE_FENCE_FD:
+		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
+	default:
+		return u_pipe_screen_get_param_defaults(pscreen, param);
+	}
+}
+
 extern const struct fd_perfcntr_group a6xx_perfcntr_groups[];
 extern const unsigned a6xx_num_perfcntr_groups;
 
 void
-fd6_screen_init(struct pipe_screen *pscreen)
+fd6_screen_init(struct pipe_screen *pscreen, bool is_glsl120)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
+
+	glsl120 = is_glsl120;
+	
 	screen->max_rts = A6XX_MAX_RENDER_TARGETS;
 	screen->compiler = ir3_compiler_create(screen->dev, screen->gpu_id);
 	pscreen->context_create = fd6_context_create;
 	pscreen->is_format_supported = fd6_screen_is_format_supported;
+	pscreen->get_param = fd6_screen_get_param;
 
 	screen->setup_slices = fd6_setup_slices;
 	screen->tile_mode = fd6_tile_mode;
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_screen.h b/src/gallium/drivers/freedreno/a6xx/fd6_screen.h
index 5c8b00dad2a..fa186a2cbc0 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_screen.h
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_screen.h
@@ -30,6 +30,8 @@
 
 #include "pipe/p_screen.h"
 
-void fd6_screen_init(struct pipe_screen *pscreen);
+#include <stdbool.h>
+
+void fd6_screen_init(struct pipe_screen *pscreen, bool is_glsl120);
 
 #endif /* FD6_SCREEN_H_ */
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index c27b1d36253..49d6695add4 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -163,240 +163,6 @@ fd_screen_destroy(struct pipe_screen *pscreen)
 	free(screen);
 }
 
-/*
-TODO either move caps to a2xx/a3xx specific code, or maybe have some
-tables for things that differ if the delta is not too much..
- */
-static int
-fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
-{
-	struct fd_screen *screen = fd_screen(pscreen);
-
-	/* this is probably not totally correct.. but it's a start: */
-	switch (param) {
-	/* Supported features (boolean caps). */
-	case PIPE_CAP_NPOT_TEXTURES:
-	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
-	case PIPE_CAP_ANISOTROPIC_FILTER:
-	case PIPE_CAP_POINT_SPRITE:
-	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
-	case PIPE_CAP_TEXTURE_SWIZZLE:
-	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
-	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
-	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
-	case PIPE_CAP_SEAMLESS_CUBE_MAP:
-	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
-	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
-	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
-	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
-	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
-	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
-	case PIPE_CAP_STRING_MARKER:
-	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
-	case PIPE_CAP_TEXTURE_BARRIER:
-	case PIPE_CAP_INVALIDATE_BUFFER:
-	case PIPE_CAP_PACKED_UNIFORMS:
-		return 1;
-
-	case PIPE_CAP_VERTEXID_NOBASE:
-		return is_a3xx(screen) || is_a4xx(screen);
-
-	case PIPE_CAP_COMPUTE:
-		return has_compute(screen);
-
-	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
-	case PIPE_CAP_PCI_GROUP:
-	case PIPE_CAP_PCI_BUS:
-	case PIPE_CAP_PCI_DEVICE:
-	case PIPE_CAP_PCI_FUNCTION:
-	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
-		return 0;
-
-	case PIPE_CAP_SM3:
-	case PIPE_CAP_PRIMITIVE_RESTART:
-	case PIPE_CAP_TGSI_INSTANCEID:
-	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
-	case PIPE_CAP_INDEP_BLEND_ENABLE:
-	case PIPE_CAP_INDEP_BLEND_FUNC:
-	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
-	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
-	case PIPE_CAP_CONDITIONAL_RENDER:
-	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
-	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
-	case PIPE_CAP_CLIP_HALFZ:
-		return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
-
-	case PIPE_CAP_FAKE_SW_MSAA:
-		return !fd_screen_get_param(pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE);
-
-	case PIPE_CAP_TEXTURE_MULTISAMPLE:
-		return is_a5xx(screen) || is_a6xx(screen);
-
-	case PIPE_CAP_SURFACE_SAMPLE_COUNT:
-		return is_a6xx(screen);
-
-	case PIPE_CAP_DEPTH_CLIP_DISABLE:
-		return is_a3xx(screen) || is_a4xx(screen);
-
-	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
-		return is_a5xx(screen) || is_a6xx(screen);
-
-	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
-		if (is_a3xx(screen)) return 16;
-		if (is_a4xx(screen)) return 32;
-		if (is_a5xx(screen)) return 32;
-		if (is_a6xx(screen)) return 64;
-		return 0;
-	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
-		/* We could possibly emulate more by pretending 2d/rect textures and
-		 * splitting high bits of index into 2nd dimension..
-		 */
-		if (is_a3xx(screen)) return 8192;
-		if (is_a4xx(screen)) return 16384;
-		if (is_a5xx(screen)) return 16384;
-		if (is_a6xx(screen)) return 1 << 27;
-		return 0;
-
-	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
-	case PIPE_CAP_CUBE_MAP_ARRAY:
-	case PIPE_CAP_SAMPLER_VIEW_TARGET:
-	case PIPE_CAP_TEXTURE_QUERY_LOD:
-		return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
-
-	case PIPE_CAP_START_INSTANCE:
-		/* Note that a5xx can do this, it just can't (at least with
-		 * current firmware) do draw_indirect with base_instance.
-		 * Since draw_indirect is needed sooner (gles31 and gl40 vs
-		 * gl42), hide base_instance on a5xx.  :-/
-		 */
-		return is_a4xx(screen);
-
-	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
-		return 64;
-
-	case PIPE_CAP_GLSL_FEATURE_LEVEL:
-	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
-		if (glsl120)
-			return 120;
-		return is_ir3(screen) ? 140 : 120;
-
-	case PIPE_CAP_ESSL_FEATURE_LEVEL:
-		/* we can probably enable 320 for a5xx too, but need to test: */
-		if (is_a6xx(screen)) return 320;
-		if (is_a5xx(screen)) return 310;
-		if (is_ir3(screen))  return 300;
-		return 120;
-
-	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
-		if (is_a6xx(screen)) return 64;
-		if (is_a5xx(screen)) return 4;
-			return 4;
-		return 0;
-
-	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
-		if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
-			return 4;
-		return 0;
-
-	/* TODO if we need this, do it in nir/ir3 backend to avoid breaking precompile: */
-	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
-		return 0;
-
-	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
-		return 0;
-
-	case PIPE_CAP_CONTEXT_PRIORITY_MASK:
-		return screen->priority_mask;
-
-	case PIPE_CAP_DRAW_INDIRECT:
-		if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
-			return 1;
-		return 0;
-
-	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
-		if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
-			return 1;
-		return 0;
-
-	case PIPE_CAP_LOAD_CONSTBUF:
-		/* name is confusing, but this turns on std430 packing */
-		if (is_ir3(screen))
-			return 1;
-		return 0;
-
-	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: */
-	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
-	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
-		if (is_ir3(screen))
-			return 1;
-		return 0;
-
-	/* Stream output. */
-	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
-		if (is_ir3(screen))
-			return PIPE_MAX_SO_BUFFERS;
-		return 0;
-	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
-	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
-		if (is_ir3(screen))
-			return 1;
-		return 0;
-	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
-	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
-		if (is_ir3(screen))
-			return 16 * 4;   /* should only be shader out limit? */
-		return 0;
-
-	/* Texturing. */
-	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
-	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
-		return MAX_MIP_LEVELS;
-	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
-		return 11;
-
-	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
-		return (is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) ? 256 : 0;
-
-	/* Render targets. */
-	case PIPE_CAP_MAX_RENDER_TARGETS:
-		return screen->max_rts;
-	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
-		return is_a3xx(screen) ? 1 : 0;
-
-	/* Queries. */
-	case PIPE_CAP_OCCLUSION_QUERY:
-		return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
-	case PIPE_CAP_QUERY_TIMESTAMP:
-	case PIPE_CAP_QUERY_TIME_ELAPSED:
-		/* only a4xx, requires new enough kernel so we know max_freq: */
-		return (screen->max_freq > 0) && (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen));
-
-	case PIPE_CAP_VENDOR_ID:
-		return 0x5143;
-	case PIPE_CAP_DEVICE_ID:
-		return 0xFFFFFFFF;
-	case PIPE_CAP_ACCELERATED:
-		return 1;
-	case PIPE_CAP_VIDEO_MEMORY:
-		DBG("FINISHME: The value returned is incorrect\n");
-		return 10;
-	case PIPE_CAP_UMA:
-		return 1;
-	case PIPE_CAP_NATIVE_FENCE_FD:
-		return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
-	default:
-		return u_pipe_screen_get_param_defaults(pscreen, param);
-	}
-}
-
 static float
 fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
 {
@@ -843,23 +609,23 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro)
 	case 201:
 	case 205:
 	case 220:
-		fd2_screen_init(pscreen);
+		fd2_screen_init(pscreen, glsl120);
 		break;
 	case 305:
 	case 307:
 	case 320:
 	case 330:
-		fd3_screen_init(pscreen);
+		fd3_screen_init(pscreen, glsl120);
 		break;
 	case 420:
 	case 430:
-		fd4_screen_init(pscreen);
+		fd4_screen_init(pscreen, glsl120);
 		break;
 	case 530:
-		fd5_screen_init(pscreen);
+		fd5_screen_init(pscreen, glsl120);
 		break;
 	case 630:
-		fd6_screen_init(pscreen);
+		fd6_screen_init(pscreen, glsl120);
 		break;
 	default:
 		debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
@@ -893,7 +659,6 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro)
 	(void) mtx_init(&screen->lock, mtx_plain);
 
 	pscreen->destroy = fd_screen_destroy;
-	pscreen->get_param = fd_screen_get_param;
 	pscreen->get_paramf = fd_screen_get_paramf;
 	pscreen->get_shader_param = fd_screen_get_shader_param;
 	pscreen->get_compute_param = fd_get_compute_param;
-- 
2.21.0



More information about the Freedreno mailing list