101e04c3fSmrg/*
201e04c3fSmrg * Copyright (c) 2012-2015 Etnaviv Project
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the
1201e04c3fSmrg * next paragraph) shall be included in all copies or substantial portions
1301e04c3fSmrg * of the Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Wladimir J. van der Laan <laanwj@gmail.com>
2501e04c3fSmrg *    Christian Gmeiner <christian.gmeiner@gmail.com>
2601e04c3fSmrg */
2701e04c3fSmrg
2801e04c3fSmrg#include "etnaviv_screen.h"
2901e04c3fSmrg
3001e04c3fSmrg#include "hw/common.xml.h"
3101e04c3fSmrg
3201e04c3fSmrg#include "etnaviv_compiler.h"
3301e04c3fSmrg#include "etnaviv_context.h"
3401e04c3fSmrg#include "etnaviv_debug.h"
3501e04c3fSmrg#include "etnaviv_fence.h"
3601e04c3fSmrg#include "etnaviv_format.h"
3701e04c3fSmrg#include "etnaviv_query.h"
3801e04c3fSmrg#include "etnaviv_resource.h"
3901e04c3fSmrg#include "etnaviv_translate.h"
4001e04c3fSmrg
419f464c52Smaya#include "util/hash_table.h"
4201e04c3fSmrg#include "util/os_time.h"
4301e04c3fSmrg#include "util/u_math.h"
4401e04c3fSmrg#include "util/u_memory.h"
4501e04c3fSmrg#include "util/u_screen.h"
4601e04c3fSmrg#include "util/u_string.h"
4701e04c3fSmrg
487ec681f3Smrg#include "frontend/drm_driver.h"
4901e04c3fSmrg
509f464c52Smaya#include "drm-uapi/drm_fourcc.h"
5101e04c3fSmrg
5201e04c3fSmrg#define ETNA_DRM_VERSION_FENCE_FD      ETNA_DRM_VERSION(1, 1)
5301e04c3fSmrg#define ETNA_DRM_VERSION_PERFMON       ETNA_DRM_VERSION(1, 2)
5401e04c3fSmrg
557ec681f3Smrgstatic const struct debug_named_value etna_debug_options[] = {
5601e04c3fSmrg   {"dbg_msgs",       ETNA_DBG_MSGS, "Print debug messages"},
5701e04c3fSmrg   {"frame_msgs",     ETNA_DBG_FRAME_MSGS, "Print frame messages"},
5801e04c3fSmrg   {"resource_msgs",  ETNA_DBG_RESOURCE_MSGS, "Print resource messages"},
5901e04c3fSmrg   {"compiler_msgs",  ETNA_DBG_COMPILER_MSGS, "Print compiler messages"},
6001e04c3fSmrg   {"linker_msgs",    ETNA_DBG_LINKER_MSGS, "Print linker messages"},
6101e04c3fSmrg   {"dump_shaders",   ETNA_DBG_DUMP_SHADERS, "Dump shaders"},
6201e04c3fSmrg   {"no_ts",          ETNA_DBG_NO_TS, "Disable TS"},
6301e04c3fSmrg   {"no_autodisable", ETNA_DBG_NO_AUTODISABLE, "Disable autodisable"},
6401e04c3fSmrg   {"no_supertile",   ETNA_DBG_NO_SUPERTILE, "Disable supertiles"},
6501e04c3fSmrg   {"no_early_z",     ETNA_DBG_NO_EARLY_Z, "Disable early z"},
669f464c52Smaya   {"cflush_all",     ETNA_DBG_CFLUSH_ALL, "Flush every cache before state update"},
6701e04c3fSmrg   {"msaa2x",         ETNA_DBG_MSAA_2X, "Force 2x msaa"},
6801e04c3fSmrg   {"msaa4x",         ETNA_DBG_MSAA_4X, "Force 4x msaa"},
6901e04c3fSmrg   {"flush_all",      ETNA_DBG_FLUSH_ALL, "Flush after every rendered primitive"},
7001e04c3fSmrg   {"zero",           ETNA_DBG_ZERO, "Zero all resources after allocation"},
7101e04c3fSmrg   {"draw_stall",     ETNA_DBG_DRAW_STALL, "Stall FE/PE after each rendered primitive"},
7201e04c3fSmrg   {"shaderdb",       ETNA_DBG_SHADERDB, "Enable shaderdb output"},
7301e04c3fSmrg   {"no_singlebuffer",ETNA_DBG_NO_SINGLEBUF, "Disable single buffer feature"},
747ec681f3Smrg   {"nir",            ETNA_DBG_NIR, "use new NIR compiler"},
757ec681f3Smrg   {"deqp",           ETNA_DBG_DEQP, "Hacks to run dEQP GLES3 tests"}, /* needs MESA_GLES_VERSION_OVERRIDE=3.0 */
767ec681f3Smrg   {"nocache",        ETNA_DBG_NOCACHE,    "Disable shader cache"},
7701e04c3fSmrg   DEBUG_NAMED_VALUE_END
7801e04c3fSmrg};
7901e04c3fSmrg
807ec681f3SmrgDEBUG_GET_ONCE_FLAGS_OPTION(etna_mesa_debug, "ETNA_MESA_DEBUG", etna_debug_options, 0)
8101e04c3fSmrgint etna_mesa_debug = 0;
8201e04c3fSmrg
8301e04c3fSmrgstatic void
8401e04c3fSmrgetna_screen_destroy(struct pipe_screen *pscreen)
8501e04c3fSmrg{
8601e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
8701e04c3fSmrg
8801e04c3fSmrg   if (screen->perfmon)
8901e04c3fSmrg      etna_perfmon_del(screen->perfmon);
9001e04c3fSmrg
917ec681f3Smrg   if (screen->compiler)
927ec681f3Smrg      etna_compiler_destroy(screen->compiler);
937ec681f3Smrg
9401e04c3fSmrg   if (screen->pipe)
9501e04c3fSmrg      etna_pipe_del(screen->pipe);
9601e04c3fSmrg
9701e04c3fSmrg   if (screen->gpu)
9801e04c3fSmrg      etna_gpu_del(screen->gpu);
9901e04c3fSmrg
10001e04c3fSmrg   if (screen->ro)
1017ec681f3Smrg      screen->ro->destroy(screen->ro);
10201e04c3fSmrg
10301e04c3fSmrg   if (screen->dev)
10401e04c3fSmrg      etna_device_del(screen->dev);
10501e04c3fSmrg
10601e04c3fSmrg   FREE(screen);
10701e04c3fSmrg}
10801e04c3fSmrg
10901e04c3fSmrgstatic const char *
11001e04c3fSmrgetna_screen_get_name(struct pipe_screen *pscreen)
11101e04c3fSmrg{
11201e04c3fSmrg   struct etna_screen *priv = etna_screen(pscreen);
11301e04c3fSmrg   static char buffer[128];
11401e04c3fSmrg
1157ec681f3Smrg   snprintf(buffer, sizeof(buffer), "Vivante GC%x rev %04x", priv->model,
1167ec681f3Smrg            priv->revision);
11701e04c3fSmrg
11801e04c3fSmrg   return buffer;
11901e04c3fSmrg}
12001e04c3fSmrg
12101e04c3fSmrgstatic const char *
12201e04c3fSmrgetna_screen_get_vendor(struct pipe_screen *pscreen)
12301e04c3fSmrg{
12401e04c3fSmrg   return "etnaviv";
12501e04c3fSmrg}
12601e04c3fSmrg
12701e04c3fSmrgstatic const char *
12801e04c3fSmrgetna_screen_get_device_vendor(struct pipe_screen *pscreen)
12901e04c3fSmrg{
13001e04c3fSmrg   return "Vivante";
13101e04c3fSmrg}
13201e04c3fSmrg
13301e04c3fSmrgstatic int
13401e04c3fSmrgetna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
13501e04c3fSmrg{
13601e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
13701e04c3fSmrg
13801e04c3fSmrg   switch (param) {
13901e04c3fSmrg   /* Supported features (boolean caps). */
14001e04c3fSmrg   case PIPE_CAP_POINT_SPRITE:
14101e04c3fSmrg   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
14201e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
14301e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
1447ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
1457ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
1467ec681f3Smrg   case PIPE_CAP_VERTEX_SHADER_SATURATE:
14701e04c3fSmrg   case PIPE_CAP_TEXTURE_BARRIER:
14801e04c3fSmrg   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
14901e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
15001e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
15101e04c3fSmrg   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
15201e04c3fSmrg   case PIPE_CAP_TGSI_TEXCOORD:
15301e04c3fSmrg   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
15401e04c3fSmrg   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
1557ec681f3Smrg   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
1567ec681f3Smrg   case PIPE_CAP_STRING_MARKER:
15701e04c3fSmrg      return 1;
15801e04c3fSmrg   case PIPE_CAP_NATIVE_FENCE_FD:
15901e04c3fSmrg      return screen->drm_version >= ETNA_DRM_VERSION_FENCE_FD;
1607ec681f3Smrg   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
1617ec681f3Smrg   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: /* note: not integer */
1627ec681f3Smrg      return DBG_ENABLED(ETNA_DBG_NIR);
1637ec681f3Smrg   case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL:
1647ec681f3Smrg      return 0;
16501e04c3fSmrg
16601e04c3fSmrg   /* Memory */
16701e04c3fSmrg   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
16801e04c3fSmrg      return 256;
16901e04c3fSmrg   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
17001e04c3fSmrg      return 4; /* XXX could easily be supported */
17101e04c3fSmrg
17201e04c3fSmrg   case PIPE_CAP_NPOT_TEXTURES:
17301e04c3fSmrg      return true; /* VIV_FEATURE(priv->dev, chipMinorFeatures1,
17401e04c3fSmrg                      NON_POWER_OF_TWO); */
17501e04c3fSmrg
1767ec681f3Smrg   case PIPE_CAP_ANISOTROPIC_FILTER:
17701e04c3fSmrg   case PIPE_CAP_TEXTURE_SWIZZLE:
17801e04c3fSmrg   case PIPE_CAP_PRIMITIVE_RESTART:
1797ec681f3Smrg   case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
18001e04c3fSmrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
18101e04c3fSmrg
1827ec681f3Smrg   case PIPE_CAP_ALPHA_TEST:
1837ec681f3Smrg      if (DBG_ENABLED(ETNA_DBG_NIR))
1847ec681f3Smrg         return !VIV_FEATURE(screen, chipMinorFeatures7, PE_NO_ALPHA_TEST);
1857ec681f3Smrg      else
1867ec681f3Smrg         return 1;
18701e04c3fSmrg
18801e04c3fSmrg   /* Unsupported features. */
18901e04c3fSmrg   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
19001e04c3fSmrg   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
19101e04c3fSmrg   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
1927ec681f3Smrg   case PIPE_CAP_TEXRECT:
19301e04c3fSmrg      return 0;
19401e04c3fSmrg
19501e04c3fSmrg   /* Stream output. */
19601e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
1977ec681f3Smrg      return DBG_ENABLED(ETNA_DBG_DEQP) ? 4 : 0;
19801e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
19901e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
20001e04c3fSmrg      return 0;
20101e04c3fSmrg
20201e04c3fSmrg   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
20301e04c3fSmrg      return 128;
20401e04c3fSmrg   case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
20501e04c3fSmrg      return 255;
2067ec681f3Smrg   case PIPE_CAP_MAX_VERTEX_BUFFERS:
2077ec681f3Smrg      return screen->specs.stream_count;
2087ec681f3Smrg   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
2097ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
2107ec681f3Smrg
21101e04c3fSmrg
21201e04c3fSmrg   /* Texturing. */
2137ec681f3Smrg   case PIPE_CAP_TEXTURE_SHADOW_MAP:
2147ec681f3Smrg      return DBG_ENABLED(ETNA_DBG_NIR) && screen->specs.halti >= 2;
2157ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
2167ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: /* TODO: verify */
2177ec681f3Smrg      return screen->specs.max_texture_size;
21801e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
2197ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
22001e04c3fSmrg   {
22101e04c3fSmrg      int log2_max_tex_size = util_last_bit(screen->specs.max_texture_size);
22201e04c3fSmrg      assert(log2_max_tex_size > 0);
22301e04c3fSmrg      return log2_max_tex_size;
22401e04c3fSmrg   }
2257ec681f3Smrg
22601e04c3fSmrg   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
22701e04c3fSmrg   case PIPE_CAP_MIN_TEXEL_OFFSET:
22801e04c3fSmrg      return -8;
22901e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
23001e04c3fSmrg   case PIPE_CAP_MAX_TEXEL_OFFSET:
23101e04c3fSmrg      return 7;
2327ec681f3Smrg   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
2337ec681f3Smrg      return screen->specs.seamless_cube_map;
23401e04c3fSmrg
2357ec681f3Smrg   /* Queries. */
23601e04c3fSmrg   case PIPE_CAP_OCCLUSION_QUERY:
23701e04c3fSmrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
23801e04c3fSmrg
23901e04c3fSmrg   /* Preferences */
24001e04c3fSmrg   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
24101e04c3fSmrg      return 0;
2427ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET: {
2437ec681f3Smrg      /* etnaviv is being run on systems as small as 256MB total RAM so
2447ec681f3Smrg       * we need to provide a sane value for such a device. Limit the
2457ec681f3Smrg       * memory budget to min(~3% of pyhiscal memory, 64MB).
2467ec681f3Smrg       *
2477ec681f3Smrg       * a simple divison by 32 provides the numbers we want.
2487ec681f3Smrg       *    256MB / 32 =  8MB
2497ec681f3Smrg       *   2048MB / 32 = 64MB
2507ec681f3Smrg       */
2517ec681f3Smrg      uint64_t system_memory;
2527ec681f3Smrg
2537ec681f3Smrg      if (!os_get_total_physical_memory(&system_memory))
2547ec681f3Smrg         system_memory = (uint64_t)4096 << 20;
2557ec681f3Smrg
2567ec681f3Smrg      return MIN2(system_memory / 32, 64 * 1024 * 1024);
2577ec681f3Smrg   }
25801e04c3fSmrg
2599f464c52Smaya   case PIPE_CAP_MAX_VARYINGS:
2609f464c52Smaya      return screen->specs.max_varyings;
2619f464c52Smaya
2627ec681f3Smrg   case PIPE_CAP_SUPPORTED_PRIM_MODES:
2637ec681f3Smrg   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: {
2647ec681f3Smrg      /* Generate the bitmask of supported draw primitives. */
2657ec681f3Smrg      uint32_t modes = 1 << PIPE_PRIM_POINTS |
2667ec681f3Smrg                       1 << PIPE_PRIM_LINES |
2677ec681f3Smrg                       1 << PIPE_PRIM_LINE_STRIP |
2687ec681f3Smrg                       1 << PIPE_PRIM_TRIANGLES |
2697ec681f3Smrg                       1 << PIPE_PRIM_TRIANGLE_FAN;
2707ec681f3Smrg
2717ec681f3Smrg      /* TODO: The bug relates only to indexed draws, but here we signal
2727ec681f3Smrg       * that there is no support for triangle strips at all. This should
2737ec681f3Smrg       * be refined.
2747ec681f3Smrg       */
2757ec681f3Smrg      if (VIV_FEATURE(screen, chipMinorFeatures2, BUG_FIXES8))
2767ec681f3Smrg         modes |= 1 << PIPE_PRIM_TRIANGLE_STRIP;
2777ec681f3Smrg
2787ec681f3Smrg      if (VIV_FEATURE(screen, chipMinorFeatures2, LINE_LOOP))
2797ec681f3Smrg         modes |= 1 << PIPE_PRIM_LINE_LOOP;
2807ec681f3Smrg
2817ec681f3Smrg      return modes;
2827ec681f3Smrg   }
2837ec681f3Smrg
28401e04c3fSmrg   case PIPE_CAP_PCI_GROUP:
28501e04c3fSmrg   case PIPE_CAP_PCI_BUS:
28601e04c3fSmrg   case PIPE_CAP_PCI_DEVICE:
28701e04c3fSmrg   case PIPE_CAP_PCI_FUNCTION:
28801e04c3fSmrg      return 0;
28901e04c3fSmrg   case PIPE_CAP_ACCELERATED:
29001e04c3fSmrg      return 1;
29101e04c3fSmrg   case PIPE_CAP_VIDEO_MEMORY:
29201e04c3fSmrg      return 0;
29301e04c3fSmrg   case PIPE_CAP_UMA:
29401e04c3fSmrg      return 1;
29501e04c3fSmrg   default:
29601e04c3fSmrg      return u_pipe_screen_get_param_defaults(pscreen, param);
29701e04c3fSmrg   }
29801e04c3fSmrg}
29901e04c3fSmrg
30001e04c3fSmrgstatic float
30101e04c3fSmrgetna_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
30201e04c3fSmrg{
30301e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
30401e04c3fSmrg
30501e04c3fSmrg   switch (param) {
30601e04c3fSmrg   case PIPE_CAPF_MAX_LINE_WIDTH:
30701e04c3fSmrg   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
30801e04c3fSmrg   case PIPE_CAPF_MAX_POINT_WIDTH:
30901e04c3fSmrg   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
31001e04c3fSmrg      return 8192.0f;
31101e04c3fSmrg   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
31201e04c3fSmrg      return 16.0f;
31301e04c3fSmrg   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
31401e04c3fSmrg      return util_last_bit(screen->specs.max_texture_size);
31501e04c3fSmrg   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
31601e04c3fSmrg   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
31701e04c3fSmrg   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
31801e04c3fSmrg      return 0.0f;
31901e04c3fSmrg   }
32001e04c3fSmrg
32101e04c3fSmrg   debug_printf("unknown paramf %d", param);
32201e04c3fSmrg   return 0;
32301e04c3fSmrg}
32401e04c3fSmrg
32501e04c3fSmrgstatic int
32601e04c3fSmrgetna_screen_get_shader_param(struct pipe_screen *pscreen,
32701e04c3fSmrg                             enum pipe_shader_type shader,
32801e04c3fSmrg                             enum pipe_shader_cap param)
32901e04c3fSmrg{
33001e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
3317ec681f3Smrg   bool ubo_enable = screen->specs.halti >= 2 && DBG_ENABLED(ETNA_DBG_NIR);
3327ec681f3Smrg
3337ec681f3Smrg   if (DBG_ENABLED(ETNA_DBG_DEQP))
3347ec681f3Smrg      ubo_enable = true;
33501e04c3fSmrg
33601e04c3fSmrg   switch (shader) {
33701e04c3fSmrg   case PIPE_SHADER_FRAGMENT:
33801e04c3fSmrg   case PIPE_SHADER_VERTEX:
33901e04c3fSmrg      break;
34001e04c3fSmrg   case PIPE_SHADER_COMPUTE:
34101e04c3fSmrg   case PIPE_SHADER_GEOMETRY:
34201e04c3fSmrg   case PIPE_SHADER_TESS_CTRL:
34301e04c3fSmrg   case PIPE_SHADER_TESS_EVAL:
34401e04c3fSmrg      return 0;
34501e04c3fSmrg   default:
34601e04c3fSmrg      DBG("unknown shader type %d", shader);
34701e04c3fSmrg      return 0;
34801e04c3fSmrg   }
34901e04c3fSmrg
35001e04c3fSmrg   switch (param) {
35101e04c3fSmrg   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
35201e04c3fSmrg   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
35301e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
35401e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
35501e04c3fSmrg      return ETNA_MAX_TOKENS;
35601e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
35701e04c3fSmrg      return ETNA_MAX_DEPTH; /* XXX */
35801e04c3fSmrg   case PIPE_SHADER_CAP_MAX_INPUTS:
35901e04c3fSmrg      /* Maximum number of inputs for the vertex shader is the number
36001e04c3fSmrg       * of vertex elements - each element defines one vertex shader
36101e04c3fSmrg       * input register.  For the fragment shader, this is the number
36201e04c3fSmrg       * of varyings. */
36301e04c3fSmrg      return shader == PIPE_SHADER_FRAGMENT ? screen->specs.max_varyings
36401e04c3fSmrg                                            : screen->specs.vertex_max_elements;
36501e04c3fSmrg   case PIPE_SHADER_CAP_MAX_OUTPUTS:
36601e04c3fSmrg      return 16; /* see VIVS_VS_OUTPUT */
36701e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEMPS:
36801e04c3fSmrg      return 64; /* Max native temporaries. */
36901e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
3707ec681f3Smrg      return ubo_enable ? ETNA_MAX_CONST_BUF : 1;
37101e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
37201e04c3fSmrg      return 1;
37301e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
37401e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
37501e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
37601e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
37701e04c3fSmrg      return 1;
37801e04c3fSmrg   case PIPE_SHADER_CAP_SUBROUTINES:
37901e04c3fSmrg      return 0;
38001e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
38101e04c3fSmrg      return VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
38201e04c3fSmrg   case PIPE_SHADER_CAP_INT64_ATOMICS:
38301e04c3fSmrg   case PIPE_SHADER_CAP_FP16:
3847ec681f3Smrg   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
3857ec681f3Smrg   case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
3867ec681f3Smrg   case PIPE_SHADER_CAP_INT16:
3877ec681f3Smrg   case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
38801e04c3fSmrg      return 0;
3897ec681f3Smrg   case PIPE_SHADER_CAP_INTEGERS:
3907ec681f3Smrg      return DBG_ENABLED(ETNA_DBG_NIR) && screen->specs.halti >= 2;
39101e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
39201e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
39301e04c3fSmrg      return shader == PIPE_SHADER_FRAGMENT
39401e04c3fSmrg                ? screen->specs.fragment_sampler_count
39501e04c3fSmrg                : screen->specs.vertex_sampler_count;
39601e04c3fSmrg   case PIPE_SHADER_CAP_PREFERRED_IR:
3977ec681f3Smrg      return DBG_ENABLED(ETNA_DBG_NIR) ? PIPE_SHADER_IR_NIR : PIPE_SHADER_IR_TGSI;
39801e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
3997ec681f3Smrg      if (ubo_enable)
4007ec681f3Smrg         return 16384; /* 16384 so state tracker enables UBOs */
4017ec681f3Smrg      return shader == PIPE_SHADER_FRAGMENT
4027ec681f3Smrg                ? screen->specs.max_ps_uniforms * sizeof(float[4])
4037ec681f3Smrg                : screen->specs.max_vs_uniforms * sizeof(float[4]);
40401e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
40501e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
40601e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
40701e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
40801e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
40901e04c3fSmrg      return false;
41001e04c3fSmrg   case PIPE_SHADER_CAP_SUPPORTED_IRS:
4117ec681f3Smrg      return (1 << PIPE_SHADER_IR_TGSI) |
4127ec681f3Smrg             (DBG_ENABLED(ETNA_DBG_NIR) ? 1 << PIPE_SHADER_IR_NIR : 0);
41301e04c3fSmrg   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
41401e04c3fSmrg      return 32;
41501e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
41601e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
41701e04c3fSmrg   case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
41801e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
41901e04c3fSmrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
42001e04c3fSmrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
42101e04c3fSmrg      return 0;
42201e04c3fSmrg   }
42301e04c3fSmrg
42401e04c3fSmrg   debug_printf("unknown shader param %d", param);
42501e04c3fSmrg   return 0;
42601e04c3fSmrg}
42701e04c3fSmrg
42801e04c3fSmrgstatic uint64_t
42901e04c3fSmrgetna_screen_get_timestamp(struct pipe_screen *pscreen)
43001e04c3fSmrg{
43101e04c3fSmrg   return os_time_get_nano();
43201e04c3fSmrg}
43301e04c3fSmrg
43401e04c3fSmrgstatic bool
4357ec681f3Smrggpu_supports_texture_target(struct etna_screen *screen,
4367ec681f3Smrg                            enum pipe_texture_target target)
4377ec681f3Smrg{
4387ec681f3Smrg   if (target == PIPE_TEXTURE_CUBE_ARRAY)
4397ec681f3Smrg      return false;
4407ec681f3Smrg
4417ec681f3Smrg   /* pre-halti has no array/3D */
4427ec681f3Smrg   if (screen->specs.halti < 0 &&
4437ec681f3Smrg       (target == PIPE_TEXTURE_1D_ARRAY ||
4447ec681f3Smrg        target == PIPE_TEXTURE_2D_ARRAY ||
4457ec681f3Smrg        target == PIPE_TEXTURE_3D))
4467ec681f3Smrg      return false;
4477ec681f3Smrg
4487ec681f3Smrg   return true;
4497ec681f3Smrg}
4507ec681f3Smrg
4517ec681f3Smrgstatic bool
4527ec681f3Smrggpu_supports_texture_format(struct etna_screen *screen, uint32_t fmt,
4537ec681f3Smrg                            enum pipe_format format)
45401e04c3fSmrg{
45501e04c3fSmrg   bool supported = true;
45601e04c3fSmrg
45701e04c3fSmrg   if (fmt == TEXTURE_FORMAT_ETC1)
45801e04c3fSmrg      supported = VIV_FEATURE(screen, chipFeatures, ETC1_TEXTURE_COMPRESSION);
45901e04c3fSmrg
46001e04c3fSmrg   if (fmt >= TEXTURE_FORMAT_DXT1 && fmt <= TEXTURE_FORMAT_DXT4_DXT5)
46101e04c3fSmrg      supported = VIV_FEATURE(screen, chipFeatures, DXT_TEXTURE_COMPRESSION);
46201e04c3fSmrg
46301e04c3fSmrg   if (util_format_is_srgb(format))
46401e04c3fSmrg      supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
46501e04c3fSmrg
4669f464c52Smaya   if (fmt & EXT_FORMAT)
46701e04c3fSmrg      supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
46801e04c3fSmrg
46901e04c3fSmrg   if (fmt & ASTC_FORMAT) {
47001e04c3fSmrg      supported = screen->specs.tex_astc;
47101e04c3fSmrg   }
47201e04c3fSmrg
4737ec681f3Smrg   if (util_format_is_snorm(format))
4747ec681f3Smrg      supported = VIV_FEATURE(screen, chipMinorFeatures2, HALTI1);
4757ec681f3Smrg
4767ec681f3Smrg   if (format != PIPE_FORMAT_S8_UINT_Z24_UNORM &&
4777ec681f3Smrg       (util_format_is_pure_integer(format) || util_format_is_float(format)))
4787ec681f3Smrg      supported = VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
4797ec681f3Smrg
4807ec681f3Smrg
48101e04c3fSmrg   if (!supported)
48201e04c3fSmrg      return false;
48301e04c3fSmrg
48401e04c3fSmrg   if (texture_format_needs_swiz(format))
48501e04c3fSmrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
48601e04c3fSmrg
48701e04c3fSmrg   return true;
48801e04c3fSmrg}
48901e04c3fSmrg
4907ec681f3Smrgstatic bool
4917ec681f3Smrggpu_supports_render_format(struct etna_screen *screen, enum pipe_format format,
4927ec681f3Smrg                           unsigned sample_count)
4937ec681f3Smrg{
4947ec681f3Smrg   const uint32_t fmt = translate_pe_format(format);
4957ec681f3Smrg
4967ec681f3Smrg   if (fmt == ETNA_NO_MATCH)
4977ec681f3Smrg      return false;
4987ec681f3Smrg
4997ec681f3Smrg   /* MSAA is broken */
5007ec681f3Smrg   if (sample_count > 1)
5017ec681f3Smrg         return false;
5027ec681f3Smrg
5037ec681f3Smrg   if (format == PIPE_FORMAT_R8_UNORM)
5047ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures5, HALTI5);
5057ec681f3Smrg
5067ec681f3Smrg   /* figure out 8bpp RS clear to enable these formats */
5077ec681f3Smrg   if (format == PIPE_FORMAT_R8_SINT || format == PIPE_FORMAT_R8_UINT)
5087ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures5, HALTI5);
5097ec681f3Smrg
5107ec681f3Smrg   if (util_format_is_srgb(format))
5117ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures5, HALTI3);
5127ec681f3Smrg
5137ec681f3Smrg   if (util_format_is_pure_integer(format) || util_format_is_float(format))
5147ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
5157ec681f3Smrg
5167ec681f3Smrg   if (format == PIPE_FORMAT_R8G8_UNORM)
5177ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
5187ec681f3Smrg
5197ec681f3Smrg   /* any other extended format is HALTI0 (only R10G10B10A2?) */
5207ec681f3Smrg   if (fmt >= PE_FORMAT_R16F)
5217ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
5227ec681f3Smrg
5237ec681f3Smrg   return true;
5247ec681f3Smrg}
5257ec681f3Smrg
5267ec681f3Smrgstatic bool
5277ec681f3Smrggpu_supports_vertex_format(struct etna_screen *screen, enum pipe_format format)
5287ec681f3Smrg{
5297ec681f3Smrg   if (translate_vertex_format_type(format) == ETNA_NO_MATCH)
5307ec681f3Smrg      return false;
5317ec681f3Smrg
5327ec681f3Smrg   if (util_format_is_pure_integer(format))
5337ec681f3Smrg      return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
5347ec681f3Smrg
5357ec681f3Smrg   return true;
5367ec681f3Smrg}
5377ec681f3Smrg
5387ec681f3Smrgstatic bool
53901e04c3fSmrgetna_screen_is_format_supported(struct pipe_screen *pscreen,
54001e04c3fSmrg                                enum pipe_format format,
54101e04c3fSmrg                                enum pipe_texture_target target,
54201e04c3fSmrg                                unsigned sample_count,
54301e04c3fSmrg                                unsigned storage_sample_count,
54401e04c3fSmrg                                unsigned usage)
54501e04c3fSmrg{
54601e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
54701e04c3fSmrg   unsigned allowed = 0;
54801e04c3fSmrg
5497ec681f3Smrg   if (!gpu_supports_texture_target(screen, target))
5507ec681f3Smrg      return false;
55101e04c3fSmrg
55201e04c3fSmrg   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
55301e04c3fSmrg      return false;
55401e04c3fSmrg
55501e04c3fSmrg   if (usage & PIPE_BIND_RENDER_TARGET) {
5567ec681f3Smrg      if (gpu_supports_render_format(screen, format, sample_count))
5577ec681f3Smrg         allowed |= PIPE_BIND_RENDER_TARGET;
55801e04c3fSmrg   }
55901e04c3fSmrg
56001e04c3fSmrg   if (usage & PIPE_BIND_DEPTH_STENCIL) {
56101e04c3fSmrg      if (translate_depth_format(format) != ETNA_NO_MATCH)
56201e04c3fSmrg         allowed |= PIPE_BIND_DEPTH_STENCIL;
56301e04c3fSmrg   }
56401e04c3fSmrg
56501e04c3fSmrg   if (usage & PIPE_BIND_SAMPLER_VIEW) {
56601e04c3fSmrg      uint32_t fmt = translate_texture_format(format);
56701e04c3fSmrg
5687ec681f3Smrg      if (!gpu_supports_texture_format(screen, fmt, format))
56901e04c3fSmrg         fmt = ETNA_NO_MATCH;
57001e04c3fSmrg
57101e04c3fSmrg      if (sample_count < 2 && fmt != ETNA_NO_MATCH)
57201e04c3fSmrg         allowed |= PIPE_BIND_SAMPLER_VIEW;
57301e04c3fSmrg   }
57401e04c3fSmrg
57501e04c3fSmrg   if (usage & PIPE_BIND_VERTEX_BUFFER) {
5767ec681f3Smrg      if (gpu_supports_vertex_format(screen, format))
57701e04c3fSmrg         allowed |= PIPE_BIND_VERTEX_BUFFER;
57801e04c3fSmrg   }
57901e04c3fSmrg
58001e04c3fSmrg   if (usage & PIPE_BIND_INDEX_BUFFER) {
58101e04c3fSmrg      /* must be supported index format */
5827ec681f3Smrg      if (format == PIPE_FORMAT_R8_UINT || format == PIPE_FORMAT_R16_UINT ||
5837ec681f3Smrg          (format == PIPE_FORMAT_R32_UINT &&
58401e04c3fSmrg           VIV_FEATURE(screen, chipFeatures, 32_BIT_INDICES))) {
58501e04c3fSmrg         allowed |= PIPE_BIND_INDEX_BUFFER;
58601e04c3fSmrg      }
58701e04c3fSmrg   }
58801e04c3fSmrg
58901e04c3fSmrg   /* Always allowed */
59001e04c3fSmrg   allowed |=
59101e04c3fSmrg      usage & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
59201e04c3fSmrg
59301e04c3fSmrg   if (usage != allowed) {
59401e04c3fSmrg      DBG("not supported: format=%s, target=%d, sample_count=%d, "
59501e04c3fSmrg          "usage=%x, allowed=%x",
59601e04c3fSmrg          util_format_name(format), target, sample_count, usage, allowed);
59701e04c3fSmrg   }
59801e04c3fSmrg
59901e04c3fSmrg   return usage == allowed;
60001e04c3fSmrg}
60101e04c3fSmrg
60201e04c3fSmrgconst uint64_t supported_modifiers[] = {
60301e04c3fSmrg   DRM_FORMAT_MOD_LINEAR,
60401e04c3fSmrg   DRM_FORMAT_MOD_VIVANTE_TILED,
60501e04c3fSmrg   DRM_FORMAT_MOD_VIVANTE_SUPER_TILED,
60601e04c3fSmrg   DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED,
60701e04c3fSmrg   DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED,
60801e04c3fSmrg};
60901e04c3fSmrg
6107ec681f3Smrgstatic bool modifier_num_supported(struct pipe_screen *pscreen, int num)
6117ec681f3Smrg{
6127ec681f3Smrg   struct etna_screen *screen = etna_screen(pscreen);
6137ec681f3Smrg
6147ec681f3Smrg   /* don't advertise split tiled formats on single pipe/buffer GPUs */
6157ec681f3Smrg   if ((screen->specs.pixel_pipes == 1 || screen->specs.single_buffer) &&
6167ec681f3Smrg       num >= 3)
6177ec681f3Smrg      return false;
6187ec681f3Smrg
6197ec681f3Smrg   return true;
6207ec681f3Smrg}
6217ec681f3Smrg
62201e04c3fSmrgstatic void
62301e04c3fSmrgetna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
62401e04c3fSmrg                                   enum pipe_format format, int max,
62501e04c3fSmrg                                   uint64_t *modifiers,
62601e04c3fSmrg                                   unsigned int *external_only, int *count)
62701e04c3fSmrg{
62801e04c3fSmrg   int i, num_modifiers = 0;
62901e04c3fSmrg
63001e04c3fSmrg   if (max > ARRAY_SIZE(supported_modifiers))
63101e04c3fSmrg      max = ARRAY_SIZE(supported_modifiers);
63201e04c3fSmrg
63301e04c3fSmrg   if (!max) {
63401e04c3fSmrg      modifiers = NULL;
63501e04c3fSmrg      max = ARRAY_SIZE(supported_modifiers);
63601e04c3fSmrg   }
63701e04c3fSmrg
63801e04c3fSmrg   for (i = 0; num_modifiers < max; i++) {
6397ec681f3Smrg      if (!modifier_num_supported(pscreen, i))
64001e04c3fSmrg         break;
64101e04c3fSmrg
64201e04c3fSmrg      if (modifiers)
64301e04c3fSmrg         modifiers[num_modifiers] = supported_modifiers[i];
64401e04c3fSmrg      if (external_only)
64501e04c3fSmrg         external_only[num_modifiers] = util_format_is_yuv(format) ? 1 : 0;
64601e04c3fSmrg      num_modifiers++;
64701e04c3fSmrg   }
64801e04c3fSmrg
64901e04c3fSmrg   *count = num_modifiers;
65001e04c3fSmrg}
65101e04c3fSmrg
6527ec681f3Smrgstatic bool
6537ec681f3Smrgetna_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
6547ec681f3Smrg                                         uint64_t modifier,
6557ec681f3Smrg                                         enum pipe_format format,
6567ec681f3Smrg                                         bool *external_only)
6577ec681f3Smrg{
6587ec681f3Smrg   int i;
6597ec681f3Smrg
6607ec681f3Smrg   for (i = 0; i < ARRAY_SIZE(supported_modifiers); i++) {
6617ec681f3Smrg      if (!modifier_num_supported(pscreen, i))
6627ec681f3Smrg         break;
6637ec681f3Smrg
6647ec681f3Smrg      if (modifier == supported_modifiers[i]) {
6657ec681f3Smrg         if (external_only)
6667ec681f3Smrg            *external_only = util_format_is_yuv(format) ? 1 : 0;
6677ec681f3Smrg
6687ec681f3Smrg         return true;
6697ec681f3Smrg      }
6707ec681f3Smrg   }
6717ec681f3Smrg
6727ec681f3Smrg   return false;
6737ec681f3Smrg}
6747ec681f3Smrg
6757ec681f3Smrgstatic void
6767ec681f3Smrgetna_determine_uniform_limits(struct etna_screen *screen)
6777ec681f3Smrg{
6787ec681f3Smrg   /* values for the non unified case are taken from
6797ec681f3Smrg    * gcmCONFIGUREUNIFORMS in the Vivante kernel driver file
6807ec681f3Smrg    * drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h.
6817ec681f3Smrg    */
6827ec681f3Smrg   if (screen->model == chipModel_GC2000 &&
6837ec681f3Smrg       (screen->revision == 0x5118 || screen->revision == 0x5140)) {
6847ec681f3Smrg      screen->specs.max_vs_uniforms = 256;
6857ec681f3Smrg      screen->specs.max_ps_uniforms = 64;
6867ec681f3Smrg   } else if (screen->specs.num_constants == 320) {
6877ec681f3Smrg      screen->specs.max_vs_uniforms = 256;
6887ec681f3Smrg      screen->specs.max_ps_uniforms = 64;
6897ec681f3Smrg   } else if (screen->specs.num_constants > 256 &&
6907ec681f3Smrg              screen->model == chipModel_GC1000) {
6917ec681f3Smrg      /* All GC1000 series chips can only support 64 uniforms for ps on non-unified const mode. */
6927ec681f3Smrg      screen->specs.max_vs_uniforms = 256;
6937ec681f3Smrg      screen->specs.max_ps_uniforms = 64;
6947ec681f3Smrg   } else if (screen->specs.num_constants > 256) {
6957ec681f3Smrg      screen->specs.max_vs_uniforms = 256;
6967ec681f3Smrg      screen->specs.max_ps_uniforms = 256;
6977ec681f3Smrg   } else if (screen->specs.num_constants == 256) {
6987ec681f3Smrg      screen->specs.max_vs_uniforms = 256;
6997ec681f3Smrg      screen->specs.max_ps_uniforms = 256;
7007ec681f3Smrg   } else {
7017ec681f3Smrg      screen->specs.max_vs_uniforms = 168;
7027ec681f3Smrg      screen->specs.max_ps_uniforms = 64;
7037ec681f3Smrg   }
7047ec681f3Smrg}
7057ec681f3Smrg
7067ec681f3Smrgstatic void
7077ec681f3Smrgetna_determine_sampler_limits(struct etna_screen *screen)
7087ec681f3Smrg{
7097ec681f3Smrg   /* vertex and fragment samplers live in one address space */
7107ec681f3Smrg   if (screen->specs.halti >= 1) {
7117ec681f3Smrg      screen->specs.vertex_sampler_offset = 16;
7127ec681f3Smrg      screen->specs.fragment_sampler_count = 16;
7137ec681f3Smrg      screen->specs.vertex_sampler_count = 16;
7147ec681f3Smrg   } else {
7157ec681f3Smrg      screen->specs.vertex_sampler_offset = 8;
7167ec681f3Smrg      screen->specs.fragment_sampler_count = 8;
7177ec681f3Smrg      screen->specs.vertex_sampler_count = 4;
7187ec681f3Smrg   }
7197ec681f3Smrg
7207ec681f3Smrg   if (screen->model == 0x400)
7217ec681f3Smrg      screen->specs.vertex_sampler_count = 0;
7227ec681f3Smrg}
7237ec681f3Smrg
7247ec681f3Smrgstatic bool
72501e04c3fSmrgetna_get_specs(struct etna_screen *screen)
72601e04c3fSmrg{
72701e04c3fSmrg   uint64_t val;
72801e04c3fSmrg   uint32_t instruction_count;
72901e04c3fSmrg
73001e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_INSTRUCTION_COUNT, &val)) {
73101e04c3fSmrg      DBG("could not get ETNA_GPU_INSTRUCTION_COUNT");
73201e04c3fSmrg      goto fail;
73301e04c3fSmrg   }
73401e04c3fSmrg   instruction_count = val;
73501e04c3fSmrg
73601e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE,
73701e04c3fSmrg                          &val)) {
73801e04c3fSmrg      DBG("could not get ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE");
73901e04c3fSmrg      goto fail;
74001e04c3fSmrg   }
74101e04c3fSmrg   screen->specs.vertex_output_buffer_size = val;
74201e04c3fSmrg
74301e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_CACHE_SIZE, &val)) {
74401e04c3fSmrg      DBG("could not get ETNA_GPU_VERTEX_CACHE_SIZE");
74501e04c3fSmrg      goto fail;
74601e04c3fSmrg   }
74701e04c3fSmrg   screen->specs.vertex_cache_size = val;
74801e04c3fSmrg
74901e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_SHADER_CORE_COUNT, &val)) {
75001e04c3fSmrg      DBG("could not get ETNA_GPU_SHADER_CORE_COUNT");
75101e04c3fSmrg      goto fail;
75201e04c3fSmrg   }
75301e04c3fSmrg   screen->specs.shader_core_count = val;
75401e04c3fSmrg
75501e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_STREAM_COUNT, &val)) {
75601e04c3fSmrg      DBG("could not get ETNA_GPU_STREAM_COUNT");
75701e04c3fSmrg      goto fail;
75801e04c3fSmrg   }
75901e04c3fSmrg   screen->specs.stream_count = val;
76001e04c3fSmrg
76101e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REGISTER_MAX, &val)) {
76201e04c3fSmrg      DBG("could not get ETNA_GPU_REGISTER_MAX");
76301e04c3fSmrg      goto fail;
76401e04c3fSmrg   }
76501e04c3fSmrg   screen->specs.max_registers = val;
76601e04c3fSmrg
76701e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_PIXEL_PIPES, &val)) {
76801e04c3fSmrg      DBG("could not get ETNA_GPU_PIXEL_PIPES");
76901e04c3fSmrg      goto fail;
77001e04c3fSmrg   }
77101e04c3fSmrg   screen->specs.pixel_pipes = val;
77201e04c3fSmrg
77301e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_NUM_CONSTANTS, &val)) {
77401e04c3fSmrg      DBG("could not get %s", "ETNA_GPU_NUM_CONSTANTS");
77501e04c3fSmrg      goto fail;
77601e04c3fSmrg   }
77701e04c3fSmrg   if (val == 0) {
77801e04c3fSmrg      fprintf(stderr, "Warning: zero num constants (update kernel?)\n");
77901e04c3fSmrg      val = 168;
78001e04c3fSmrg   }
78101e04c3fSmrg   screen->specs.num_constants = val;
78201e04c3fSmrg
7837ec681f3Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_NUM_VARYINGS, &val)) {
7847ec681f3Smrg      DBG("could not get ETNA_GPU_NUM_VARYINGS");
7857ec681f3Smrg      goto fail;
7867ec681f3Smrg   }
7877ec681f3Smrg   screen->specs.max_varyings = MAX2(val, ETNA_NUM_VARYINGS);
7887ec681f3Smrg
78901e04c3fSmrg   /* Figure out gross GPU architecture. See rnndb/common.xml for a specific
79001e04c3fSmrg    * description of the differences. */
79101e04c3fSmrg   if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI5))
79201e04c3fSmrg      screen->specs.halti = 5; /* New GC7000/GC8x00  */
79301e04c3fSmrg   else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI4))
79401e04c3fSmrg      screen->specs.halti = 4; /* Old GC7000/GC7400 */
79501e04c3fSmrg   else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI3))
79601e04c3fSmrg      screen->specs.halti = 3; /* None? */
79701e04c3fSmrg   else if (VIV_FEATURE(screen, chipMinorFeatures4, HALTI2))
79801e04c3fSmrg      screen->specs.halti = 2; /* GC2500/GC3000/GC5000/GC6400 */
79901e04c3fSmrg   else if (VIV_FEATURE(screen, chipMinorFeatures2, HALTI1))
80001e04c3fSmrg      screen->specs.halti = 1; /* GC900/GC4000/GC7000UL */
80101e04c3fSmrg   else if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0))
80201e04c3fSmrg      screen->specs.halti = 0; /* GC880/GC2000/GC7000TM */
80301e04c3fSmrg   else
80401e04c3fSmrg      screen->specs.halti = -1; /* GC7000nanolite / pre-GC2000 except GC880 */
80501e04c3fSmrg   if (screen->specs.halti >= 0)
80601e04c3fSmrg      DBG("etnaviv: GPU arch: HALTI%d", screen->specs.halti);
80701e04c3fSmrg   else
80801e04c3fSmrg      DBG("etnaviv: GPU arch: pre-HALTI");
80901e04c3fSmrg
81001e04c3fSmrg   screen->specs.can_supertile =
81101e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, SUPER_TILED);
81201e04c3fSmrg   screen->specs.bits_per_tile =
81301e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 2 : 4;
81401e04c3fSmrg   screen->specs.ts_clear_value =
8157ec681f3Smrg      VIV_FEATURE(screen, chipMinorFeatures5, BLT_ENGINE)  ? 0xffffffff :
8167ec681f3Smrg      VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 0x55555555 :
8177ec681f3Smrg                                                             0x11111111;
81801e04c3fSmrg
81901e04c3fSmrg   screen->specs.vs_need_z_div =
82001e04c3fSmrg      screen->model < 0x1000 && screen->model != 0x880;
82101e04c3fSmrg   screen->specs.has_sin_cos_sqrt =
82201e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
82301e04c3fSmrg   screen->specs.has_sign_floor_ceil =
82401e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, HAS_SIGN_FLOOR_CEIL);
82501e04c3fSmrg   screen->specs.has_shader_range_registers =
82601e04c3fSmrg      screen->model >= 0x1000 || screen->model == 0x880;
82701e04c3fSmrg   screen->specs.npot_tex_any_wrap =
82801e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures1, NON_POWER_OF_TWO);
82901e04c3fSmrg   screen->specs.has_new_transcendentals =
83001e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures3, HAS_FAST_TRANSCENDENTALS);
83101e04c3fSmrg   screen->specs.has_halti2_instructions =
83201e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
8337ec681f3Smrg   screen->specs.v4_compression =
8347ec681f3Smrg      VIV_FEATURE(screen, chipMinorFeatures6, V4_COMPRESSION);
8357ec681f3Smrg   screen->specs.seamless_cube_map =
8367ec681f3Smrg      (screen->model != 0x880) && /* Seamless cubemap is broken on GC880? */
8377ec681f3Smrg      VIV_FEATURE(screen, chipMinorFeatures2, SEAMLESS_CUBE_MAP);
83801e04c3fSmrg
83901e04c3fSmrg   if (screen->specs.halti >= 5) {
84001e04c3fSmrg      /* GC7000 - this core must load shaders from memory. */
84101e04c3fSmrg      screen->specs.vs_offset = 0;
84201e04c3fSmrg      screen->specs.ps_offset = 0;
84301e04c3fSmrg      screen->specs.max_instructions = 0; /* Do not program shaders manually */
84401e04c3fSmrg      screen->specs.has_icache = true;
84501e04c3fSmrg   } else if (VIV_FEATURE(screen, chipMinorFeatures3, INSTRUCTION_CACHE)) {
84601e04c3fSmrg      /* GC3000 - this core is capable of loading shaders from
84701e04c3fSmrg       * memory. It can also run shaders from registers, as a fallback, but
84801e04c3fSmrg       * "max_instructions" does not have the correct value. It has place for
84901e04c3fSmrg       * 2*256 instructions just like GC2000, but the offsets are slightly
85001e04c3fSmrg       * different.
85101e04c3fSmrg       */
85201e04c3fSmrg      screen->specs.vs_offset = 0xC000;
85301e04c3fSmrg      /* State 08000-0C000 mirrors 0C000-0E000, and the Vivante driver uses
85401e04c3fSmrg       * this mirror for writing PS instructions, probably safest to do the
85501e04c3fSmrg       * same.
85601e04c3fSmrg       */
85701e04c3fSmrg      screen->specs.ps_offset = 0x8000 + 0x1000;
85801e04c3fSmrg      screen->specs.max_instructions = 256; /* maximum number instructions for non-icache use */
85901e04c3fSmrg      screen->specs.has_icache = true;
86001e04c3fSmrg   } else {
86101e04c3fSmrg      if (instruction_count > 256) { /* unified instruction memory? */
86201e04c3fSmrg         screen->specs.vs_offset = 0xC000;
86301e04c3fSmrg         screen->specs.ps_offset = 0xD000; /* like vivante driver */
86401e04c3fSmrg         screen->specs.max_instructions = 256;
86501e04c3fSmrg      } else {
86601e04c3fSmrg         screen->specs.vs_offset = 0x4000;
86701e04c3fSmrg         screen->specs.ps_offset = 0x6000;
86801e04c3fSmrg         screen->specs.max_instructions = instruction_count / 2;
86901e04c3fSmrg      }
87001e04c3fSmrg      screen->specs.has_icache = false;
87101e04c3fSmrg   }
87201e04c3fSmrg
87301e04c3fSmrg   if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0)) {
87401e04c3fSmrg      screen->specs.vertex_max_elements = 16;
87501e04c3fSmrg   } else {
87601e04c3fSmrg      /* Etna_viv documentation seems confused over the correct value
87701e04c3fSmrg       * here so choose the lower to be safe: HALTI0 says 16 i.s.o.
87801e04c3fSmrg       * 10, but VERTEX_ELEMENT_CONFIG register says 16 i.s.o. 12. */
87901e04c3fSmrg      screen->specs.vertex_max_elements = 10;
88001e04c3fSmrg   }
88101e04c3fSmrg
8827ec681f3Smrg   etna_determine_uniform_limits(screen);
8837ec681f3Smrg   etna_determine_sampler_limits(screen);
88401e04c3fSmrg
88501e04c3fSmrg   if (screen->specs.halti >= 5) {
88601e04c3fSmrg      screen->specs.has_unified_uniforms = true;
88701e04c3fSmrg      screen->specs.vs_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS_MIRROR(0);
88801e04c3fSmrg      screen->specs.ps_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS(screen->specs.max_vs_uniforms*4);
88901e04c3fSmrg   } else if (screen->specs.halti >= 1) {
89001e04c3fSmrg      /* unified uniform memory on GC3000 - HALTI1 feature bit is just a guess
89101e04c3fSmrg      */
89201e04c3fSmrg      screen->specs.has_unified_uniforms = true;
89301e04c3fSmrg      screen->specs.vs_uniforms_offset = VIVS_SH_UNIFORMS(0);
89401e04c3fSmrg      /* hardcode PS uniforms to start after end of VS uniforms -
89501e04c3fSmrg       * for more flexibility this offset could be variable based on the
89601e04c3fSmrg       * shader.
89701e04c3fSmrg       */
89801e04c3fSmrg      screen->specs.ps_uniforms_offset = VIVS_SH_UNIFORMS(screen->specs.max_vs_uniforms*4);
89901e04c3fSmrg   } else {
90001e04c3fSmrg      screen->specs.has_unified_uniforms = false;
90101e04c3fSmrg      screen->specs.vs_uniforms_offset = VIVS_VS_UNIFORMS(0);
90201e04c3fSmrg      screen->specs.ps_uniforms_offset = VIVS_PS_UNIFORMS(0);
90301e04c3fSmrg   }
90401e04c3fSmrg
90501e04c3fSmrg   screen->specs.max_texture_size =
90601e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, TEXTURE_8K) ? 8192 : 2048;
90701e04c3fSmrg   screen->specs.max_rendertarget_size =
90801e04c3fSmrg      VIV_FEATURE(screen, chipMinorFeatures0, RENDERTARGET_8K) ? 8192 : 2048;
90901e04c3fSmrg
91001e04c3fSmrg   screen->specs.single_buffer = VIV_FEATURE(screen, chipMinorFeatures4, SINGLE_BUFFER);
91101e04c3fSmrg   if (screen->specs.single_buffer)
91201e04c3fSmrg      DBG("etnaviv: Single buffer mode enabled with %d pixel pipes", screen->specs.pixel_pipes);
91301e04c3fSmrg
9147ec681f3Smrg   screen->specs.tex_astc = VIV_FEATURE(screen, chipMinorFeatures4, TEXTURE_ASTC) &&
9157ec681f3Smrg                            !VIV_FEATURE(screen, chipMinorFeatures6, NO_ASTC);
91601e04c3fSmrg
91701e04c3fSmrg   screen->specs.use_blt = VIV_FEATURE(screen, chipMinorFeatures5, BLT_ENGINE);
91801e04c3fSmrg
91901e04c3fSmrg   return true;
92001e04c3fSmrg
92101e04c3fSmrgfail:
92201e04c3fSmrg   return false;
92301e04c3fSmrg}
92401e04c3fSmrg
92501e04c3fSmrgstruct etna_bo *
92601e04c3fSmrgetna_screen_bo_from_handle(struct pipe_screen *pscreen,
9277ec681f3Smrg                           struct winsys_handle *whandle)
92801e04c3fSmrg{
92901e04c3fSmrg   struct etna_screen *screen = etna_screen(pscreen);
93001e04c3fSmrg   struct etna_bo *bo;
93101e04c3fSmrg
93201e04c3fSmrg   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
93301e04c3fSmrg      bo = etna_bo_from_name(screen->dev, whandle->handle);
93401e04c3fSmrg   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
93501e04c3fSmrg      bo = etna_bo_from_dmabuf(screen->dev, whandle->handle);
93601e04c3fSmrg   } else {
93701e04c3fSmrg      DBG("Attempt to import unsupported handle type %d", whandle->type);
93801e04c3fSmrg      return NULL;
93901e04c3fSmrg   }
94001e04c3fSmrg
94101e04c3fSmrg   if (!bo) {
94201e04c3fSmrg      DBG("ref name 0x%08x failed", whandle->handle);
94301e04c3fSmrg      return NULL;
94401e04c3fSmrg   }
94501e04c3fSmrg
94601e04c3fSmrg   return bo;
94701e04c3fSmrg}
94801e04c3fSmrg
9497ec681f3Smrgstatic const void *
9507ec681f3Smrgetna_get_compiler_options(struct pipe_screen *pscreen,
9517ec681f3Smrg                          enum pipe_shader_ir ir, unsigned shader)
9527ec681f3Smrg{
9537ec681f3Smrg   return &etna_screen(pscreen)->options;
9547ec681f3Smrg}
9557ec681f3Smrg
9567ec681f3Smrgstatic struct disk_cache *
9577ec681f3Smrgetna_get_disk_shader_cache(struct pipe_screen *pscreen)
9587ec681f3Smrg{
9597ec681f3Smrg   struct etna_screen *screen = etna_screen(pscreen);
9607ec681f3Smrg   struct etna_compiler *compiler = screen->compiler;
9617ec681f3Smrg
9627ec681f3Smrg   return compiler->disk_cache;
9637ec681f3Smrg}
9647ec681f3Smrg
96501e04c3fSmrgstruct pipe_screen *
96601e04c3fSmrgetna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
96701e04c3fSmrg                   struct renderonly *ro)
96801e04c3fSmrg{
96901e04c3fSmrg   struct etna_screen *screen = CALLOC_STRUCT(etna_screen);
97001e04c3fSmrg   struct pipe_screen *pscreen;
97101e04c3fSmrg   uint64_t val;
97201e04c3fSmrg
97301e04c3fSmrg   if (!screen)
97401e04c3fSmrg      return NULL;
97501e04c3fSmrg
97601e04c3fSmrg   pscreen = &screen->base;
97701e04c3fSmrg   screen->dev = dev;
97801e04c3fSmrg   screen->gpu = gpu;
9797ec681f3Smrg   screen->ro = ro;
98001e04c3fSmrg   screen->refcnt = 1;
98101e04c3fSmrg
9827ec681f3Smrg   screen->drm_version = etnaviv_device_version(screen->dev);
98301e04c3fSmrg   etna_mesa_debug = debug_get_option_etna_mesa_debug();
98401e04c3fSmrg
98501e04c3fSmrg   /* Disable autodisable for correct rendering with TS */
98601e04c3fSmrg   etna_mesa_debug |= ETNA_DBG_NO_AUTODISABLE;
98701e04c3fSmrg
98801e04c3fSmrg   screen->pipe = etna_pipe_new(gpu, ETNA_PIPE_3D);
98901e04c3fSmrg   if (!screen->pipe) {
99001e04c3fSmrg      DBG("could not create 3d pipe");
99101e04c3fSmrg      goto fail;
99201e04c3fSmrg   }
99301e04c3fSmrg
99401e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_MODEL, &val)) {
99501e04c3fSmrg      DBG("could not get ETNA_GPU_MODEL");
99601e04c3fSmrg      goto fail;
99701e04c3fSmrg   }
99801e04c3fSmrg   screen->model = val;
99901e04c3fSmrg
100001e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REVISION, &val)) {
100101e04c3fSmrg      DBG("could not get ETNA_GPU_REVISION");
100201e04c3fSmrg      goto fail;
100301e04c3fSmrg   }
100401e04c3fSmrg   screen->revision = val;
100501e04c3fSmrg
100601e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_0, &val)) {
100701e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_0");
100801e04c3fSmrg      goto fail;
100901e04c3fSmrg   }
101001e04c3fSmrg   screen->features[0] = val;
101101e04c3fSmrg
101201e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_1, &val)) {
101301e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_1");
101401e04c3fSmrg      goto fail;
101501e04c3fSmrg   }
101601e04c3fSmrg   screen->features[1] = val;
101701e04c3fSmrg
101801e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_2, &val)) {
101901e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_2");
102001e04c3fSmrg      goto fail;
102101e04c3fSmrg   }
102201e04c3fSmrg   screen->features[2] = val;
102301e04c3fSmrg
102401e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_3, &val)) {
102501e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_3");
102601e04c3fSmrg      goto fail;
102701e04c3fSmrg   }
102801e04c3fSmrg   screen->features[3] = val;
102901e04c3fSmrg
103001e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_4, &val)) {
103101e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_4");
103201e04c3fSmrg      goto fail;
103301e04c3fSmrg   }
103401e04c3fSmrg   screen->features[4] = val;
103501e04c3fSmrg
103601e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_5, &val)) {
103701e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_5");
103801e04c3fSmrg      goto fail;
103901e04c3fSmrg   }
104001e04c3fSmrg   screen->features[5] = val;
104101e04c3fSmrg
104201e04c3fSmrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_6, &val)) {
104301e04c3fSmrg      DBG("could not get ETNA_GPU_FEATURES_6");
104401e04c3fSmrg      goto fail;
104501e04c3fSmrg   }
104601e04c3fSmrg   screen->features[6] = val;
104701e04c3fSmrg
10487ec681f3Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_7, &val)) {
10497ec681f3Smrg      DBG("could not get ETNA_GPU_FEATURES_7");
10507ec681f3Smrg      goto fail;
10517ec681f3Smrg   }
10527ec681f3Smrg   screen->features[7] = val;
10537ec681f3Smrg
10547ec681f3Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_8, &val)) {
10557ec681f3Smrg      DBG("could not get ETNA_GPU_FEATURES_8");
10567ec681f3Smrg      goto fail;
10577ec681f3Smrg   }
10587ec681f3Smrg   screen->features[8] = val;
10597ec681f3Smrg
106001e04c3fSmrg   if (!etna_get_specs(screen))
106101e04c3fSmrg      goto fail;
106201e04c3fSmrg
10637ec681f3Smrg   if (screen->specs.halti >= 5 && !etnaviv_device_softpin_capable(dev)) {
10647ec681f3Smrg      DBG("halti5 requires softpin");
10657ec681f3Smrg      goto fail;
10667ec681f3Smrg   }
10677ec681f3Smrg
10687ec681f3Smrg   screen->options = (nir_shader_compiler_options) {
10697ec681f3Smrg      .lower_fpow = true,
10707ec681f3Smrg      .lower_ftrunc = true,
10717ec681f3Smrg      .fuse_ffma16 = true,
10727ec681f3Smrg      .fuse_ffma32 = true,
10737ec681f3Smrg      .fuse_ffma64 = true,
10747ec681f3Smrg      .lower_bitops = true,
10757ec681f3Smrg      .lower_all_io_to_temps = true,
10767ec681f3Smrg      .vertex_id_zero_based = true,
10777ec681f3Smrg      .lower_flrp32 = true,
10787ec681f3Smrg      .lower_fmod = true,
10797ec681f3Smrg      .lower_vector_cmp = true,
10807ec681f3Smrg      .lower_fdph = true,
10817ec681f3Smrg      .lower_insert_byte = true,
10827ec681f3Smrg      .lower_insert_word = true,
10837ec681f3Smrg      .lower_fdiv = true, /* !screen->specs.has_new_transcendentals */
10847ec681f3Smrg      .lower_fsign = !screen->specs.has_sign_floor_ceil,
10857ec681f3Smrg      .lower_ffloor = !screen->specs.has_sign_floor_ceil,
10867ec681f3Smrg      .lower_fceil = !screen->specs.has_sign_floor_ceil,
10877ec681f3Smrg      .lower_fsqrt = !screen->specs.has_sin_cos_sqrt,
10887ec681f3Smrg      .lower_sincos = !screen->specs.has_sin_cos_sqrt,
10897ec681f3Smrg      .lower_uniforms_to_ubo = screen->specs.halti >= 2,
10907ec681f3Smrg      .force_indirect_unrolling = nir_var_all,
10917ec681f3Smrg   };
10927ec681f3Smrg
109301e04c3fSmrg   /* apply debug options that disable individual features */
109401e04c3fSmrg   if (DBG_ENABLED(ETNA_DBG_NO_EARLY_Z))
109501e04c3fSmrg      screen->features[viv_chipFeatures] |= chipFeatures_NO_EARLY_Z;
109601e04c3fSmrg   if (DBG_ENABLED(ETNA_DBG_NO_TS))
109701e04c3fSmrg         screen->features[viv_chipFeatures] &= ~chipFeatures_FAST_CLEAR;
109801e04c3fSmrg   if (DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE))
109901e04c3fSmrg      screen->features[viv_chipMinorFeatures1] &= ~chipMinorFeatures1_AUTO_DISABLE;
110001e04c3fSmrg   if (DBG_ENABLED(ETNA_DBG_NO_SUPERTILE))
110101e04c3fSmrg      screen->specs.can_supertile = 0;
110201e04c3fSmrg   if (DBG_ENABLED(ETNA_DBG_NO_SINGLEBUF))
110301e04c3fSmrg      screen->specs.single_buffer = 0;
110401e04c3fSmrg
110501e04c3fSmrg   pscreen->destroy = etna_screen_destroy;
110601e04c3fSmrg   pscreen->get_param = etna_screen_get_param;
110701e04c3fSmrg   pscreen->get_paramf = etna_screen_get_paramf;
110801e04c3fSmrg   pscreen->get_shader_param = etna_screen_get_shader_param;
11097ec681f3Smrg   pscreen->get_compiler_options = etna_get_compiler_options;
11107ec681f3Smrg   pscreen->get_disk_shader_cache = etna_get_disk_shader_cache;
111101e04c3fSmrg
111201e04c3fSmrg   pscreen->get_name = etna_screen_get_name;
111301e04c3fSmrg   pscreen->get_vendor = etna_screen_get_vendor;
111401e04c3fSmrg   pscreen->get_device_vendor = etna_screen_get_device_vendor;
111501e04c3fSmrg
111601e04c3fSmrg   pscreen->get_timestamp = etna_screen_get_timestamp;
111701e04c3fSmrg   pscreen->context_create = etna_context_create;
111801e04c3fSmrg   pscreen->is_format_supported = etna_screen_is_format_supported;
111901e04c3fSmrg   pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers;
11207ec681f3Smrg   pscreen->is_dmabuf_modifier_supported = etna_screen_is_dmabuf_modifier_supported;
11217ec681f3Smrg
11227ec681f3Smrg   screen->compiler = etna_compiler_create(etna_screen_get_name(pscreen));
11237ec681f3Smrg   if (!screen->compiler)
11247ec681f3Smrg      goto fail;
112501e04c3fSmrg
112601e04c3fSmrg   etna_fence_screen_init(pscreen);
112701e04c3fSmrg   etna_query_screen_init(pscreen);
112801e04c3fSmrg   etna_resource_screen_init(pscreen);
112901e04c3fSmrg
113001e04c3fSmrg   util_dynarray_init(&screen->supported_pm_queries, NULL);
113101e04c3fSmrg   slab_create_parent(&screen->transfer_pool, sizeof(struct etna_transfer), 16);
113201e04c3fSmrg
113301e04c3fSmrg   if (screen->drm_version >= ETNA_DRM_VERSION_PERFMON)
113401e04c3fSmrg      etna_pm_query_setup(screen);
113501e04c3fSmrg
113601e04c3fSmrg   return pscreen;
113701e04c3fSmrg
113801e04c3fSmrgfail:
113901e04c3fSmrg   etna_screen_destroy(pscreen);
114001e04c3fSmrg   return NULL;
114101e04c3fSmrg}
1142