r600_pipe.c revision 8d1a9a984f33d8e45f932a9f47cdd57da617a919
1/*
2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include "r600_pipe.h"
24#include "r600_public.h"
25
26#include <errno.h>
27#include "pipe/p_shader_tokens.h"
28#include "util/u_blitter.h"
29#include "util/u_format_s3tc.h"
30#include "util/u_simple_shaders.h"
31#include "util/u_upload_mgr.h"
32#include "vl/vl_decoder.h"
33#include "vl/vl_video_buffer.h"
34#include "os/os_time.h"
35
36/*
37 * pipe_context
38 */
39static struct r600_fence *r600_create_fence(struct r600_context *rctx)
40{
41	struct r600_screen *rscreen = rctx->screen;
42	struct r600_fence *fence = NULL;
43
44	pipe_mutex_lock(rscreen->fences.mutex);
45
46	if (!rscreen->fences.bo) {
47		/* Create the shared buffer object */
48		rscreen->fences.bo = (struct r600_resource*)
49			pipe_buffer_create(&rscreen->screen, PIPE_BIND_CUSTOM,
50					   PIPE_USAGE_STAGING, 4096);
51		if (!rscreen->fences.bo) {
52			R600_ERR("r600: failed to create bo for fence objects\n");
53			goto out;
54		}
55		rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->cs_buf,
56							   rctx->cs,
57							   PIPE_TRANSFER_READ_WRITE);
58	}
59
60	if (!LIST_IS_EMPTY(&rscreen->fences.pool)) {
61		struct r600_fence *entry;
62
63		/* Try to find a freed fence that has been signalled */
64		LIST_FOR_EACH_ENTRY(entry, &rscreen->fences.pool, head) {
65			if (rscreen->fences.data[entry->index] != 0) {
66				LIST_DELINIT(&entry->head);
67				fence = entry;
68				break;
69			}
70		}
71	}
72
73	if (!fence) {
74		/* Allocate a new fence */
75		struct r600_fence_block *block;
76		unsigned index;
77
78		if ((rscreen->fences.next_index + 1) >= 1024) {
79			R600_ERR("r600: too many concurrent fences\n");
80			goto out;
81		}
82
83		index = rscreen->fences.next_index++;
84
85		if (!(index % FENCE_BLOCK_SIZE)) {
86			/* Allocate a new block */
87			block = CALLOC_STRUCT(r600_fence_block);
88			if (block == NULL)
89				goto out;
90
91			LIST_ADD(&block->head, &rscreen->fences.blocks);
92		} else {
93			block = LIST_ENTRY(struct r600_fence_block, rscreen->fences.blocks.next, head);
94		}
95
96		fence = &block->fences[index % FENCE_BLOCK_SIZE];
97		fence->index = index;
98	}
99
100	pipe_reference_init(&fence->reference, 1);
101
102	rscreen->fences.data[fence->index] = 0;
103	r600_context_emit_fence(rctx, rscreen->fences.bo, fence->index, 1);
104
105	/* Create a dummy BO so that fence_finish without a timeout can sleep waiting for completion */
106	fence->sleep_bo = (struct r600_resource*)
107			pipe_buffer_create(&rctx->screen->screen, PIPE_BIND_CUSTOM,
108					   PIPE_USAGE_STAGING, 1);
109	/* Add the fence as a dummy relocation. */
110	r600_context_bo_reloc(rctx, fence->sleep_bo, RADEON_USAGE_READWRITE);
111
112out:
113	pipe_mutex_unlock(rscreen->fences.mutex);
114	return fence;
115}
116
117
118void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
119		unsigned flags)
120{
121	struct r600_context *rctx = (struct r600_context *)ctx;
122	struct r600_fence **rfence = (struct r600_fence**)fence;
123	struct pipe_query *render_cond = NULL;
124	unsigned render_cond_mode = 0;
125
126	if (rfence)
127		*rfence = r600_create_fence(rctx);
128
129	/* Disable render condition. */
130	if (rctx->current_render_cond) {
131		render_cond = rctx->current_render_cond;
132		render_cond_mode = rctx->current_render_cond_mode;
133		ctx->render_condition(ctx, NULL, 0);
134	}
135
136	r600_context_flush(rctx, flags);
137
138	/* Re-enable render condition. */
139	if (render_cond) {
140		ctx->render_condition(ctx, render_cond, render_cond_mode);
141	}
142}
143
144static void r600_flush_from_st(struct pipe_context *ctx,
145			       struct pipe_fence_handle **fence)
146{
147	r600_flush(ctx, fence, 0);
148}
149
150static void r600_flush_from_winsys(void *ctx, unsigned flags)
151{
152	r600_flush((struct pipe_context*)ctx, NULL, flags);
153}
154
155static void r600_destroy_context(struct pipe_context *context)
156{
157	struct r600_context *rctx = (struct r600_context *)context;
158
159	if (rctx->no_blend) {
160		rctx->context.delete_blend_state(&rctx->context, rctx->no_blend);
161	}
162	if (rctx->dummy_pixel_shader) {
163		rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
164	}
165	if (rctx->custom_dsa_flush) {
166		rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
167	}
168	if (rctx->custom_blend_resolve) {
169		rctx->context.delete_blend_state(&rctx->context, rctx->custom_blend_resolve);
170	}
171	util_unreference_framebuffer_state(&rctx->framebuffer);
172
173	r600_context_fini(rctx);
174
175	if (rctx->blitter) {
176		util_blitter_destroy(rctx->blitter);
177	}
178	for (int i = 0; i < R600_PIPE_NSTATES; i++) {
179		free(rctx->states[i]);
180	}
181
182	if (rctx->uploader) {
183		u_upload_destroy(rctx->uploader);
184	}
185	util_slab_destroy(&rctx->pool_transfers);
186
187	r600_release_command_buffer(&rctx->start_cs_cmd);
188
189	if (rctx->cs) {
190		rctx->ws->cs_destroy(rctx->cs);
191	}
192
193	FREE(rctx->range);
194	FREE(rctx);
195}
196
197static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
198{
199	struct r600_context *rctx = CALLOC_STRUCT(r600_context);
200	struct r600_screen* rscreen = (struct r600_screen *)screen;
201	struct pipe_blend_state no_blend = {};
202
203	if (rctx == NULL)
204		return NULL;
205
206	util_slab_create(&rctx->pool_transfers,
207			 sizeof(struct r600_transfer), 64,
208			 UTIL_SLAB_SINGLETHREADED);
209
210	rctx->context.screen = screen;
211	rctx->context.priv = priv;
212	rctx->context.destroy = r600_destroy_context;
213	rctx->context.flush = r600_flush_from_st;
214
215	/* Easy accessing of screen/winsys. */
216	rctx->screen = rscreen;
217	rctx->ws = rscreen->ws;
218	rctx->family = rscreen->family;
219	rctx->chip_class = rscreen->chip_class;
220
221	LIST_INITHEAD(&rctx->dirty_states);
222	LIST_INITHEAD(&rctx->active_timer_queries);
223	LIST_INITHEAD(&rctx->active_nontimer_queries);
224	LIST_INITHEAD(&rctx->dirty);
225	LIST_INITHEAD(&rctx->enable_list);
226
227	rctx->range = CALLOC(NUM_RANGES, sizeof(struct r600_range));
228	if (!rctx->range)
229		goto fail;
230
231	r600_init_blit_functions(rctx);
232	r600_init_query_functions(rctx);
233	r600_init_context_resource_functions(rctx);
234	r600_init_surface_functions(rctx);
235	rctx->context.draw_vbo = r600_draw_vbo;
236
237	rctx->context.create_video_decoder = vl_create_decoder;
238	rctx->context.create_video_buffer = vl_video_buffer_create;
239
240	r600_init_common_atoms(rctx);
241
242	switch (rctx->chip_class) {
243	case R600:
244	case R700:
245		r600_init_state_functions(rctx);
246		r600_init_atom_start_cs(rctx);
247		if (r600_context_init(rctx))
248			goto fail;
249		rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
250		rctx->has_vertex_cache = !(rctx->family == CHIP_RV610 ||
251					   rctx->family == CHIP_RV620 ||
252					   rctx->family == CHIP_RS780 ||
253					   rctx->family == CHIP_RS880 ||
254					   rctx->family == CHIP_RV710);
255		break;
256	case EVERGREEN:
257	case CAYMAN:
258		evergreen_init_state_functions(rctx);
259		evergreen_init_atom_start_cs(rctx);
260		evergreen_init_atom_start_compute_cs(rctx);
261		if (evergreen_context_init(rctx))
262			goto fail;
263		rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
264		rctx->custom_blend_resolve = evergreen_create_resolve_blend(rctx);
265		rctx->has_vertex_cache = !(rctx->family == CHIP_CEDAR ||
266					   rctx->family == CHIP_PALM ||
267					   rctx->family == CHIP_SUMO ||
268					   rctx->family == CHIP_SUMO2 ||
269					   rctx->family == CHIP_CAICOS ||
270					   rctx->family == CHIP_CAYMAN ||
271					   rctx->family == CHIP_ARUBA);
272		break;
273	default:
274		R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
275		goto fail;
276	}
277
278	rctx->cs = rctx->ws->cs_create(rctx->ws);
279	rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
280	r600_emit_atom(rctx, &rctx->start_cs_cmd.atom);
281
282        rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
283                                         PIPE_BIND_INDEX_BUFFER |
284                                         PIPE_BIND_CONSTANT_BUFFER);
285        if (!rctx->uploader)
286                goto fail;
287
288	rctx->blitter = util_blitter_create(&rctx->context);
289	if (rctx->blitter == NULL)
290		goto fail;
291
292	r600_get_backend_mask(rctx); /* this emits commands and must be last */
293
294	if (rctx->chip_class == R600)
295		r600_set_max_scissor(rctx);
296
297	rctx->dummy_pixel_shader =
298		util_make_fragment_cloneinput_shader(&rctx->context, 0,
299						     TGSI_SEMANTIC_GENERIC,
300						     TGSI_INTERPOLATE_CONSTANT);
301	rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
302
303	no_blend.rt[0].colormask = 0xF;
304	rctx->no_blend = rctx->context.create_blend_state(&rctx->context, &no_blend);
305
306	return &rctx->context;
307
308fail:
309	r600_destroy_context(&rctx->context);
310	return NULL;
311}
312
313/*
314 * pipe_screen
315 */
316static const char* r600_get_vendor(struct pipe_screen* pscreen)
317{
318	return "X.Org";
319}
320
321static const char *r600_get_family_name(enum radeon_family family)
322{
323	switch(family) {
324	case CHIP_R600: return "AMD R600";
325	case CHIP_RV610: return "AMD RV610";
326	case CHIP_RV630: return "AMD RV630";
327	case CHIP_RV670: return "AMD RV670";
328	case CHIP_RV620: return "AMD RV620";
329	case CHIP_RV635: return "AMD RV635";
330	case CHIP_RS780: return "AMD RS780";
331	case CHIP_RS880: return "AMD RS880";
332	case CHIP_RV770: return "AMD RV770";
333	case CHIP_RV730: return "AMD RV730";
334	case CHIP_RV710: return "AMD RV710";
335	case CHIP_RV740: return "AMD RV740";
336	case CHIP_CEDAR: return "AMD CEDAR";
337	case CHIP_REDWOOD: return "AMD REDWOOD";
338	case CHIP_JUNIPER: return "AMD JUNIPER";
339	case CHIP_CYPRESS: return "AMD CYPRESS";
340	case CHIP_HEMLOCK: return "AMD HEMLOCK";
341	case CHIP_PALM: return "AMD PALM";
342	case CHIP_SUMO: return "AMD SUMO";
343	case CHIP_SUMO2: return "AMD SUMO2";
344	case CHIP_BARTS: return "AMD BARTS";
345	case CHIP_TURKS: return "AMD TURKS";
346	case CHIP_CAICOS: return "AMD CAICOS";
347	case CHIP_CAYMAN: return "AMD CAYMAN";
348	case CHIP_ARUBA: return "AMD ARUBA";
349	default: return "AMD unknown";
350	}
351}
352
353static const char* r600_get_name(struct pipe_screen* pscreen)
354{
355	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
356
357	return r600_get_family_name(rscreen->family);
358}
359
360static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
361{
362	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
363	enum radeon_family family = rscreen->family;
364
365	switch (param) {
366	/* Supported features (boolean caps). */
367	case PIPE_CAP_NPOT_TEXTURES:
368	case PIPE_CAP_TWO_SIDED_STENCIL:
369	case PIPE_CAP_ANISOTROPIC_FILTER:
370	case PIPE_CAP_POINT_SPRITE:
371	case PIPE_CAP_OCCLUSION_QUERY:
372	case PIPE_CAP_TEXTURE_SHADOW_MAP:
373	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
374	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
375	case PIPE_CAP_TEXTURE_SWIZZLE:
376	case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
377	case PIPE_CAP_DEPTH_CLIP_DISABLE:
378	case PIPE_CAP_SHADER_STENCIL_EXPORT:
379	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
380	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
381	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
382	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
383	case PIPE_CAP_SM3:
384	case PIPE_CAP_SEAMLESS_CUBE_MAP:
385	case PIPE_CAP_PRIMITIVE_RESTART:
386	case PIPE_CAP_CONDITIONAL_RENDER:
387	case PIPE_CAP_TEXTURE_BARRIER:
388	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
389	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
390	case PIPE_CAP_TGSI_INSTANCEID:
391	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
392	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
393	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
394	case PIPE_CAP_USER_INDEX_BUFFERS:
395	case PIPE_CAP_USER_CONSTANT_BUFFERS:
396	case PIPE_CAP_COMPUTE:
397	case PIPE_CAP_START_INSTANCE:
398	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
399		return 1;
400
401	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
402		return 256;
403
404	case PIPE_CAP_GLSL_FEATURE_LEVEL:
405		return 130;
406
407	/* Supported except the original R600. */
408	case PIPE_CAP_INDEP_BLEND_ENABLE:
409	case PIPE_CAP_INDEP_BLEND_FUNC:
410		/* R600 doesn't support per-MRT blends */
411		return family == CHIP_R600 ? 0 : 1;
412
413	/* Supported on Evergreen. */
414	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
415		return family >= CHIP_CEDAR ? 1 : 0;
416
417	/* Unsupported features. */
418	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
419	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
420	case PIPE_CAP_SCALED_RESOLVE:
421	case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
422	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
423	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
424	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
425	case PIPE_CAP_USER_VERTEX_BUFFERS:
426		return 0;
427
428	/* Stream output. */
429	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
430		return rscreen->has_streamout ? 4 : 0;
431	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
432		return rscreen->has_streamout ? 1 : 0;
433	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
434	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
435		return 16*4;
436
437	/* Texturing. */
438	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
439	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
440	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
441		if (family >= CHIP_CEDAR)
442			return 15;
443		else
444			return 14;
445	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
446		return rscreen->info.drm_minor >= 9 ?
447			(family >= CHIP_CEDAR ? 16384 : 8192) : 0;
448	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
449		return 32;
450
451	/* Render targets. */
452	case PIPE_CAP_MAX_RENDER_TARGETS:
453		/* XXX some r6xx are buggy and can only do 4 */
454		return 8;
455
456	/* Timer queries, present when the clock frequency is non zero. */
457	case PIPE_CAP_TIMER_QUERY:
458		return rscreen->info.r600_clock_crystal_freq != 0;
459	case PIPE_CAP_QUERY_TIMESTAMP:
460		return rscreen->info.drm_minor >= 20 &&
461		       rscreen->info.r600_clock_crystal_freq != 0;
462
463	case PIPE_CAP_MIN_TEXEL_OFFSET:
464		return -8;
465
466	case PIPE_CAP_MAX_TEXEL_OFFSET:
467		return 7;
468	}
469	return 0;
470}
471
472static float r600_get_paramf(struct pipe_screen* pscreen,
473			     enum pipe_capf param)
474{
475	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
476	enum radeon_family family = rscreen->family;
477
478	switch (param) {
479	case PIPE_CAPF_MAX_LINE_WIDTH:
480	case PIPE_CAPF_MAX_LINE_WIDTH_AA:
481	case PIPE_CAPF_MAX_POINT_WIDTH:
482	case PIPE_CAPF_MAX_POINT_WIDTH_AA:
483		if (family >= CHIP_CEDAR)
484			return 16384.0f;
485		else
486			return 8192.0f;
487	case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
488		return 16.0f;
489	case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
490		return 16.0f;
491	case PIPE_CAPF_GUARD_BAND_LEFT:
492	case PIPE_CAPF_GUARD_BAND_TOP:
493	case PIPE_CAPF_GUARD_BAND_RIGHT:
494	case PIPE_CAPF_GUARD_BAND_BOTTOM:
495		return 0.0f;
496	}
497	return 0.0f;
498}
499
500static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
501{
502	switch(shader)
503	{
504	case PIPE_SHADER_FRAGMENT:
505	case PIPE_SHADER_VERTEX:
506        case PIPE_SHADER_COMPUTE:
507		break;
508	case PIPE_SHADER_GEOMETRY:
509		/* XXX: support and enable geometry programs */
510		return 0;
511	default:
512		/* XXX: support tessellation on Evergreen */
513		return 0;
514	}
515
516	/* XXX: all these should be fixed, since r600 surely supports much more! */
517	switch (param) {
518	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
519	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
520	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
521	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
522		return 16384;
523	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
524		return 8; /* XXX */
525	case PIPE_SHADER_CAP_MAX_INPUTS:
526		if(shader == PIPE_SHADER_FRAGMENT)
527			return 34;
528		else
529			return 32;
530	case PIPE_SHADER_CAP_MAX_TEMPS:
531		return 256; /* Max native temporaries. */
532	case PIPE_SHADER_CAP_MAX_ADDRS:
533		/* XXX Isn't this equal to TEMPS? */
534		return 1; /* Max native address registers */
535	case PIPE_SHADER_CAP_MAX_CONSTS:
536		return R600_MAX_CONST_BUFFER_SIZE;
537	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
538		return R600_MAX_CONST_BUFFERS-1;
539	case PIPE_SHADER_CAP_MAX_PREDS:
540		return 0; /* nothing uses this */
541	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
542		return 1;
543	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
544	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
545	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
546	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
547		return 1;
548	case PIPE_SHADER_CAP_SUBROUTINES:
549		return 0;
550	case PIPE_SHADER_CAP_INTEGERS:
551		return 1;
552	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
553		return 16;
554        case PIPE_SHADER_CAP_PREFERRED_IR:
555		if (shader == PIPE_SHADER_COMPUTE) {
556			return PIPE_SHADER_IR_LLVM;
557		} else {
558			return PIPE_SHADER_IR_TGSI;
559		}
560	}
561	return 0;
562}
563
564static int r600_get_video_param(struct pipe_screen *screen,
565				enum pipe_video_profile profile,
566				enum pipe_video_cap param)
567{
568	switch (param) {
569	case PIPE_VIDEO_CAP_SUPPORTED:
570		return vl_profile_supported(screen, profile);
571	case PIPE_VIDEO_CAP_NPOT_TEXTURES:
572		return 1;
573	case PIPE_VIDEO_CAP_MAX_WIDTH:
574	case PIPE_VIDEO_CAP_MAX_HEIGHT:
575		return vl_video_buffer_max_size(screen);
576	case PIPE_VIDEO_CAP_PREFERED_FORMAT:
577		return PIPE_FORMAT_NV12;
578	case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
579		return false;
580	case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
581		return false;
582	case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
583		return true;
584	default:
585		return 0;
586	}
587}
588
589static int r600_get_compute_param(struct pipe_screen *screen,
590        enum pipe_compute_cap param,
591        void *ret)
592{
593	//TODO: select these params by asic
594	switch (param) {
595	case PIPE_COMPUTE_CAP_IR_TARGET:
596		if (ret) {
597			strcpy(ret, "r600--");
598		}
599		return 7 * sizeof(char);
600
601	case PIPE_COMPUTE_CAP_GRID_DIMENSION:
602		if (ret) {
603			uint64_t * grid_dimension = ret;
604			grid_dimension[0] = 3;
605		}
606		return 1 * sizeof(uint64_t);
607
608	case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
609		if (ret) {
610			uint64_t * grid_size = ret;
611			grid_size[0] = 65535;
612			grid_size[1] = 65535;
613			grid_size[2] = 1;
614		}
615		return 3 * sizeof(uint64_t) ;
616
617	case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
618		if (ret) {
619			uint64_t * block_size = ret;
620			block_size[0] = 256;
621			block_size[1] = 256;
622			block_size[2] = 256;
623		}
624		return 3 * sizeof(uint64_t);
625
626	case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
627		if (ret) {
628			uint64_t * max_threads_per_block = ret;
629			*max_threads_per_block = 256;
630		}
631		return sizeof(uint64_t);
632
633	case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
634		if (ret) {
635			uint64_t * max_global_size = ret;
636			/* XXX: This is 64kb for now until we get the
637			 * compute memory pool working correctly.
638			 */
639			*max_global_size = 1024 * 16 * 4;
640		}
641		return sizeof(uint64_t);
642
643	case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
644		if (ret) {
645			uint64_t * max_input_size = ret;
646			*max_input_size = 1024;
647		}
648		return sizeof(uint64_t);
649
650	case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
651		if (ret) {
652			uint64_t * max_local_size = ret;
653			/* XXX: This is what the proprietary driver reports, we
654			 * may want to use a different value. */
655			*max_local_size = 32768;
656		}
657		return sizeof(uint64_t);
658
659	default:
660		fprintf(stderr, "unknown PIPE_COMPUTE_CAP %d\n", param);
661		return 0;
662	}
663}
664
665static void r600_destroy_screen(struct pipe_screen* pscreen)
666{
667	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
668
669	if (rscreen == NULL)
670		return;
671
672	if (rscreen->global_pool) {
673		compute_memory_pool_delete(rscreen->global_pool);
674	}
675
676	if (rscreen->fences.bo) {
677		struct r600_fence_block *entry, *tmp;
678
679		LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, &rscreen->fences.blocks, head) {
680			LIST_DEL(&entry->head);
681			FREE(entry);
682		}
683
684		rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
685		pipe_resource_reference((struct pipe_resource**)&rscreen->fences.bo, NULL);
686	}
687	pipe_mutex_destroy(rscreen->fences.mutex);
688
689	rscreen->ws->destroy(rscreen->ws);
690	FREE(rscreen);
691}
692
693static void r600_fence_reference(struct pipe_screen *pscreen,
694                                 struct pipe_fence_handle **ptr,
695                                 struct pipe_fence_handle *fence)
696{
697	struct r600_fence **oldf = (struct r600_fence**)ptr;
698	struct r600_fence *newf = (struct r600_fence*)fence;
699
700	if (pipe_reference(&(*oldf)->reference, &newf->reference)) {
701		struct r600_screen *rscreen = (struct r600_screen *)pscreen;
702		pipe_mutex_lock(rscreen->fences.mutex);
703		pipe_resource_reference((struct pipe_resource**)&(*oldf)->sleep_bo, NULL);
704		LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool);
705		pipe_mutex_unlock(rscreen->fences.mutex);
706	}
707
708	*ptr = fence;
709}
710
711static boolean r600_fence_signalled(struct pipe_screen *pscreen,
712                                    struct pipe_fence_handle *fence)
713{
714	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
715	struct r600_fence *rfence = (struct r600_fence*)fence;
716
717	return rscreen->fences.data[rfence->index];
718}
719
720static boolean r600_fence_finish(struct pipe_screen *pscreen,
721                                 struct pipe_fence_handle *fence,
722                                 uint64_t timeout)
723{
724	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
725	struct r600_fence *rfence = (struct r600_fence*)fence;
726	int64_t start_time = 0;
727	unsigned spins = 0;
728
729	if (timeout != PIPE_TIMEOUT_INFINITE) {
730		start_time = os_time_get();
731
732		/* Convert to microseconds. */
733		timeout /= 1000;
734	}
735
736	while (rscreen->fences.data[rfence->index] == 0) {
737		/* Special-case infinite timeout - wait for the dummy BO to become idle */
738		if (timeout == PIPE_TIMEOUT_INFINITE) {
739			rscreen->ws->buffer_wait(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE);
740			break;
741		}
742
743		/* The dummy BO will be busy until the CS including the fence has completed, or
744		 * the GPU is reset. Don't bother continuing to spin when the BO is idle. */
745		if (!rscreen->ws->buffer_is_busy(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE))
746			break;
747
748		if (++spins % 256)
749			continue;
750#ifdef PIPE_OS_UNIX
751		sched_yield();
752#else
753		os_time_sleep(10);
754#endif
755		if (timeout != PIPE_TIMEOUT_INFINITE &&
756		    os_time_get() - start_time >= timeout) {
757			break;
758		}
759	}
760
761	return rscreen->fences.data[rfence->index] != 0;
762}
763
764static int r600_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
765{
766	switch ((tiling_config & 0xe) >> 1) {
767	case 0:
768		rscreen->tiling_info.num_channels = 1;
769		break;
770	case 1:
771		rscreen->tiling_info.num_channels = 2;
772		break;
773	case 2:
774		rscreen->tiling_info.num_channels = 4;
775		break;
776	case 3:
777		rscreen->tiling_info.num_channels = 8;
778		break;
779	default:
780		return -EINVAL;
781	}
782
783	switch ((tiling_config & 0x30) >> 4) {
784	case 0:
785		rscreen->tiling_info.num_banks = 4;
786		break;
787	case 1:
788		rscreen->tiling_info.num_banks = 8;
789		break;
790	default:
791		return -EINVAL;
792
793	}
794	switch ((tiling_config & 0xc0) >> 6) {
795	case 0:
796		rscreen->tiling_info.group_bytes = 256;
797		break;
798	case 1:
799		rscreen->tiling_info.group_bytes = 512;
800		break;
801	default:
802		return -EINVAL;
803	}
804	return 0;
805}
806
807static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
808{
809	switch (tiling_config & 0xf) {
810	case 0:
811		rscreen->tiling_info.num_channels = 1;
812		break;
813	case 1:
814		rscreen->tiling_info.num_channels = 2;
815		break;
816	case 2:
817		rscreen->tiling_info.num_channels = 4;
818		break;
819	case 3:
820		rscreen->tiling_info.num_channels = 8;
821		break;
822	default:
823		return -EINVAL;
824	}
825
826	switch ((tiling_config & 0xf0) >> 4) {
827	case 0:
828		rscreen->tiling_info.num_banks = 4;
829		break;
830	case 1:
831		rscreen->tiling_info.num_banks = 8;
832		break;
833	case 2:
834		rscreen->tiling_info.num_banks = 16;
835		break;
836	default:
837		return -EINVAL;
838	}
839
840	switch ((tiling_config & 0xf00) >> 8) {
841	case 0:
842		rscreen->tiling_info.group_bytes = 256;
843		break;
844	case 1:
845		rscreen->tiling_info.group_bytes = 512;
846		break;
847	default:
848		return -EINVAL;
849	}
850	return 0;
851}
852
853static int r600_init_tiling(struct r600_screen *rscreen)
854{
855	uint32_t tiling_config = rscreen->info.r600_tiling_config;
856
857	/* set default group bytes, overridden by tiling info ioctl */
858	if (rscreen->chip_class <= R700) {
859		rscreen->tiling_info.group_bytes = 256;
860	} else {
861		rscreen->tiling_info.group_bytes = 512;
862	}
863
864	if (!tiling_config)
865		return 0;
866
867	if (rscreen->chip_class <= R700) {
868		return r600_interpret_tiling(rscreen, tiling_config);
869	} else {
870		return evergreen_interpret_tiling(rscreen, tiling_config);
871	}
872}
873
874static unsigned radeon_family_from_device(unsigned device)
875{
876	switch (device) {
877#define CHIPSET(pciid, name, family) case pciid: return CHIP_##family;
878#include "pci_ids/r600_pci_ids.h"
879#undef CHIPSET
880	default:
881		return CHIP_UNKNOWN;
882	}
883}
884
885static uint64_t r600_get_timestamp(struct pipe_screen *screen)
886{
887	struct r600_screen *rscreen = (struct r600_screen*)screen;
888
889	return 1000000 * rscreen->ws->query_timestamp(rscreen->ws) /
890			rscreen->info.r600_clock_crystal_freq;
891}
892
893struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
894{
895	struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
896
897	if (rscreen == NULL) {
898		return NULL;
899	}
900
901	rscreen->ws = ws;
902	ws->query_info(ws, &rscreen->info);
903
904	rscreen->family = radeon_family_from_device(rscreen->info.pci_id);
905	if (rscreen->family == CHIP_UNKNOWN) {
906		fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
907		FREE(rscreen);
908		return NULL;
909	}
910
911	/* setup class */
912	if (rscreen->family >= CHIP_CAYMAN) {
913		rscreen->chip_class = CAYMAN;
914	} else if (rscreen->family >= CHIP_CEDAR) {
915		rscreen->chip_class = EVERGREEN;
916	} else if (rscreen->family >= CHIP_RV770) {
917		rscreen->chip_class = R700;
918	} else {
919		rscreen->chip_class = R600;
920	}
921
922	/* Figure out streamout kernel support. */
923	switch (rscreen->chip_class) {
924	case R600:
925	case EVERGREEN:
926		rscreen->has_streamout = rscreen->info.drm_minor >= 14;
927		break;
928	case R700:
929		rscreen->has_streamout = rscreen->info.drm_minor >= 17;
930		break;
931	/* TODO: Cayman */
932	default:
933		rscreen->has_streamout = debug_get_bool_option("R600_STREAMOUT", FALSE);
934	}
935
936	if (r600_init_tiling(rscreen)) {
937		FREE(rscreen);
938		return NULL;
939	}
940
941	rscreen->screen.destroy = r600_destroy_screen;
942	rscreen->screen.get_name = r600_get_name;
943	rscreen->screen.get_vendor = r600_get_vendor;
944	rscreen->screen.get_param = r600_get_param;
945	rscreen->screen.get_shader_param = r600_get_shader_param;
946	rscreen->screen.get_paramf = r600_get_paramf;
947	rscreen->screen.get_video_param = r600_get_video_param;
948	rscreen->screen.get_compute_param = r600_get_compute_param;
949	rscreen->screen.get_timestamp = r600_get_timestamp;
950
951	if (rscreen->chip_class >= EVERGREEN) {
952		rscreen->screen.is_format_supported = evergreen_is_format_supported;
953	} else {
954		rscreen->screen.is_format_supported = r600_is_format_supported;
955	}
956	rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
957	rscreen->screen.context_create = r600_create_context;
958	rscreen->screen.fence_reference = r600_fence_reference;
959	rscreen->screen.fence_signalled = r600_fence_signalled;
960	rscreen->screen.fence_finish = r600_fence_finish;
961	r600_init_screen_resource_functions(&rscreen->screen);
962
963	util_format_s3tc_init();
964
965	rscreen->fences.bo = NULL;
966	rscreen->fences.data = NULL;
967	rscreen->fences.next_index = 0;
968	LIST_INITHEAD(&rscreen->fences.pool);
969	LIST_INITHEAD(&rscreen->fences.blocks);
970	pipe_mutex_init(rscreen->fences.mutex);
971
972	rscreen->global_pool = compute_memory_pool_new(rscreen);
973
974	return &rscreen->screen;
975}
976