Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
 
3
/*
4
 * Copyright (C) 2012 Rob Clark 
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 
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 
44
#include 
45
#include 
46
 
47
#include "freedreno_screen.h"
48
#include "freedreno_resource.h"
49
#include "freedreno_fence.h"
50
#include "freedreno_util.h"
51
 
52
#include "fd2_screen.h"
53
#include "fd3_screen.h"
54
 
55
/* XXX this should go away */
56
#include "state_tracker/drm_driver.h"
57
 
58
static const struct debug_named_value debug_options[] = {
59
		{"msgs",      FD_DBG_MSGS,   "Print debug messages"},
60
		{"disasm",    FD_DBG_DISASM, "Dump TGSI and adreno shader disassembly"},
61
		{"dclear",    FD_DBG_DCLEAR, "Mark all state dirty after clear"},
62
		{"dgmem",     FD_DBG_DGMEM,  "Mark all state dirty after GMEM tile pass"},
4401 Serge 63
		{"dscis",     FD_DBG_DSCIS,  "Disable scissor optimization"},
4358 Serge 64
		DEBUG_NAMED_VALUE_END
65
};
66
 
67
DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", debug_options, 0)
68
 
69
int fd_mesa_debug = 0;
70
 
71
static const char *
72
fd_screen_get_name(struct pipe_screen *pscreen)
73
{
74
	static char buffer[128];
75
	util_snprintf(buffer, sizeof(buffer), "FD%03d",
76
			fd_screen(pscreen)->device_id);
77
	return buffer;
78
}
79
 
80
static const char *
81
fd_screen_get_vendor(struct pipe_screen *pscreen)
82
{
83
	return "freedreno";
84
}
85
 
86
static uint64_t
87
fd_screen_get_timestamp(struct pipe_screen *pscreen)
88
{
89
	int64_t cpu_time = os_time_get() * 1000;
90
	return cpu_time + fd_screen(pscreen)->cpu_gpu_time_delta;
91
}
92
 
93
static void
94
fd_screen_fence_ref(struct pipe_screen *pscreen,
95
		struct pipe_fence_handle **ptr,
96
		struct pipe_fence_handle *pfence)
97
{
98
	fd_fence_ref(fd_fence(pfence), (struct fd_fence **)ptr);
99
}
100
 
101
static boolean
102
fd_screen_fence_signalled(struct pipe_screen *screen,
103
		struct pipe_fence_handle *pfence)
104
{
105
	return fd_fence_signalled(fd_fence(pfence));
106
}
107
 
108
static boolean
109
fd_screen_fence_finish(struct pipe_screen *screen,
110
		struct pipe_fence_handle *pfence,
111
		uint64_t timeout)
112
{
113
	return fd_fence_wait(fd_fence(pfence));
114
}
115
 
116
static void
117
fd_screen_destroy(struct pipe_screen *pscreen)
118
{
119
	struct fd_screen *screen = fd_screen(pscreen);
120
 
121
	if (screen->pipe)
122
		fd_pipe_del(screen->pipe);
123
 
124
	if (screen->dev)
125
		fd_device_del(screen->dev);
126
 
127
	free(screen);
128
}
129
 
130
/*
131
TODO either move caps to a2xx/a3xx specific code, or maybe have some
132
tables for things that differ if the delta is not too much..
133
 */
134
static int
135
fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
136
{
137
	/* this is probably not totally correct.. but it's a start: */
138
	switch (param) {
139
	/* Supported features (boolean caps). */
140
	case PIPE_CAP_NPOT_TEXTURES:
141
	case PIPE_CAP_TWO_SIDED_STENCIL:
142
	case PIPE_CAP_ANISOTROPIC_FILTER:
143
	case PIPE_CAP_POINT_SPRITE:
144
	case PIPE_CAP_TEXTURE_SHADOW_MAP:
145
	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
146
	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
147
	case PIPE_CAP_TEXTURE_SWIZZLE:
148
	case PIPE_CAP_SHADER_STENCIL_EXPORT:
149
	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
150
	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
151
	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
152
	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
153
	case PIPE_CAP_SM3:
154
	case PIPE_CAP_SEAMLESS_CUBE_MAP:
155
	case PIPE_CAP_PRIMITIVE_RESTART:
156
	case PIPE_CAP_CONDITIONAL_RENDER:
157
	case PIPE_CAP_TEXTURE_BARRIER:
158
	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
159
	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
160
	case PIPE_CAP_TGSI_INSTANCEID:
161
	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
162
	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
163
	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
164
	case PIPE_CAP_COMPUTE:
165
	case PIPE_CAP_START_INSTANCE:
166
	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
167
	case PIPE_CAP_TEXTURE_MULTISAMPLE:
168
	case PIPE_CAP_USER_CONSTANT_BUFFERS:
169
		return 1;
170
 
171
	case PIPE_CAP_TGSI_TEXCOORD:
172
	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
173
		return 0;
174
 
175
	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
176
		return 256;
177
 
178
	case PIPE_CAP_GLSL_FEATURE_LEVEL:
179
		return 120;
180
 
181
	/* Unsupported features. */
182
	case PIPE_CAP_INDEP_BLEND_ENABLE:
183
	case PIPE_CAP_INDEP_BLEND_FUNC:
184
	case PIPE_CAP_DEPTH_CLIP_DISABLE:
185
	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
186
	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
187
	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
188
	case PIPE_CAP_SCALED_RESOLVE:
189
	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
190
	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
191
	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
192
	case PIPE_CAP_USER_VERTEX_BUFFERS:
193
	case PIPE_CAP_USER_INDEX_BUFFERS:
194
	case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
195
	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
196
		return 0;
197
 
198
	/* Stream output. */
199
	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
200
	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
201
	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
202
	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
203
		return 0;
204
 
205
	/* Texturing. */
206
	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
207
	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
208
	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
209
		return 14;
210
	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
211
		return 9192;
212
	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
213
		return 20;
214
 
215
	/* Render targets. */
216
	case PIPE_CAP_MAX_RENDER_TARGETS:
217
		return 1;
218
 
219
	/* Timer queries. */
220
	case PIPE_CAP_QUERY_TIME_ELAPSED:
221
	case PIPE_CAP_OCCLUSION_QUERY:
222
	case PIPE_CAP_QUERY_TIMESTAMP:
223
		return 0;
224
 
225
	case PIPE_CAP_MIN_TEXEL_OFFSET:
226
		return -8;
227
 
228
	case PIPE_CAP_MAX_TEXEL_OFFSET:
229
		return 7;
230
 
231
	case PIPE_CAP_ENDIANNESS:
232
		return PIPE_ENDIAN_LITTLE;
233
 
234
	default:
235
		DBG("unknown param %d", param);
236
		return 0;
237
	}
238
}
239
 
240
static float
241
fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
242
{
243
	switch (param) {
244
	case PIPE_CAPF_MAX_LINE_WIDTH:
245
	case PIPE_CAPF_MAX_LINE_WIDTH_AA:
246
	case PIPE_CAPF_MAX_POINT_WIDTH:
247
	case PIPE_CAPF_MAX_POINT_WIDTH_AA:
248
		return 8192.0f;
249
	case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
250
		return 16.0f;
251
	case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
252
		return 16.0f;
253
	case PIPE_CAPF_GUARD_BAND_LEFT:
254
	case PIPE_CAPF_GUARD_BAND_TOP:
255
	case PIPE_CAPF_GUARD_BAND_RIGHT:
256
	case PIPE_CAPF_GUARD_BAND_BOTTOM:
257
		return 0.0f;
258
	default:
259
		DBG("unknown paramf %d", param);
260
		return 0;
261
	}
262
}
263
 
264
static int
265
fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
266
		enum pipe_shader_cap param)
267
{
268
	switch(shader)
269
	{
270
	case PIPE_SHADER_FRAGMENT:
271
	case PIPE_SHADER_VERTEX:
272
		break;
273
	case PIPE_SHADER_COMPUTE:
274
	case PIPE_SHADER_GEOMETRY:
275
		/* maye we could emulate.. */
276
		return 0;
277
	default:
278
		DBG("unknown shader type %d", shader);
279
		return 0;
280
	}
281
 
282
	/* this is probably not totally correct.. but it's a start: */
283
	switch (param) {
284
	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
285
	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
286
	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
287
	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
288
		return 16384;
289
	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
290
		return 8; /* XXX */
291
	case PIPE_SHADER_CAP_MAX_INPUTS:
292
		return 32;
293
	case PIPE_SHADER_CAP_MAX_TEMPS:
294
		return 256; /* Max native temporaries. */
295
	case PIPE_SHADER_CAP_MAX_ADDRS:
296
		/* XXX Isn't this equal to TEMPS? */
297
		return 1; /* Max native address registers */
298
	case PIPE_SHADER_CAP_MAX_CONSTS:
299
	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
300
		return 64;
301
	case PIPE_SHADER_CAP_MAX_PREDS:
302
		return 0; /* nothing uses this */
303
	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
304
		return 1;
305
	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
306
	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
307
	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
308
	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
309
		return 1;
310
	case PIPE_SHADER_CAP_SUBROUTINES:
311
		return 0;
312
	case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
313
	case PIPE_SHADER_CAP_INTEGERS:
314
		return 0;
315
	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
316
		return 16;
317
	case PIPE_SHADER_CAP_PREFERRED_IR:
318
		return PIPE_SHADER_IR_TGSI;
319
	default:
320
		DBG("unknown shader param %d", param);
321
		return 0;
322
	}
323
	return 0;
324
}
325
 
326
boolean
327
fd_screen_bo_get_handle(struct pipe_screen *pscreen,
328
		struct fd_bo *bo,
329
		unsigned stride,
330
		struct winsys_handle *whandle)
331
{
332
	whandle->stride = stride;
333
 
334
	if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
335
		return fd_bo_get_name(bo, &whandle->handle) == 0;
336
	} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
337
		whandle->handle = fd_bo_handle(bo);
338
		return TRUE;
339
	} else {
340
		return FALSE;
341
	}
342
}
343
 
344
struct fd_bo *
345
fd_screen_bo_from_handle(struct pipe_screen *pscreen,
346
		struct winsys_handle *whandle,
347
		unsigned *out_stride)
348
{
349
	struct fd_screen *screen = fd_screen(pscreen);
350
	struct fd_bo *bo;
351
 
352
	bo = fd_bo_from_name(screen->dev, whandle->handle);
353
	if (!bo) {
354
		DBG("ref name 0x%08x failed", whandle->handle);
355
		return NULL;
356
	}
357
 
358
	*out_stride = whandle->stride;
359
 
360
	return bo;
361
}
362
 
363
struct pipe_screen *
364
fd_screen_create(struct fd_device *dev)
365
{
366
	struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
367
	struct pipe_screen *pscreen;
368
	uint64_t val;
369
 
370
	fd_mesa_debug = debug_get_option_fd_mesa_debug();
371
 
372
	if (!screen)
373
		return NULL;
374
 
375
	pscreen = &screen->base;
376
 
377
	screen->dev = dev;
378
 
379
	// maybe this should be in context?
380
	screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
381
	if (!screen->pipe) {
382
		DBG("could not create 3d pipe");
383
		goto fail;
384
	}
385
 
386
	if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
387
		DBG("could not get GMEM size");
388
		goto fail;
389
	}
390
	screen->gmemsize_bytes = val;
391
 
392
	if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) {
393
		DBG("could not get device-id");
394
		goto fail;
395
	}
396
	screen->device_id = val;
397
 
398
	if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
399
		DBG("could not get gpu-id");
400
		goto fail;
401
	}
402
	screen->gpu_id = val;
403
 
404
	/* explicitly checking for GPU revisions that are known to work.  This
405
	 * may be overly conservative for a3xx, where spoofing the gpu_id with
406
	 * the blob driver seems to generate identical cmdstream dumps.  But
407
	 * on a2xx, there seem to be small differences between the GPU revs
408
	 * so it is probably better to actually test first on real hardware
409
	 * before enabling:
410
	 *
411
	 * If you have a different adreno version, feel free to add it to one
412
	 * of the two cases below and see what happens.  And if it works, please
413
	 * send a patch ;-)
414
	 */
415
	switch (screen->gpu_id) {
416
	case 220:
417
		fd2_screen_init(pscreen);
418
		break;
419
	case 320:
420
		fd3_screen_init(pscreen);
421
		break;
422
	default:
423
		debug_printf("unsupported GPU: a%03d\n", screen->gpu_id);
424
		goto fail;
425
	}
426
 
427
	pscreen->destroy = fd_screen_destroy;
428
	pscreen->get_param = fd_screen_get_param;
429
	pscreen->get_paramf = fd_screen_get_paramf;
430
	pscreen->get_shader_param = fd_screen_get_shader_param;
431
 
432
	fd_resource_screen_init(pscreen);
433
 
434
	pscreen->get_name = fd_screen_get_name;
435
	pscreen->get_vendor = fd_screen_get_vendor;
436
 
437
	pscreen->get_timestamp = fd_screen_get_timestamp;
438
 
439
	pscreen->fence_reference = fd_screen_fence_ref;
440
	pscreen->fence_signalled = fd_screen_fence_signalled;
441
	pscreen->fence_finish = fd_screen_fence_finish;
442
 
443
	util_format_s3tc_init();
444
 
445
	return pscreen;
446
 
447
fail:
448
	fd_screen_destroy(pscreen);
449
	return NULL;
450
}