freedreno_screen.c revision af69d88d
1/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3/*
4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 *    Rob Clark <robclark@freedesktop.org>
27 */
28
29
30#include "pipe/p_defines.h"
31#include "pipe/p_screen.h"
32#include "pipe/p_state.h"
33
34#include "util/u_memory.h"
35#include "util/u_inlines.h"
36#include "util/u_format.h"
37#include "util/u_format_s3tc.h"
38#include "util/u_string.h"
39#include "util/u_debug.h"
40
41#include "os/os_time.h"
42
43#include <stdio.h>
44#include <errno.h>
45#include <stdlib.h>
46
47#include "freedreno_screen.h"
48#include "freedreno_resource.h"
49#include "freedreno_fence.h"
50#include "freedreno_query.h"
51#include "freedreno_util.h"
52
53#include "a2xx/fd2_screen.h"
54#include "a3xx/fd3_screen.h"
55
56/* XXX this should go away */
57#include "state_tracker/drm_driver.h"
58
59static const struct debug_named_value debug_options[] = {
60		{"msgs",      FD_DBG_MSGS,   "Print debug messages"},
61		{"disasm",    FD_DBG_DISASM, "Dump TGSI and adreno shader disassembly"},
62		{"dclear",    FD_DBG_DCLEAR, "Mark all state dirty after clear"},
63		{"flush",     FD_DBG_FLUSH,  "Force flush after every draw"},
64		{"dscis",     FD_DBG_DSCIS,  "Disable scissor optimization"},
65		{"direct",    FD_DBG_DIRECT, "Force inline (SS_DIRECT) state loads"},
66		{"dbypass",   FD_DBG_DBYPASS,"Disable GMEM bypass"},
67		{"fraghalf",  FD_DBG_FRAGHALF, "Use half-precision in fragment shader"},
68		{"nobin",     FD_DBG_NOBIN,  "Disable hw binning"},
69		{"noopt",     FD_DBG_NOOPT , "Disable optimization passes in compiler"},
70		{"optmsgs",   FD_DBG_OPTMSGS,"Enable optimizater debug messages"},
71		{"optdump",   FD_DBG_OPTDUMP,"Dump shader DAG to .dot files"},
72		{"glsl130",   FD_DBG_GLSL130,"Temporary flag to enable GLSL 130 on a3xx+"},
73		{"nocp",      FD_DBG_NOCP,   "Disable copy-propagation"},
74		DEBUG_NAMED_VALUE_END
75};
76
77DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", debug_options, 0)
78
79int fd_mesa_debug = 0;
80bool fd_binning_enabled = true;
81static bool glsl130 = false;
82
83static const char *
84fd_screen_get_name(struct pipe_screen *pscreen)
85{
86	static char buffer[128];
87	util_snprintf(buffer, sizeof(buffer), "FD%03d",
88			fd_screen(pscreen)->device_id);
89	return buffer;
90}
91
92static const char *
93fd_screen_get_vendor(struct pipe_screen *pscreen)
94{
95	return "freedreno";
96}
97
98static uint64_t
99fd_screen_get_timestamp(struct pipe_screen *pscreen)
100{
101	int64_t cpu_time = os_time_get() * 1000;
102	return cpu_time + fd_screen(pscreen)->cpu_gpu_time_delta;
103}
104
105static void
106fd_screen_fence_ref(struct pipe_screen *pscreen,
107		struct pipe_fence_handle **ptr,
108		struct pipe_fence_handle *pfence)
109{
110	fd_fence_ref(fd_fence(pfence), (struct fd_fence **)ptr);
111}
112
113static boolean
114fd_screen_fence_signalled(struct pipe_screen *screen,
115		struct pipe_fence_handle *pfence)
116{
117	return fd_fence_signalled(fd_fence(pfence));
118}
119
120static boolean
121fd_screen_fence_finish(struct pipe_screen *screen,
122		struct pipe_fence_handle *pfence,
123		uint64_t timeout)
124{
125	return fd_fence_wait(fd_fence(pfence));
126}
127
128static void
129fd_screen_destroy(struct pipe_screen *pscreen)
130{
131	struct fd_screen *screen = fd_screen(pscreen);
132
133	if (screen->pipe)
134		fd_pipe_del(screen->pipe);
135
136	if (screen->dev)
137		fd_device_del(screen->dev);
138
139	free(screen);
140}
141
142/*
143TODO either move caps to a2xx/a3xx specific code, or maybe have some
144tables for things that differ if the delta is not too much..
145 */
146static int
147fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
148{
149	struct fd_screen *screen = fd_screen(pscreen);
150
151	/* this is probably not totally correct.. but it's a start: */
152	switch (param) {
153	/* Supported features (boolean caps). */
154	case PIPE_CAP_NPOT_TEXTURES:
155	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
156	case PIPE_CAP_TWO_SIDED_STENCIL:
157	case PIPE_CAP_ANISOTROPIC_FILTER:
158	case PIPE_CAP_POINT_SPRITE:
159	case PIPE_CAP_TEXTURE_SHADOW_MAP:
160	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
161	case PIPE_CAP_TEXTURE_SWIZZLE:
162	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
163	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
164	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
165	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
166	case PIPE_CAP_SEAMLESS_CUBE_MAP:
167	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
168	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
169	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
170	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
171	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
172	case PIPE_CAP_USER_CONSTANT_BUFFERS:
173	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
174		return 1;
175
176	case PIPE_CAP_SHADER_STENCIL_EXPORT:
177	case PIPE_CAP_TGSI_TEXCOORD:
178	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
179	case PIPE_CAP_CONDITIONAL_RENDER:
180	case PIPE_CAP_TEXTURE_MULTISAMPLE:
181	case PIPE_CAP_TEXTURE_BARRIER:
182	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
183	case PIPE_CAP_CUBE_MAP_ARRAY:
184	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
185	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
186	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
187	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
188	case PIPE_CAP_TGSI_INSTANCEID:
189	case PIPE_CAP_START_INSTANCE:
190	case PIPE_CAP_COMPUTE:
191		return 0;
192
193	case PIPE_CAP_SM3:
194	case PIPE_CAP_PRIMITIVE_RESTART:
195		return (screen->gpu_id >= 300) ? 1 : 0;
196
197	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
198		return 256;
199
200	case PIPE_CAP_GLSL_FEATURE_LEVEL:
201		return ((screen->gpu_id >= 300) && glsl130) ? 130 : 120;
202
203	/* Unsupported features. */
204	case PIPE_CAP_INDEP_BLEND_ENABLE:
205	case PIPE_CAP_INDEP_BLEND_FUNC:
206	case PIPE_CAP_DEPTH_CLIP_DISABLE:
207	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
208	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
209	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
210	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
211	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
212	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
213	case PIPE_CAP_USER_VERTEX_BUFFERS:
214	case PIPE_CAP_USER_INDEX_BUFFERS:
215	case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
216	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
217	case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
218	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
219	case PIPE_CAP_TEXTURE_GATHER_SM5:
220	case PIPE_CAP_FAKE_SW_MSAA:
221	case PIPE_CAP_TEXTURE_QUERY_LOD:
222	case PIPE_CAP_SAMPLE_SHADING:
223	case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
224	case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
225	case PIPE_CAP_DRAW_INDIRECT:
226	case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
227	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
228		return 0;
229
230	case PIPE_CAP_MAX_VIEWPORTS:
231		return 1;
232
233	/* Stream output. */
234	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
235	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
236	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
237	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
238		return 0;
239
240	/* Geometry shader output, unsupported. */
241	case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
242	case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
243	case PIPE_CAP_MAX_VERTEX_STREAMS:
244		return 0;
245
246	/* Texturing. */
247	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
248	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
249		return MAX_MIP_LEVELS;
250	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
251		return 11;
252
253	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
254		return (screen->gpu_id >= 300) ? 256 : 0;
255
256	/* Render targets. */
257	case PIPE_CAP_MAX_RENDER_TARGETS:
258		return 1;
259
260	/* Queries. */
261	case PIPE_CAP_QUERY_TIME_ELAPSED:
262	case PIPE_CAP_QUERY_TIMESTAMP:
263		return 0;
264	case PIPE_CAP_OCCLUSION_QUERY:
265		return (screen->gpu_id >= 300) ? 1 : 0;
266
267	case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
268	case PIPE_CAP_MIN_TEXEL_OFFSET:
269		return -8;
270
271	case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
272	case PIPE_CAP_MAX_TEXEL_OFFSET:
273		return 7;
274
275	case PIPE_CAP_ENDIANNESS:
276		return PIPE_ENDIAN_LITTLE;
277
278	case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
279		return 64;
280
281	case PIPE_CAP_VENDOR_ID:
282		return 0x5143;
283	case PIPE_CAP_DEVICE_ID:
284		return 0xFFFFFFFF;
285	case PIPE_CAP_ACCELERATED:
286		return 1;
287	case PIPE_CAP_VIDEO_MEMORY:
288		DBG("FINISHME: The value returned is incorrect\n");
289		return 10;
290	case PIPE_CAP_UMA:
291		return 1;
292	}
293	debug_printf("unknown param %d\n", param);
294	return 0;
295}
296
297static float
298fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
299{
300	switch (param) {
301	case PIPE_CAPF_MAX_LINE_WIDTH:
302	case PIPE_CAPF_MAX_LINE_WIDTH_AA:
303	case PIPE_CAPF_MAX_POINT_WIDTH:
304	case PIPE_CAPF_MAX_POINT_WIDTH_AA:
305		return 8192.0f;
306	case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
307		return 16.0f;
308	case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
309		return 15.0f;
310	case PIPE_CAPF_GUARD_BAND_LEFT:
311	case PIPE_CAPF_GUARD_BAND_TOP:
312	case PIPE_CAPF_GUARD_BAND_RIGHT:
313	case PIPE_CAPF_GUARD_BAND_BOTTOM:
314		return 0.0f;
315	}
316	debug_printf("unknown paramf %d\n", param);
317	return 0;
318}
319
320static int
321fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
322		enum pipe_shader_cap param)
323{
324	struct fd_screen *screen = fd_screen(pscreen);
325
326	switch(shader)
327	{
328	case PIPE_SHADER_FRAGMENT:
329	case PIPE_SHADER_VERTEX:
330		break;
331	case PIPE_SHADER_COMPUTE:
332	case PIPE_SHADER_GEOMETRY:
333		/* maye we could emulate.. */
334		return 0;
335	default:
336		DBG("unknown shader type %d", shader);
337		return 0;
338	}
339
340	/* this is probably not totally correct.. but it's a start: */
341	switch (param) {
342	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
343	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
344	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
345	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
346		return 16384;
347	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
348		return 8; /* XXX */
349	case PIPE_SHADER_CAP_MAX_INPUTS:
350		return 16;
351	case PIPE_SHADER_CAP_MAX_TEMPS:
352		return 64; /* Max native temporaries. */
353	case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
354		/* NOTE: seems to be limit for a3xx is actually 512 but
355		 * split between VS and FS.  Use lower limit of 256 to
356		 * avoid getting into impossible situations:
357		 */
358		return ((screen->gpu_id >= 300) ? 256 : 64) * sizeof(float[4]);
359	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
360		return 1;
361	case PIPE_SHADER_CAP_MAX_PREDS:
362		return 0; /* nothing uses this */
363	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
364		return 1;
365	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
366	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
367	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
368	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
369		return 1;
370	case PIPE_SHADER_CAP_SUBROUTINES:
371	case PIPE_SHADER_CAP_DOUBLES:
372		return 0;
373	case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
374		return 1;
375	case PIPE_SHADER_CAP_INTEGERS:
376		/* we should be able to support this on a3xx, but not
377		 * implemented yet:
378		 */
379		return ((screen->gpu_id >= 300) && glsl130) ? 1 : 0;
380	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
381	case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
382		return 16;
383	case PIPE_SHADER_CAP_PREFERRED_IR:
384		return PIPE_SHADER_IR_TGSI;
385	}
386	debug_printf("unknown shader param %d\n", param);
387	return 0;
388}
389
390boolean
391fd_screen_bo_get_handle(struct pipe_screen *pscreen,
392		struct fd_bo *bo,
393		unsigned stride,
394		struct winsys_handle *whandle)
395{
396	whandle->stride = stride;
397
398	if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
399		return fd_bo_get_name(bo, &whandle->handle) == 0;
400	} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
401		whandle->handle = fd_bo_handle(bo);
402		return TRUE;
403	} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
404		whandle->handle = fd_bo_dmabuf(bo);
405		return TRUE;
406	} else {
407		return FALSE;
408	}
409}
410
411struct fd_bo *
412fd_screen_bo_from_handle(struct pipe_screen *pscreen,
413		struct winsys_handle *whandle,
414		unsigned *out_stride)
415{
416	struct fd_screen *screen = fd_screen(pscreen);
417	struct fd_bo *bo;
418
419	if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
420		bo = fd_bo_from_name(screen->dev, whandle->handle);
421	} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
422		bo = fd_bo_from_handle(screen->dev, whandle->handle, 0);
423	} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
424		bo = fd_bo_from_dmabuf(screen->dev, whandle->handle);
425	} else {
426		DBG("Attempt to import unsupported handle type %d", whandle->type);
427		return NULL;
428	}
429
430	if (!bo) {
431		DBG("ref name 0x%08x failed", whandle->handle);
432		return NULL;
433	}
434
435	*out_stride = whandle->stride;
436
437	return bo;
438}
439
440struct pipe_screen *
441fd_screen_create(struct fd_device *dev)
442{
443	struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
444	struct pipe_screen *pscreen;
445	uint64_t val;
446
447	fd_mesa_debug = debug_get_option_fd_mesa_debug();
448
449	if (fd_mesa_debug & FD_DBG_NOBIN)
450		fd_binning_enabled = false;
451
452	glsl130 = !!(fd_mesa_debug & FD_DBG_GLSL130);
453
454	if (!screen)
455		return NULL;
456
457	pscreen = &screen->base;
458
459	screen->dev = dev;
460
461	// maybe this should be in context?
462	screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
463	if (!screen->pipe) {
464		DBG("could not create 3d pipe");
465		goto fail;
466	}
467
468	if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
469		DBG("could not get GMEM size");
470		goto fail;
471	}
472	screen->gmemsize_bytes = val;
473
474	if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) {
475		DBG("could not get device-id");
476		goto fail;
477	}
478	screen->device_id = val;
479
480	if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
481		DBG("could not get gpu-id");
482		goto fail;
483	}
484	screen->gpu_id = val;
485
486	if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) {
487		DBG("could not get chip-id");
488		/* older kernels may not have this property: */
489		unsigned core  = screen->gpu_id / 100;
490		unsigned major = (screen->gpu_id % 100) / 10;
491		unsigned minor = screen->gpu_id % 10;
492		unsigned patch = 0;  /* assume the worst */
493		val = (patch & 0xff) | ((minor & 0xff) << 8) |
494			((major & 0xff) << 16) | ((core & 0xff) << 24);
495	}
496	screen->chip_id = val;
497
498	DBG("Pipe Info:");
499	DBG(" GPU-id:          %d", screen->gpu_id);
500	DBG(" Chip-id:         0x%08x", screen->chip_id);
501	DBG(" GMEM size:       0x%08x", screen->gmemsize_bytes);
502
503	/* explicitly checking for GPU revisions that are known to work.  This
504	 * may be overly conservative for a3xx, where spoofing the gpu_id with
505	 * the blob driver seems to generate identical cmdstream dumps.  But
506	 * on a2xx, there seem to be small differences between the GPU revs
507	 * so it is probably better to actually test first on real hardware
508	 * before enabling:
509	 *
510	 * If you have a different adreno version, feel free to add it to one
511	 * of the two cases below and see what happens.  And if it works, please
512	 * send a patch ;-)
513	 */
514	switch (screen->gpu_id) {
515	case 220:
516		fd2_screen_init(pscreen);
517		break;
518	case 320:
519	case 330:
520		fd3_screen_init(pscreen);
521		break;
522	default:
523		debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
524		goto fail;
525	}
526
527	pscreen->destroy = fd_screen_destroy;
528	pscreen->get_param = fd_screen_get_param;
529	pscreen->get_paramf = fd_screen_get_paramf;
530	pscreen->get_shader_param = fd_screen_get_shader_param;
531
532	fd_resource_screen_init(pscreen);
533	fd_query_screen_init(pscreen);
534
535	pscreen->get_name = fd_screen_get_name;
536	pscreen->get_vendor = fd_screen_get_vendor;
537
538	pscreen->get_timestamp = fd_screen_get_timestamp;
539
540	pscreen->fence_reference = fd_screen_fence_ref;
541	pscreen->fence_signalled = fd_screen_fence_signalled;
542	pscreen->fence_finish = fd_screen_fence_finish;
543
544	util_format_s3tc_init();
545
546	return pscreen;
547
548fail:
549	fd_screen_destroy(pscreen);
550	return NULL;
551}
552