1b8e80941Smrg/*
2b8e80941Smrg * Copyright (c) 2012-2015 Etnaviv Project
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sub license,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the
12b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions
13b8e80941Smrg * of the Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Wladimir J. van der Laan <laanwj@gmail.com>
25b8e80941Smrg *    Christian Gmeiner <christian.gmeiner@gmail.com>
26b8e80941Smrg */
27b8e80941Smrg
28b8e80941Smrg#include "etnaviv_screen.h"
29b8e80941Smrg
30b8e80941Smrg#include "hw/common.xml.h"
31b8e80941Smrg
32b8e80941Smrg#include "etnaviv_compiler.h"
33b8e80941Smrg#include "etnaviv_context.h"
34b8e80941Smrg#include "etnaviv_debug.h"
35b8e80941Smrg#include "etnaviv_fence.h"
36b8e80941Smrg#include "etnaviv_format.h"
37b8e80941Smrg#include "etnaviv_query.h"
38b8e80941Smrg#include "etnaviv_resource.h"
39b8e80941Smrg#include "etnaviv_translate.h"
40b8e80941Smrg
41b8e80941Smrg#include "util/hash_table.h"
42b8e80941Smrg#include "util/os_time.h"
43b8e80941Smrg#include "util/u_math.h"
44b8e80941Smrg#include "util/u_memory.h"
45b8e80941Smrg#include "util/u_screen.h"
46b8e80941Smrg#include "util/u_string.h"
47b8e80941Smrg
48b8e80941Smrg#include "state_tracker/drm_driver.h"
49b8e80941Smrg
50b8e80941Smrg#include "drm-uapi/drm_fourcc.h"
51b8e80941Smrg
52b8e80941Smrg#define ETNA_DRM_VERSION(major, minor) ((major) << 16 | (minor))
53b8e80941Smrg#define ETNA_DRM_VERSION_FENCE_FD      ETNA_DRM_VERSION(1, 1)
54b8e80941Smrg#define ETNA_DRM_VERSION_PERFMON       ETNA_DRM_VERSION(1, 2)
55b8e80941Smrg
56b8e80941Smrgstatic const struct debug_named_value debug_options[] = {
57b8e80941Smrg   {"dbg_msgs",       ETNA_DBG_MSGS, "Print debug messages"},
58b8e80941Smrg   {"frame_msgs",     ETNA_DBG_FRAME_MSGS, "Print frame messages"},
59b8e80941Smrg   {"resource_msgs",  ETNA_DBG_RESOURCE_MSGS, "Print resource messages"},
60b8e80941Smrg   {"compiler_msgs",  ETNA_DBG_COMPILER_MSGS, "Print compiler messages"},
61b8e80941Smrg   {"linker_msgs",    ETNA_DBG_LINKER_MSGS, "Print linker messages"},
62b8e80941Smrg   {"dump_shaders",   ETNA_DBG_DUMP_SHADERS, "Dump shaders"},
63b8e80941Smrg   {"no_ts",          ETNA_DBG_NO_TS, "Disable TS"},
64b8e80941Smrg   {"no_autodisable", ETNA_DBG_NO_AUTODISABLE, "Disable autodisable"},
65b8e80941Smrg   {"no_supertile",   ETNA_DBG_NO_SUPERTILE, "Disable supertiles"},
66b8e80941Smrg   {"no_early_z",     ETNA_DBG_NO_EARLY_Z, "Disable early z"},
67b8e80941Smrg   {"cflush_all",     ETNA_DBG_CFLUSH_ALL, "Flush every cache before state update"},
68b8e80941Smrg   {"msaa2x",         ETNA_DBG_MSAA_2X, "Force 2x msaa"},
69b8e80941Smrg   {"msaa4x",         ETNA_DBG_MSAA_4X, "Force 4x msaa"},
70b8e80941Smrg   {"flush_all",      ETNA_DBG_FLUSH_ALL, "Flush after every rendered primitive"},
71b8e80941Smrg   {"zero",           ETNA_DBG_ZERO, "Zero all resources after allocation"},
72b8e80941Smrg   {"draw_stall",     ETNA_DBG_DRAW_STALL, "Stall FE/PE after each rendered primitive"},
73b8e80941Smrg   {"shaderdb",       ETNA_DBG_SHADERDB, "Enable shaderdb output"},
74b8e80941Smrg   {"no_singlebuffer",ETNA_DBG_NO_SINGLEBUF, "Disable single buffer feature"},
75b8e80941Smrg   DEBUG_NAMED_VALUE_END
76b8e80941Smrg};
77b8e80941Smrg
78b8e80941SmrgDEBUG_GET_ONCE_FLAGS_OPTION(etna_mesa_debug, "ETNA_MESA_DEBUG", debug_options, 0)
79b8e80941Smrgint etna_mesa_debug = 0;
80b8e80941Smrg
81b8e80941Smrgstatic void
82b8e80941Smrgetna_screen_destroy(struct pipe_screen *pscreen)
83b8e80941Smrg{
84b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
85b8e80941Smrg
86b8e80941Smrg   _mesa_set_destroy(screen->used_resources, NULL);
87b8e80941Smrg   mtx_destroy(&screen->lock);
88b8e80941Smrg
89b8e80941Smrg   if (screen->perfmon)
90b8e80941Smrg      etna_perfmon_del(screen->perfmon);
91b8e80941Smrg
92b8e80941Smrg   if (screen->pipe)
93b8e80941Smrg      etna_pipe_del(screen->pipe);
94b8e80941Smrg
95b8e80941Smrg   if (screen->gpu)
96b8e80941Smrg      etna_gpu_del(screen->gpu);
97b8e80941Smrg
98b8e80941Smrg   if (screen->ro)
99b8e80941Smrg      FREE(screen->ro);
100b8e80941Smrg
101b8e80941Smrg   if (screen->dev)
102b8e80941Smrg      etna_device_del(screen->dev);
103b8e80941Smrg
104b8e80941Smrg   FREE(screen);
105b8e80941Smrg}
106b8e80941Smrg
107b8e80941Smrgstatic const char *
108b8e80941Smrgetna_screen_get_name(struct pipe_screen *pscreen)
109b8e80941Smrg{
110b8e80941Smrg   struct etna_screen *priv = etna_screen(pscreen);
111b8e80941Smrg   static char buffer[128];
112b8e80941Smrg
113b8e80941Smrg   util_snprintf(buffer, sizeof(buffer), "Vivante GC%x rev %04x", priv->model,
114b8e80941Smrg                 priv->revision);
115b8e80941Smrg
116b8e80941Smrg   return buffer;
117b8e80941Smrg}
118b8e80941Smrg
119b8e80941Smrgstatic const char *
120b8e80941Smrgetna_screen_get_vendor(struct pipe_screen *pscreen)
121b8e80941Smrg{
122b8e80941Smrg   return "etnaviv";
123b8e80941Smrg}
124b8e80941Smrg
125b8e80941Smrgstatic const char *
126b8e80941Smrgetna_screen_get_device_vendor(struct pipe_screen *pscreen)
127b8e80941Smrg{
128b8e80941Smrg   return "Vivante";
129b8e80941Smrg}
130b8e80941Smrg
131b8e80941Smrgstatic int
132b8e80941Smrgetna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
133b8e80941Smrg{
134b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
135b8e80941Smrg
136b8e80941Smrg   switch (param) {
137b8e80941Smrg   /* Supported features (boolean caps). */
138b8e80941Smrg   case PIPE_CAP_ANISOTROPIC_FILTER:
139b8e80941Smrg   case PIPE_CAP_POINT_SPRITE:
140b8e80941Smrg   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
141b8e80941Smrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
142b8e80941Smrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
143b8e80941Smrg   case PIPE_CAP_SM3:
144b8e80941Smrg   case PIPE_CAP_TEXTURE_BARRIER:
145b8e80941Smrg   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
146b8e80941Smrg   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
147b8e80941Smrg   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
148b8e80941Smrg   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
149b8e80941Smrg   case PIPE_CAP_TGSI_TEXCOORD:
150b8e80941Smrg   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
151b8e80941Smrg   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
152b8e80941Smrg      return 1;
153b8e80941Smrg   case PIPE_CAP_NATIVE_FENCE_FD:
154b8e80941Smrg      return screen->drm_version >= ETNA_DRM_VERSION_FENCE_FD;
155b8e80941Smrg
156b8e80941Smrg   /* Memory */
157b8e80941Smrg   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
158b8e80941Smrg      return 256;
159b8e80941Smrg   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
160b8e80941Smrg      return 4; /* XXX could easily be supported */
161b8e80941Smrg   case PIPE_CAP_GLSL_FEATURE_LEVEL:
162b8e80941Smrg   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
163b8e80941Smrg      return 120;
164b8e80941Smrg
165b8e80941Smrg   case PIPE_CAP_NPOT_TEXTURES:
166b8e80941Smrg      return true; /* VIV_FEATURE(priv->dev, chipMinorFeatures1,
167b8e80941Smrg                      NON_POWER_OF_TWO); */
168b8e80941Smrg
169b8e80941Smrg   case PIPE_CAP_TEXTURE_SWIZZLE:
170b8e80941Smrg   case PIPE_CAP_PRIMITIVE_RESTART:
171b8e80941Smrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
172b8e80941Smrg
173b8e80941Smrg   case PIPE_CAP_ENDIANNESS:
174b8e80941Smrg      return PIPE_ENDIAN_LITTLE; /* on most Viv hw this is configurable (feature
175b8e80941Smrg                                    ENDIANNESS_CONFIG) */
176b8e80941Smrg
177b8e80941Smrg   /* Unsupported features. */
178b8e80941Smrg   case PIPE_CAP_SEAMLESS_CUBE_MAP:
179b8e80941Smrg   case PIPE_CAP_COMPUTE: /* XXX supported on gc2000 */
180b8e80941Smrg   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: /* only one colorbuffer supported, so mixing makes no sense */
181b8e80941Smrg   case PIPE_CAP_CONDITIONAL_RENDER: /* no occlusion queries */
182b8e80941Smrg   case PIPE_CAP_TGSI_INSTANCEID: /* no idea, really */
183b8e80941Smrg   case PIPE_CAP_START_INSTANCE: /* instancing not supported AFAIK */
184b8e80941Smrg   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* instancing not supported AFAIK */
185b8e80941Smrg   case PIPE_CAP_SHADER_STENCIL_EXPORT: /* Fragment shader cannot export stencil value */
186b8e80941Smrg   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: /* no dual-source supported */
187b8e80941Smrg   case PIPE_CAP_TEXTURE_MULTISAMPLE: /* no texture multisample */
188b8e80941Smrg   case PIPE_CAP_TEXTURE_MIRROR_CLAMP: /* only mirrored repeat */
189b8e80941Smrg   case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: /* only mirrored repeat */
190b8e80941Smrg   case PIPE_CAP_INDEP_BLEND_ENABLE:
191b8e80941Smrg   case PIPE_CAP_INDEP_BLEND_FUNC:
192b8e80941Smrg   case PIPE_CAP_DEPTH_CLIP_DISABLE:
193b8e80941Smrg   case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
194b8e80941Smrg   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
195b8e80941Smrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
196b8e80941Smrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
197b8e80941Smrg   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: /* Don't skip strict max uniform limit check */
198b8e80941Smrg   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
199b8e80941Smrg   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
200b8e80941Smrg   case PIPE_CAP_USER_VERTEX_BUFFERS:
201b8e80941Smrg   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
202b8e80941Smrg   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
203b8e80941Smrg   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
204b8e80941Smrg   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: /* TODO: test me out with piglit */
205b8e80941Smrg   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
206b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
207b8e80941Smrg   case PIPE_CAP_TEXTURE_GATHER_SM5:
208b8e80941Smrg   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
209b8e80941Smrg   case PIPE_CAP_FAKE_SW_MSAA:
210b8e80941Smrg   case PIPE_CAP_TEXTURE_QUERY_LOD:
211b8e80941Smrg   case PIPE_CAP_SAMPLE_SHADING:
212b8e80941Smrg   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
213b8e80941Smrg   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
214b8e80941Smrg   case PIPE_CAP_DRAW_INDIRECT:
215b8e80941Smrg   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
216b8e80941Smrg   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
217b8e80941Smrg   case PIPE_CAP_SAMPLER_VIEW_TARGET:
218b8e80941Smrg   case PIPE_CAP_CLIP_HALFZ:
219b8e80941Smrg   case PIPE_CAP_VERTEXID_NOBASE:
220b8e80941Smrg   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
221b8e80941Smrg   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
222b8e80941Smrg   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
223b8e80941Smrg   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
224b8e80941Smrg   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
225b8e80941Smrg   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
226b8e80941Smrg   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
227b8e80941Smrg   case PIPE_CAP_DEPTH_BOUNDS_TEST:
228b8e80941Smrg   case PIPE_CAP_TGSI_TXQS:
229b8e80941Smrg   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
230b8e80941Smrg   case PIPE_CAP_SHAREABLE_SHADERS:
231b8e80941Smrg   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
232b8e80941Smrg   case PIPE_CAP_CLEAR_TEXTURE:
233b8e80941Smrg   case PIPE_CAP_DRAW_PARAMETERS:
234b8e80941Smrg   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
235b8e80941Smrg   case PIPE_CAP_MULTI_DRAW_INDIRECT:
236b8e80941Smrg   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
237b8e80941Smrg   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
238b8e80941Smrg   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
239b8e80941Smrg   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
240b8e80941Smrg   case PIPE_CAP_INVALIDATE_BUFFER:
241b8e80941Smrg   case PIPE_CAP_GENERATE_MIPMAP:
242b8e80941Smrg   case PIPE_CAP_STRING_MARKER:
243b8e80941Smrg   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
244b8e80941Smrg   case PIPE_CAP_QUERY_BUFFER_OBJECT:
245b8e80941Smrg   case PIPE_CAP_QUERY_MEMORY_INFO:
246b8e80941Smrg   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
247b8e80941Smrg   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
248b8e80941Smrg   case PIPE_CAP_CULL_DISTANCE:
249b8e80941Smrg   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
250b8e80941Smrg   case PIPE_CAP_TGSI_VOTE:
251b8e80941Smrg   case PIPE_CAP_MAX_WINDOW_RECTANGLES:
252b8e80941Smrg   case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
253b8e80941Smrg   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
254b8e80941Smrg   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
255b8e80941Smrg   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
256b8e80941Smrg   case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
257b8e80941Smrg   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
258b8e80941Smrg   case PIPE_CAP_TGSI_FS_FBFETCH:
259b8e80941Smrg   case PIPE_CAP_TGSI_MUL_ZERO_WINS:
260b8e80941Smrg   case PIPE_CAP_DOUBLES:
261b8e80941Smrg   case PIPE_CAP_INT64:
262b8e80941Smrg   case PIPE_CAP_INT64_DIVMOD:
263b8e80941Smrg   case PIPE_CAP_TGSI_TEX_TXF_LZ:
264b8e80941Smrg   case PIPE_CAP_TGSI_CLOCK:
265b8e80941Smrg   case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
266b8e80941Smrg   case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
267b8e80941Smrg   case PIPE_CAP_TGSI_BALLOT:
268b8e80941Smrg   case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
269b8e80941Smrg   case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
270b8e80941Smrg   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
271b8e80941Smrg   case PIPE_CAP_POST_DEPTH_COVERAGE:
272b8e80941Smrg   case PIPE_CAP_BINDLESS_TEXTURE:
273b8e80941Smrg   case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
274b8e80941Smrg   case PIPE_CAP_QUERY_SO_OVERFLOW:
275b8e80941Smrg   case PIPE_CAP_MEMOBJ:
276b8e80941Smrg   case PIPE_CAP_LOAD_CONSTBUF:
277b8e80941Smrg   case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:
278b8e80941Smrg   case PIPE_CAP_TILE_RASTER_ORDER:
279b8e80941Smrg   case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
280b8e80941Smrg   case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
281b8e80941Smrg   case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
282b8e80941Smrg   case PIPE_CAP_CONTEXT_PRIORITY_MASK:
283b8e80941Smrg   case PIPE_CAP_FENCE_SIGNAL:
284b8e80941Smrg   case PIPE_CAP_CONSTBUF0_FLAGS:
285b8e80941Smrg   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
286b8e80941Smrg   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
287b8e80941Smrg   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
288b8e80941Smrg   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
289b8e80941Smrg   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
290b8e80941Smrg   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
291b8e80941Smrg   case PIPE_CAP_PACKED_UNIFORMS:
292b8e80941Smrg   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
293b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
294b8e80941Smrg      return 0;
295b8e80941Smrg
296b8e80941Smrg   case PIPE_CAP_MAX_GS_INVOCATIONS:
297b8e80941Smrg      return 32;
298b8e80941Smrg
299b8e80941Smrg   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
300b8e80941Smrg      return 1 << 27;
301b8e80941Smrg
302b8e80941Smrg   /* Stream output. */
303b8e80941Smrg   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
304b8e80941Smrg   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
305b8e80941Smrg   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
306b8e80941Smrg   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
307b8e80941Smrg      return 0;
308b8e80941Smrg
309b8e80941Smrg   /* Geometry shader output, unsupported. */
310b8e80941Smrg   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
311b8e80941Smrg   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
312b8e80941Smrg   case PIPE_CAP_MAX_VERTEX_STREAMS:
313b8e80941Smrg      return 0;
314b8e80941Smrg
315b8e80941Smrg   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
316b8e80941Smrg      return 128;
317b8e80941Smrg   case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
318b8e80941Smrg      return 255;
319b8e80941Smrg
320b8e80941Smrg   /* Texturing. */
321b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
322b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
323b8e80941Smrg   {
324b8e80941Smrg      int log2_max_tex_size = util_last_bit(screen->specs.max_texture_size);
325b8e80941Smrg      assert(log2_max_tex_size > 0);
326b8e80941Smrg      return log2_max_tex_size;
327b8e80941Smrg   }
328b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: /* 3D textures not supported - fake it */
329b8e80941Smrg      return 5;
330b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
331b8e80941Smrg      return 0;
332b8e80941Smrg   case PIPE_CAP_CUBE_MAP_ARRAY:
333b8e80941Smrg      return 0;
334b8e80941Smrg   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
335b8e80941Smrg   case PIPE_CAP_MIN_TEXEL_OFFSET:
336b8e80941Smrg      return -8;
337b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
338b8e80941Smrg   case PIPE_CAP_MAX_TEXEL_OFFSET:
339b8e80941Smrg      return 7;
340b8e80941Smrg   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
341b8e80941Smrg      return 0;
342b8e80941Smrg   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
343b8e80941Smrg      return 65536;
344b8e80941Smrg
345b8e80941Smrg   /* Render targets. */
346b8e80941Smrg   case PIPE_CAP_MAX_RENDER_TARGETS:
347b8e80941Smrg      return 1;
348b8e80941Smrg
349b8e80941Smrg   /* Viewports and scissors. */
350b8e80941Smrg   case PIPE_CAP_MAX_VIEWPORTS:
351b8e80941Smrg      return 1;
352b8e80941Smrg
353b8e80941Smrg   /* Timer queries. */
354b8e80941Smrg   case PIPE_CAP_QUERY_TIME_ELAPSED:
355b8e80941Smrg      return 0;
356b8e80941Smrg   case PIPE_CAP_OCCLUSION_QUERY:
357b8e80941Smrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
358b8e80941Smrg   case PIPE_CAP_QUERY_TIMESTAMP:
359b8e80941Smrg      return 1;
360b8e80941Smrg   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
361b8e80941Smrg      return 0;
362b8e80941Smrg
363b8e80941Smrg   /* Preferences */
364b8e80941Smrg   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
365b8e80941Smrg      return 0;
366b8e80941Smrg
367b8e80941Smrg   case PIPE_CAP_MAX_VARYINGS:
368b8e80941Smrg      return screen->specs.max_varyings;
369b8e80941Smrg
370b8e80941Smrg   case PIPE_CAP_PCI_GROUP:
371b8e80941Smrg   case PIPE_CAP_PCI_BUS:
372b8e80941Smrg   case PIPE_CAP_PCI_DEVICE:
373b8e80941Smrg   case PIPE_CAP_PCI_FUNCTION:
374b8e80941Smrg      return 0;
375b8e80941Smrg   case PIPE_CAP_VENDOR_ID:
376b8e80941Smrg   case PIPE_CAP_DEVICE_ID:
377b8e80941Smrg      return 0xFFFFFFFF;
378b8e80941Smrg   case PIPE_CAP_ACCELERATED:
379b8e80941Smrg      return 1;
380b8e80941Smrg   case PIPE_CAP_VIDEO_MEMORY:
381b8e80941Smrg      return 0;
382b8e80941Smrg   case PIPE_CAP_UMA:
383b8e80941Smrg      return 1;
384b8e80941Smrg   default:
385b8e80941Smrg      return u_pipe_screen_get_param_defaults(pscreen, param);
386b8e80941Smrg   }
387b8e80941Smrg}
388b8e80941Smrg
389b8e80941Smrgstatic float
390b8e80941Smrgetna_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
391b8e80941Smrg{
392b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
393b8e80941Smrg
394b8e80941Smrg   switch (param) {
395b8e80941Smrg   case PIPE_CAPF_MAX_LINE_WIDTH:
396b8e80941Smrg   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
397b8e80941Smrg   case PIPE_CAPF_MAX_POINT_WIDTH:
398b8e80941Smrg   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
399b8e80941Smrg      return 8192.0f;
400b8e80941Smrg   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
401b8e80941Smrg      return 16.0f;
402b8e80941Smrg   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
403b8e80941Smrg      return util_last_bit(screen->specs.max_texture_size);
404b8e80941Smrg   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
405b8e80941Smrg   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
406b8e80941Smrg   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
407b8e80941Smrg      return 0.0f;
408b8e80941Smrg   }
409b8e80941Smrg
410b8e80941Smrg   debug_printf("unknown paramf %d", param);
411b8e80941Smrg   return 0;
412b8e80941Smrg}
413b8e80941Smrg
414b8e80941Smrgstatic int
415b8e80941Smrgetna_screen_get_shader_param(struct pipe_screen *pscreen,
416b8e80941Smrg                             enum pipe_shader_type shader,
417b8e80941Smrg                             enum pipe_shader_cap param)
418b8e80941Smrg{
419b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
420b8e80941Smrg
421b8e80941Smrg   switch (shader) {
422b8e80941Smrg   case PIPE_SHADER_FRAGMENT:
423b8e80941Smrg   case PIPE_SHADER_VERTEX:
424b8e80941Smrg      break;
425b8e80941Smrg   case PIPE_SHADER_COMPUTE:
426b8e80941Smrg   case PIPE_SHADER_GEOMETRY:
427b8e80941Smrg   case PIPE_SHADER_TESS_CTRL:
428b8e80941Smrg   case PIPE_SHADER_TESS_EVAL:
429b8e80941Smrg      return 0;
430b8e80941Smrg   default:
431b8e80941Smrg      DBG("unknown shader type %d", shader);
432b8e80941Smrg      return 0;
433b8e80941Smrg   }
434b8e80941Smrg
435b8e80941Smrg   switch (param) {
436b8e80941Smrg   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
437b8e80941Smrg   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
438b8e80941Smrg   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
439b8e80941Smrg   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
440b8e80941Smrg      return ETNA_MAX_TOKENS;
441b8e80941Smrg   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
442b8e80941Smrg      return ETNA_MAX_DEPTH; /* XXX */
443b8e80941Smrg   case PIPE_SHADER_CAP_MAX_INPUTS:
444b8e80941Smrg      /* Maximum number of inputs for the vertex shader is the number
445b8e80941Smrg       * of vertex elements - each element defines one vertex shader
446b8e80941Smrg       * input register.  For the fragment shader, this is the number
447b8e80941Smrg       * of varyings. */
448b8e80941Smrg      return shader == PIPE_SHADER_FRAGMENT ? screen->specs.max_varyings
449b8e80941Smrg                                            : screen->specs.vertex_max_elements;
450b8e80941Smrg   case PIPE_SHADER_CAP_MAX_OUTPUTS:
451b8e80941Smrg      return 16; /* see VIVS_VS_OUTPUT */
452b8e80941Smrg   case PIPE_SHADER_CAP_MAX_TEMPS:
453b8e80941Smrg      return 64; /* Max native temporaries. */
454b8e80941Smrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
455b8e80941Smrg      return 1;
456b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
457b8e80941Smrg      return 1;
458b8e80941Smrg   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
459b8e80941Smrg   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
460b8e80941Smrg   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
461b8e80941Smrg   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
462b8e80941Smrg      return 1;
463b8e80941Smrg   case PIPE_SHADER_CAP_SUBROUTINES:
464b8e80941Smrg      return 0;
465b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
466b8e80941Smrg      return VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
467b8e80941Smrg   case PIPE_SHADER_CAP_INTEGERS:
468b8e80941Smrg   case PIPE_SHADER_CAP_INT64_ATOMICS:
469b8e80941Smrg   case PIPE_SHADER_CAP_FP16:
470b8e80941Smrg      return 0;
471b8e80941Smrg   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
472b8e80941Smrg   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
473b8e80941Smrg      return shader == PIPE_SHADER_FRAGMENT
474b8e80941Smrg                ? screen->specs.fragment_sampler_count
475b8e80941Smrg                : screen->specs.vertex_sampler_count;
476b8e80941Smrg   case PIPE_SHADER_CAP_PREFERRED_IR:
477b8e80941Smrg      return PIPE_SHADER_IR_TGSI;
478b8e80941Smrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
479b8e80941Smrg      return 4096;
480b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
481b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
482b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
483b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
484b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
485b8e80941Smrg      return false;
486b8e80941Smrg   case PIPE_SHADER_CAP_SUPPORTED_IRS:
487b8e80941Smrg      return 0;
488b8e80941Smrg   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
489b8e80941Smrg      return 32;
490b8e80941Smrg   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
491b8e80941Smrg   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
492b8e80941Smrg   case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
493b8e80941Smrg   case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
494b8e80941Smrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
495b8e80941Smrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
496b8e80941Smrg   case PIPE_SHADER_CAP_SCALAR_ISA:
497b8e80941Smrg      return 0;
498b8e80941Smrg   }
499b8e80941Smrg
500b8e80941Smrg   debug_printf("unknown shader param %d", param);
501b8e80941Smrg   return 0;
502b8e80941Smrg}
503b8e80941Smrg
504b8e80941Smrgstatic uint64_t
505b8e80941Smrgetna_screen_get_timestamp(struct pipe_screen *pscreen)
506b8e80941Smrg{
507b8e80941Smrg   return os_time_get_nano();
508b8e80941Smrg}
509b8e80941Smrg
510b8e80941Smrgstatic bool
511b8e80941Smrggpu_supports_texure_format(struct etna_screen *screen, uint32_t fmt,
512b8e80941Smrg                           enum pipe_format format)
513b8e80941Smrg{
514b8e80941Smrg   bool supported = true;
515b8e80941Smrg
516b8e80941Smrg   if (fmt == TEXTURE_FORMAT_ETC1)
517b8e80941Smrg      supported = VIV_FEATURE(screen, chipFeatures, ETC1_TEXTURE_COMPRESSION);
518b8e80941Smrg
519b8e80941Smrg   if (fmt >= TEXTURE_FORMAT_DXT1 && fmt <= TEXTURE_FORMAT_DXT4_DXT5)
520b8e80941Smrg      supported = VIV_FEATURE(screen, chipFeatures, DXT_TEXTURE_COMPRESSION);
521b8e80941Smrg
522b8e80941Smrg   if (util_format_is_srgb(format))
523b8e80941Smrg      supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
524b8e80941Smrg
525b8e80941Smrg   if (fmt & EXT_FORMAT)
526b8e80941Smrg      supported = VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
527b8e80941Smrg
528b8e80941Smrg   if (fmt & ASTC_FORMAT) {
529b8e80941Smrg      supported = screen->specs.tex_astc;
530b8e80941Smrg   }
531b8e80941Smrg
532b8e80941Smrg   if (!supported)
533b8e80941Smrg      return false;
534b8e80941Smrg
535b8e80941Smrg   if (texture_format_needs_swiz(format))
536b8e80941Smrg      return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
537b8e80941Smrg
538b8e80941Smrg   return true;
539b8e80941Smrg}
540b8e80941Smrg
541b8e80941Smrgstatic boolean
542b8e80941Smrgetna_screen_is_format_supported(struct pipe_screen *pscreen,
543b8e80941Smrg                                enum pipe_format format,
544b8e80941Smrg                                enum pipe_texture_target target,
545b8e80941Smrg                                unsigned sample_count,
546b8e80941Smrg                                unsigned storage_sample_count,
547b8e80941Smrg                                unsigned usage)
548b8e80941Smrg{
549b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
550b8e80941Smrg   unsigned allowed = 0;
551b8e80941Smrg
552b8e80941Smrg   if (target != PIPE_BUFFER &&
553b8e80941Smrg       target != PIPE_TEXTURE_1D &&
554b8e80941Smrg       target != PIPE_TEXTURE_2D &&
555b8e80941Smrg       target != PIPE_TEXTURE_3D &&
556b8e80941Smrg       target != PIPE_TEXTURE_CUBE &&
557b8e80941Smrg       target != PIPE_TEXTURE_RECT)
558b8e80941Smrg      return FALSE;
559b8e80941Smrg
560b8e80941Smrg   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
561b8e80941Smrg      return false;
562b8e80941Smrg
563b8e80941Smrg   if (usage & PIPE_BIND_RENDER_TARGET) {
564b8e80941Smrg      /* if render target, must be RS-supported format */
565b8e80941Smrg      if (translate_rs_format(format) != ETNA_NO_MATCH) {
566b8e80941Smrg         /* Validate MSAA; number of samples must be allowed, and render target
567b8e80941Smrg          * must have MSAA'able format. */
568b8e80941Smrg         if (sample_count > 1) {
569b8e80941Smrg            if (translate_samples_to_xyscale(sample_count, NULL, NULL, NULL) &&
570b8e80941Smrg                translate_msaa_format(format) != ETNA_NO_MATCH) {
571b8e80941Smrg               allowed |= PIPE_BIND_RENDER_TARGET;
572b8e80941Smrg            }
573b8e80941Smrg         } else {
574b8e80941Smrg            allowed |= PIPE_BIND_RENDER_TARGET;
575b8e80941Smrg         }
576b8e80941Smrg      }
577b8e80941Smrg   }
578b8e80941Smrg
579b8e80941Smrg   if (usage & PIPE_BIND_DEPTH_STENCIL) {
580b8e80941Smrg      if (translate_depth_format(format) != ETNA_NO_MATCH)
581b8e80941Smrg         allowed |= PIPE_BIND_DEPTH_STENCIL;
582b8e80941Smrg   }
583b8e80941Smrg
584b8e80941Smrg   if (usage & PIPE_BIND_SAMPLER_VIEW) {
585b8e80941Smrg      uint32_t fmt = translate_texture_format(format);
586b8e80941Smrg
587b8e80941Smrg      if (!gpu_supports_texure_format(screen, fmt, format))
588b8e80941Smrg         fmt = ETNA_NO_MATCH;
589b8e80941Smrg
590b8e80941Smrg      if (sample_count < 2 && fmt != ETNA_NO_MATCH)
591b8e80941Smrg         allowed |= PIPE_BIND_SAMPLER_VIEW;
592b8e80941Smrg   }
593b8e80941Smrg
594b8e80941Smrg   if (usage & PIPE_BIND_VERTEX_BUFFER) {
595b8e80941Smrg      if (translate_vertex_format_type(format) != ETNA_NO_MATCH)
596b8e80941Smrg         allowed |= PIPE_BIND_VERTEX_BUFFER;
597b8e80941Smrg   }
598b8e80941Smrg
599b8e80941Smrg   if (usage & PIPE_BIND_INDEX_BUFFER) {
600b8e80941Smrg      /* must be supported index format */
601b8e80941Smrg      if (format == PIPE_FORMAT_I8_UINT || format == PIPE_FORMAT_I16_UINT ||
602b8e80941Smrg          (format == PIPE_FORMAT_I32_UINT &&
603b8e80941Smrg           VIV_FEATURE(screen, chipFeatures, 32_BIT_INDICES))) {
604b8e80941Smrg         allowed |= PIPE_BIND_INDEX_BUFFER;
605b8e80941Smrg      }
606b8e80941Smrg   }
607b8e80941Smrg
608b8e80941Smrg   /* Always allowed */
609b8e80941Smrg   allowed |=
610b8e80941Smrg      usage & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
611b8e80941Smrg
612b8e80941Smrg   if (usage != allowed) {
613b8e80941Smrg      DBG("not supported: format=%s, target=%d, sample_count=%d, "
614b8e80941Smrg          "usage=%x, allowed=%x",
615b8e80941Smrg          util_format_name(format), target, sample_count, usage, allowed);
616b8e80941Smrg   }
617b8e80941Smrg
618b8e80941Smrg   return usage == allowed;
619b8e80941Smrg}
620b8e80941Smrg
621b8e80941Smrgconst uint64_t supported_modifiers[] = {
622b8e80941Smrg   DRM_FORMAT_MOD_LINEAR,
623b8e80941Smrg   DRM_FORMAT_MOD_VIVANTE_TILED,
624b8e80941Smrg   DRM_FORMAT_MOD_VIVANTE_SUPER_TILED,
625b8e80941Smrg   DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED,
626b8e80941Smrg   DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED,
627b8e80941Smrg};
628b8e80941Smrg
629b8e80941Smrgstatic void
630b8e80941Smrgetna_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
631b8e80941Smrg                                   enum pipe_format format, int max,
632b8e80941Smrg                                   uint64_t *modifiers,
633b8e80941Smrg                                   unsigned int *external_only, int *count)
634b8e80941Smrg{
635b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
636b8e80941Smrg   int i, num_modifiers = 0;
637b8e80941Smrg
638b8e80941Smrg   if (max > ARRAY_SIZE(supported_modifiers))
639b8e80941Smrg      max = ARRAY_SIZE(supported_modifiers);
640b8e80941Smrg
641b8e80941Smrg   if (!max) {
642b8e80941Smrg      modifiers = NULL;
643b8e80941Smrg      max = ARRAY_SIZE(supported_modifiers);
644b8e80941Smrg   }
645b8e80941Smrg
646b8e80941Smrg   for (i = 0; num_modifiers < max; i++) {
647b8e80941Smrg      /* don't advertise split tiled formats on single pipe/buffer GPUs */
648b8e80941Smrg      if ((screen->specs.pixel_pipes == 1 || screen->specs.single_buffer) &&
649b8e80941Smrg          i >= 3)
650b8e80941Smrg         break;
651b8e80941Smrg
652b8e80941Smrg      if (modifiers)
653b8e80941Smrg         modifiers[num_modifiers] = supported_modifiers[i];
654b8e80941Smrg      if (external_only)
655b8e80941Smrg         external_only[num_modifiers] = util_format_is_yuv(format) ? 1 : 0;
656b8e80941Smrg      num_modifiers++;
657b8e80941Smrg   }
658b8e80941Smrg
659b8e80941Smrg   *count = num_modifiers;
660b8e80941Smrg}
661b8e80941Smrg
662b8e80941Smrgstatic boolean
663b8e80941Smrgetna_get_specs(struct etna_screen *screen)
664b8e80941Smrg{
665b8e80941Smrg   uint64_t val;
666b8e80941Smrg   uint32_t instruction_count;
667b8e80941Smrg
668b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_INSTRUCTION_COUNT, &val)) {
669b8e80941Smrg      DBG("could not get ETNA_GPU_INSTRUCTION_COUNT");
670b8e80941Smrg      goto fail;
671b8e80941Smrg   }
672b8e80941Smrg   instruction_count = val;
673b8e80941Smrg
674b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE,
675b8e80941Smrg                          &val)) {
676b8e80941Smrg      DBG("could not get ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE");
677b8e80941Smrg      goto fail;
678b8e80941Smrg   }
679b8e80941Smrg   screen->specs.vertex_output_buffer_size = val;
680b8e80941Smrg
681b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_VERTEX_CACHE_SIZE, &val)) {
682b8e80941Smrg      DBG("could not get ETNA_GPU_VERTEX_CACHE_SIZE");
683b8e80941Smrg      goto fail;
684b8e80941Smrg   }
685b8e80941Smrg   screen->specs.vertex_cache_size = val;
686b8e80941Smrg
687b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_SHADER_CORE_COUNT, &val)) {
688b8e80941Smrg      DBG("could not get ETNA_GPU_SHADER_CORE_COUNT");
689b8e80941Smrg      goto fail;
690b8e80941Smrg   }
691b8e80941Smrg   screen->specs.shader_core_count = val;
692b8e80941Smrg
693b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_STREAM_COUNT, &val)) {
694b8e80941Smrg      DBG("could not get ETNA_GPU_STREAM_COUNT");
695b8e80941Smrg      goto fail;
696b8e80941Smrg   }
697b8e80941Smrg   screen->specs.stream_count = val;
698b8e80941Smrg
699b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REGISTER_MAX, &val)) {
700b8e80941Smrg      DBG("could not get ETNA_GPU_REGISTER_MAX");
701b8e80941Smrg      goto fail;
702b8e80941Smrg   }
703b8e80941Smrg   screen->specs.max_registers = val;
704b8e80941Smrg
705b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_PIXEL_PIPES, &val)) {
706b8e80941Smrg      DBG("could not get ETNA_GPU_PIXEL_PIPES");
707b8e80941Smrg      goto fail;
708b8e80941Smrg   }
709b8e80941Smrg   screen->specs.pixel_pipes = val;
710b8e80941Smrg
711b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_NUM_CONSTANTS, &val)) {
712b8e80941Smrg      DBG("could not get %s", "ETNA_GPU_NUM_CONSTANTS");
713b8e80941Smrg      goto fail;
714b8e80941Smrg   }
715b8e80941Smrg   if (val == 0) {
716b8e80941Smrg      fprintf(stderr, "Warning: zero num constants (update kernel?)\n");
717b8e80941Smrg      val = 168;
718b8e80941Smrg   }
719b8e80941Smrg   screen->specs.num_constants = val;
720b8e80941Smrg
721b8e80941Smrg   /* Figure out gross GPU architecture. See rnndb/common.xml for a specific
722b8e80941Smrg    * description of the differences. */
723b8e80941Smrg   if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI5))
724b8e80941Smrg      screen->specs.halti = 5; /* New GC7000/GC8x00  */
725b8e80941Smrg   else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI4))
726b8e80941Smrg      screen->specs.halti = 4; /* Old GC7000/GC7400 */
727b8e80941Smrg   else if (VIV_FEATURE(screen, chipMinorFeatures5, HALTI3))
728b8e80941Smrg      screen->specs.halti = 3; /* None? */
729b8e80941Smrg   else if (VIV_FEATURE(screen, chipMinorFeatures4, HALTI2))
730b8e80941Smrg      screen->specs.halti = 2; /* GC2500/GC3000/GC5000/GC6400 */
731b8e80941Smrg   else if (VIV_FEATURE(screen, chipMinorFeatures2, HALTI1))
732b8e80941Smrg      screen->specs.halti = 1; /* GC900/GC4000/GC7000UL */
733b8e80941Smrg   else if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0))
734b8e80941Smrg      screen->specs.halti = 0; /* GC880/GC2000/GC7000TM */
735b8e80941Smrg   else
736b8e80941Smrg      screen->specs.halti = -1; /* GC7000nanolite / pre-GC2000 except GC880 */
737b8e80941Smrg   if (screen->specs.halti >= 0)
738b8e80941Smrg      DBG("etnaviv: GPU arch: HALTI%d", screen->specs.halti);
739b8e80941Smrg   else
740b8e80941Smrg      DBG("etnaviv: GPU arch: pre-HALTI");
741b8e80941Smrg
742b8e80941Smrg   screen->specs.can_supertile =
743b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, SUPER_TILED);
744b8e80941Smrg   screen->specs.bits_per_tile =
745b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 2 : 4;
746b8e80941Smrg   screen->specs.ts_clear_value =
747b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, 2BITPERTILE) ? 0x55555555
748b8e80941Smrg                                                           : 0x11111111;
749b8e80941Smrg
750b8e80941Smrg   /* vertex and fragment samplers live in one address space */
751b8e80941Smrg   screen->specs.vertex_sampler_offset = 8;
752b8e80941Smrg   screen->specs.fragment_sampler_count = 8;
753b8e80941Smrg   screen->specs.vertex_sampler_count = 4;
754b8e80941Smrg   screen->specs.vs_need_z_div =
755b8e80941Smrg      screen->model < 0x1000 && screen->model != 0x880;
756b8e80941Smrg   screen->specs.has_sin_cos_sqrt =
757b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, HAS_SQRT_TRIG);
758b8e80941Smrg   screen->specs.has_sign_floor_ceil =
759b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, HAS_SIGN_FLOOR_CEIL);
760b8e80941Smrg   screen->specs.has_shader_range_registers =
761b8e80941Smrg      screen->model >= 0x1000 || screen->model == 0x880;
762b8e80941Smrg   screen->specs.npot_tex_any_wrap =
763b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures1, NON_POWER_OF_TWO);
764b8e80941Smrg   screen->specs.has_new_transcendentals =
765b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures3, HAS_FAST_TRANSCENDENTALS);
766b8e80941Smrg   screen->specs.has_halti2_instructions =
767b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
768b8e80941Smrg
769b8e80941Smrg   if (screen->specs.halti >= 5) {
770b8e80941Smrg      /* GC7000 - this core must load shaders from memory. */
771b8e80941Smrg      screen->specs.vs_offset = 0;
772b8e80941Smrg      screen->specs.ps_offset = 0;
773b8e80941Smrg      screen->specs.max_instructions = 0; /* Do not program shaders manually */
774b8e80941Smrg      screen->specs.has_icache = true;
775b8e80941Smrg   } else if (VIV_FEATURE(screen, chipMinorFeatures3, INSTRUCTION_CACHE)) {
776b8e80941Smrg      /* GC3000 - this core is capable of loading shaders from
777b8e80941Smrg       * memory. It can also run shaders from registers, as a fallback, but
778b8e80941Smrg       * "max_instructions" does not have the correct value. It has place for
779b8e80941Smrg       * 2*256 instructions just like GC2000, but the offsets are slightly
780b8e80941Smrg       * different.
781b8e80941Smrg       */
782b8e80941Smrg      screen->specs.vs_offset = 0xC000;
783b8e80941Smrg      /* State 08000-0C000 mirrors 0C000-0E000, and the Vivante driver uses
784b8e80941Smrg       * this mirror for writing PS instructions, probably safest to do the
785b8e80941Smrg       * same.
786b8e80941Smrg       */
787b8e80941Smrg      screen->specs.ps_offset = 0x8000 + 0x1000;
788b8e80941Smrg      screen->specs.max_instructions = 256; /* maximum number instructions for non-icache use */
789b8e80941Smrg      screen->specs.has_icache = true;
790b8e80941Smrg   } else {
791b8e80941Smrg      if (instruction_count > 256) { /* unified instruction memory? */
792b8e80941Smrg         screen->specs.vs_offset = 0xC000;
793b8e80941Smrg         screen->specs.ps_offset = 0xD000; /* like vivante driver */
794b8e80941Smrg         screen->specs.max_instructions = 256;
795b8e80941Smrg      } else {
796b8e80941Smrg         screen->specs.vs_offset = 0x4000;
797b8e80941Smrg         screen->specs.ps_offset = 0x6000;
798b8e80941Smrg         screen->specs.max_instructions = instruction_count / 2;
799b8e80941Smrg      }
800b8e80941Smrg      screen->specs.has_icache = false;
801b8e80941Smrg   }
802b8e80941Smrg
803b8e80941Smrg   if (VIV_FEATURE(screen, chipMinorFeatures1, HALTI0)) {
804b8e80941Smrg      screen->specs.max_varyings = 12;
805b8e80941Smrg      screen->specs.vertex_max_elements = 16;
806b8e80941Smrg   } else {
807b8e80941Smrg      screen->specs.max_varyings = 8;
808b8e80941Smrg      /* Etna_viv documentation seems confused over the correct value
809b8e80941Smrg       * here so choose the lower to be safe: HALTI0 says 16 i.s.o.
810b8e80941Smrg       * 10, but VERTEX_ELEMENT_CONFIG register says 16 i.s.o. 12. */
811b8e80941Smrg      screen->specs.vertex_max_elements = 10;
812b8e80941Smrg   }
813b8e80941Smrg
814b8e80941Smrg   /* Etna_viv documentation does not indicate where varyings above 8 are
815b8e80941Smrg    * stored. Moreover, if we are passed more than 8 varyings, we will
816b8e80941Smrg    * walk off the end of some arrays. Limit the maximum number of varyings. */
817b8e80941Smrg   if (screen->specs.max_varyings > ETNA_NUM_VARYINGS)
818b8e80941Smrg      screen->specs.max_varyings = ETNA_NUM_VARYINGS;
819b8e80941Smrg
820b8e80941Smrg   /* from QueryShaderCaps in kernel driver */
821b8e80941Smrg   if (screen->model < chipModel_GC4000) {
822b8e80941Smrg      screen->specs.max_vs_uniforms = 168;
823b8e80941Smrg      screen->specs.max_ps_uniforms = 64;
824b8e80941Smrg   } else {
825b8e80941Smrg      screen->specs.max_vs_uniforms = 256;
826b8e80941Smrg      screen->specs.max_ps_uniforms = 256;
827b8e80941Smrg   }
828b8e80941Smrg
829b8e80941Smrg   if (screen->specs.halti >= 5) {
830b8e80941Smrg      screen->specs.has_unified_uniforms = true;
831b8e80941Smrg      screen->specs.vs_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS_MIRROR(0);
832b8e80941Smrg      screen->specs.ps_uniforms_offset = VIVS_SH_HALTI5_UNIFORMS(screen->specs.max_vs_uniforms*4);
833b8e80941Smrg   } else if (screen->specs.halti >= 1) {
834b8e80941Smrg      /* unified uniform memory on GC3000 - HALTI1 feature bit is just a guess
835b8e80941Smrg      */
836b8e80941Smrg      screen->specs.has_unified_uniforms = true;
837b8e80941Smrg      screen->specs.vs_uniforms_offset = VIVS_SH_UNIFORMS(0);
838b8e80941Smrg      /* hardcode PS uniforms to start after end of VS uniforms -
839b8e80941Smrg       * for more flexibility this offset could be variable based on the
840b8e80941Smrg       * shader.
841b8e80941Smrg       */
842b8e80941Smrg      screen->specs.ps_uniforms_offset = VIVS_SH_UNIFORMS(screen->specs.max_vs_uniforms*4);
843b8e80941Smrg   } else {
844b8e80941Smrg      screen->specs.has_unified_uniforms = false;
845b8e80941Smrg      screen->specs.vs_uniforms_offset = VIVS_VS_UNIFORMS(0);
846b8e80941Smrg      screen->specs.ps_uniforms_offset = VIVS_PS_UNIFORMS(0);
847b8e80941Smrg   }
848b8e80941Smrg
849b8e80941Smrg   screen->specs.max_texture_size =
850b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, TEXTURE_8K) ? 8192 : 2048;
851b8e80941Smrg   screen->specs.max_rendertarget_size =
852b8e80941Smrg      VIV_FEATURE(screen, chipMinorFeatures0, RENDERTARGET_8K) ? 8192 : 2048;
853b8e80941Smrg
854b8e80941Smrg   screen->specs.single_buffer = VIV_FEATURE(screen, chipMinorFeatures4, SINGLE_BUFFER);
855b8e80941Smrg   if (screen->specs.single_buffer)
856b8e80941Smrg      DBG("etnaviv: Single buffer mode enabled with %d pixel pipes", screen->specs.pixel_pipes);
857b8e80941Smrg
858b8e80941Smrg   screen->specs.tex_astc = VIV_FEATURE(screen, chipMinorFeatures4, TEXTURE_ASTC);
859b8e80941Smrg
860b8e80941Smrg   screen->specs.use_blt = VIV_FEATURE(screen, chipMinorFeatures5, BLT_ENGINE);
861b8e80941Smrg
862b8e80941Smrg   return true;
863b8e80941Smrg
864b8e80941Smrgfail:
865b8e80941Smrg   return false;
866b8e80941Smrg}
867b8e80941Smrg
868b8e80941Smrgstruct etna_bo *
869b8e80941Smrgetna_screen_bo_from_handle(struct pipe_screen *pscreen,
870b8e80941Smrg                           struct winsys_handle *whandle, unsigned *out_stride)
871b8e80941Smrg{
872b8e80941Smrg   struct etna_screen *screen = etna_screen(pscreen);
873b8e80941Smrg   struct etna_bo *bo;
874b8e80941Smrg
875b8e80941Smrg   if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
876b8e80941Smrg      bo = etna_bo_from_name(screen->dev, whandle->handle);
877b8e80941Smrg   } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
878b8e80941Smrg      bo = etna_bo_from_dmabuf(screen->dev, whandle->handle);
879b8e80941Smrg   } else {
880b8e80941Smrg      DBG("Attempt to import unsupported handle type %d", whandle->type);
881b8e80941Smrg      return NULL;
882b8e80941Smrg   }
883b8e80941Smrg
884b8e80941Smrg   if (!bo) {
885b8e80941Smrg      DBG("ref name 0x%08x failed", whandle->handle);
886b8e80941Smrg      return NULL;
887b8e80941Smrg   }
888b8e80941Smrg
889b8e80941Smrg   *out_stride = whandle->stride;
890b8e80941Smrg
891b8e80941Smrg   return bo;
892b8e80941Smrg}
893b8e80941Smrg
894b8e80941Smrgstruct pipe_screen *
895b8e80941Smrgetna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
896b8e80941Smrg                   struct renderonly *ro)
897b8e80941Smrg{
898b8e80941Smrg   struct etna_screen *screen = CALLOC_STRUCT(etna_screen);
899b8e80941Smrg   struct pipe_screen *pscreen;
900b8e80941Smrg   drmVersionPtr version;
901b8e80941Smrg   uint64_t val;
902b8e80941Smrg
903b8e80941Smrg   if (!screen)
904b8e80941Smrg      return NULL;
905b8e80941Smrg
906b8e80941Smrg   pscreen = &screen->base;
907b8e80941Smrg   screen->dev = dev;
908b8e80941Smrg   screen->gpu = gpu;
909b8e80941Smrg   screen->ro = renderonly_dup(ro);
910b8e80941Smrg   screen->refcnt = 1;
911b8e80941Smrg
912b8e80941Smrg   if (!screen->ro) {
913b8e80941Smrg      DBG("could not create renderonly object");
914b8e80941Smrg      goto fail;
915b8e80941Smrg   }
916b8e80941Smrg
917b8e80941Smrg   version = drmGetVersion(screen->ro->gpu_fd);
918b8e80941Smrg   screen->drm_version = ETNA_DRM_VERSION(version->version_major,
919b8e80941Smrg                                          version->version_minor);
920b8e80941Smrg   drmFreeVersion(version);
921b8e80941Smrg
922b8e80941Smrg   etna_mesa_debug = debug_get_option_etna_mesa_debug();
923b8e80941Smrg
924b8e80941Smrg   /* Disable autodisable for correct rendering with TS */
925b8e80941Smrg   etna_mesa_debug |= ETNA_DBG_NO_AUTODISABLE;
926b8e80941Smrg
927b8e80941Smrg   screen->pipe = etna_pipe_new(gpu, ETNA_PIPE_3D);
928b8e80941Smrg   if (!screen->pipe) {
929b8e80941Smrg      DBG("could not create 3d pipe");
930b8e80941Smrg      goto fail;
931b8e80941Smrg   }
932b8e80941Smrg
933b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_MODEL, &val)) {
934b8e80941Smrg      DBG("could not get ETNA_GPU_MODEL");
935b8e80941Smrg      goto fail;
936b8e80941Smrg   }
937b8e80941Smrg   screen->model = val;
938b8e80941Smrg
939b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_REVISION, &val)) {
940b8e80941Smrg      DBG("could not get ETNA_GPU_REVISION");
941b8e80941Smrg      goto fail;
942b8e80941Smrg   }
943b8e80941Smrg   screen->revision = val;
944b8e80941Smrg
945b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_0, &val)) {
946b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_0");
947b8e80941Smrg      goto fail;
948b8e80941Smrg   }
949b8e80941Smrg   screen->features[0] = val;
950b8e80941Smrg
951b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_1, &val)) {
952b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_1");
953b8e80941Smrg      goto fail;
954b8e80941Smrg   }
955b8e80941Smrg   screen->features[1] = val;
956b8e80941Smrg
957b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_2, &val)) {
958b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_2");
959b8e80941Smrg      goto fail;
960b8e80941Smrg   }
961b8e80941Smrg   screen->features[2] = val;
962b8e80941Smrg
963b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_3, &val)) {
964b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_3");
965b8e80941Smrg      goto fail;
966b8e80941Smrg   }
967b8e80941Smrg   screen->features[3] = val;
968b8e80941Smrg
969b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_4, &val)) {
970b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_4");
971b8e80941Smrg      goto fail;
972b8e80941Smrg   }
973b8e80941Smrg   screen->features[4] = val;
974b8e80941Smrg
975b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_5, &val)) {
976b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_5");
977b8e80941Smrg      goto fail;
978b8e80941Smrg   }
979b8e80941Smrg   screen->features[5] = val;
980b8e80941Smrg
981b8e80941Smrg   if (etna_gpu_get_param(screen->gpu, ETNA_GPU_FEATURES_6, &val)) {
982b8e80941Smrg      DBG("could not get ETNA_GPU_FEATURES_6");
983b8e80941Smrg      goto fail;
984b8e80941Smrg   }
985b8e80941Smrg   screen->features[6] = val;
986b8e80941Smrg
987b8e80941Smrg   if (!etna_get_specs(screen))
988b8e80941Smrg      goto fail;
989b8e80941Smrg
990b8e80941Smrg   /* apply debug options that disable individual features */
991b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_NO_EARLY_Z))
992b8e80941Smrg      screen->features[viv_chipFeatures] |= chipFeatures_NO_EARLY_Z;
993b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_NO_TS))
994b8e80941Smrg         screen->features[viv_chipFeatures] &= ~chipFeatures_FAST_CLEAR;
995b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_NO_AUTODISABLE))
996b8e80941Smrg      screen->features[viv_chipMinorFeatures1] &= ~chipMinorFeatures1_AUTO_DISABLE;
997b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_NO_SUPERTILE))
998b8e80941Smrg      screen->specs.can_supertile = 0;
999b8e80941Smrg   if (DBG_ENABLED(ETNA_DBG_NO_SINGLEBUF))
1000b8e80941Smrg      screen->specs.single_buffer = 0;
1001b8e80941Smrg
1002b8e80941Smrg   pscreen->destroy = etna_screen_destroy;
1003b8e80941Smrg   pscreen->get_param = etna_screen_get_param;
1004b8e80941Smrg   pscreen->get_paramf = etna_screen_get_paramf;
1005b8e80941Smrg   pscreen->get_shader_param = etna_screen_get_shader_param;
1006b8e80941Smrg
1007b8e80941Smrg   pscreen->get_name = etna_screen_get_name;
1008b8e80941Smrg   pscreen->get_vendor = etna_screen_get_vendor;
1009b8e80941Smrg   pscreen->get_device_vendor = etna_screen_get_device_vendor;
1010b8e80941Smrg
1011b8e80941Smrg   pscreen->get_timestamp = etna_screen_get_timestamp;
1012b8e80941Smrg   pscreen->context_create = etna_context_create;
1013b8e80941Smrg   pscreen->is_format_supported = etna_screen_is_format_supported;
1014b8e80941Smrg   pscreen->query_dmabuf_modifiers = etna_screen_query_dmabuf_modifiers;
1015b8e80941Smrg
1016b8e80941Smrg   etna_fence_screen_init(pscreen);
1017b8e80941Smrg   etna_query_screen_init(pscreen);
1018b8e80941Smrg   etna_resource_screen_init(pscreen);
1019b8e80941Smrg
1020b8e80941Smrg   util_dynarray_init(&screen->supported_pm_queries, NULL);
1021b8e80941Smrg   slab_create_parent(&screen->transfer_pool, sizeof(struct etna_transfer), 16);
1022b8e80941Smrg
1023b8e80941Smrg   if (screen->drm_version >= ETNA_DRM_VERSION_PERFMON)
1024b8e80941Smrg      etna_pm_query_setup(screen);
1025b8e80941Smrg
1026b8e80941Smrg   mtx_init(&screen->lock, mtx_recursive);
1027b8e80941Smrg   screen->used_resources = _mesa_set_create(NULL, _mesa_hash_pointer,
1028b8e80941Smrg                                             _mesa_key_pointer_equal);
1029b8e80941Smrg   if (!screen->used_resources)
1030b8e80941Smrg      goto fail2;
1031b8e80941Smrg
1032b8e80941Smrg   return pscreen;
1033b8e80941Smrg
1034b8e80941Smrgfail2:
1035b8e80941Smrg   mtx_destroy(&screen->lock);
1036b8e80941Smrgfail:
1037b8e80941Smrg   etna_screen_destroy(pscreen);
1038b8e80941Smrg   return NULL;
1039b8e80941Smrg}
1040