radeonsi_pipe.c revision 1b11395a36a44a902cfb3e1783758544662df73f
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 <stdio.h>
24#include <errno.h>
25#include "pipe/p_defines.h"
26#include "pipe/p_state.h"
27#include "pipe/p_context.h"
28#include "tgsi/tgsi_scan.h"
29#include "tgsi/tgsi_parse.h"
30#include "tgsi/tgsi_util.h"
31#include "util/u_blitter.h"
32#include "util/u_double_list.h"
33#include "util/u_format.h"
34#include "util/u_format_s3tc.h"
35#include "util/u_transfer.h"
36#include "util/u_surface.h"
37#include "util/u_pack_color.h"
38#include "util/u_memory.h"
39#include "util/u_inlines.h"
40#include "util/u_simple_shaders.h"
41#include "util/u_upload_mgr.h"
42#include "vl/vl_decoder.h"
43#include "vl/vl_video_buffer.h"
44#include "os/os_time.h"
45#include "pipebuffer/pb_buffer.h"
46#include "r600.h"
47#include "sid.h"
48#include "r600_resource.h"
49#include "radeonsi_pipe.h"
50#include "r600_hw_context_priv.h"
51#include "si_state.h"
52
53/*
54 * pipe_context
55 */
56static struct r600_fence *r600_create_fence(struct r600_context *rctx)
57{
58	struct r600_screen *rscreen = rctx->screen;
59	struct r600_fence *fence = NULL;
60
61	pipe_mutex_lock(rscreen->fences.mutex);
62
63	if (!rscreen->fences.bo) {
64		/* Create the shared buffer object */
65		rscreen->fences.bo = si_resource_create_custom(&rscreen->screen,
66							       PIPE_USAGE_STAGING,
67							       4096);
68		if (!rscreen->fences.bo) {
69			R600_ERR("r600: failed to create bo for fence objects\n");
70			goto out;
71		}
72		rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->cs_buf,
73							   rctx->cs,
74							   PIPE_TRANSFER_READ_WRITE);
75	}
76
77	if (!LIST_IS_EMPTY(&rscreen->fences.pool)) {
78		struct r600_fence *entry;
79
80		/* Try to find a freed fence that has been signalled */
81		LIST_FOR_EACH_ENTRY(entry, &rscreen->fences.pool, head) {
82			if (rscreen->fences.data[entry->index] != 0) {
83				LIST_DELINIT(&entry->head);
84				fence = entry;
85				break;
86			}
87		}
88	}
89
90	if (!fence) {
91		/* Allocate a new fence */
92		struct r600_fence_block *block;
93		unsigned index;
94
95		if ((rscreen->fences.next_index + 1) >= 1024) {
96			R600_ERR("r600: too many concurrent fences\n");
97			goto out;
98		}
99
100		index = rscreen->fences.next_index++;
101
102		if (!(index % FENCE_BLOCK_SIZE)) {
103			/* Allocate a new block */
104			block = CALLOC_STRUCT(r600_fence_block);
105			if (block == NULL)
106				goto out;
107
108			LIST_ADD(&block->head, &rscreen->fences.blocks);
109		} else {
110			block = LIST_ENTRY(struct r600_fence_block, rscreen->fences.blocks.next, head);
111		}
112
113		fence = &block->fences[index % FENCE_BLOCK_SIZE];
114		fence->index = index;
115	}
116
117	pipe_reference_init(&fence->reference, 1);
118
119	rscreen->fences.data[fence->index] = 0;
120	si_context_emit_fence(rctx, rscreen->fences.bo, fence->index, 1);
121
122	/* Create a dummy BO so that fence_finish without a timeout can sleep waiting for completion */
123	fence->sleep_bo = si_resource_create_custom(&rctx->screen->screen, PIPE_USAGE_STAGING, 1);
124
125	/* Add the fence as a dummy relocation. */
126	r600_context_bo_reloc(rctx, fence->sleep_bo, RADEON_USAGE_READWRITE);
127
128out:
129	pipe_mutex_unlock(rscreen->fences.mutex);
130	return fence;
131}
132
133
134void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
135		    unsigned flags)
136{
137	struct r600_context *rctx = (struct r600_context *)ctx;
138	struct r600_fence **rfence = (struct r600_fence**)fence;
139	struct pipe_query *render_cond = NULL;
140	unsigned render_cond_mode = 0;
141
142	if (rfence)
143		*rfence = r600_create_fence(rctx);
144
145	/* Disable render condition. */
146	if (rctx->current_render_cond) {
147		render_cond = rctx->current_render_cond;
148		render_cond_mode = rctx->current_render_cond_mode;
149		ctx->render_condition(ctx, NULL, 0);
150	}
151
152	si_context_flush(rctx, flags);
153
154	/* Re-enable render condition. */
155	if (render_cond) {
156		ctx->render_condition(ctx, render_cond, render_cond_mode);
157	}
158}
159
160static void r600_flush_from_st(struct pipe_context *ctx,
161			       struct pipe_fence_handle **fence)
162{
163	radeonsi_flush(ctx, fence, 0);
164}
165
166static void r600_flush_from_winsys(void *ctx, unsigned flags)
167{
168	radeonsi_flush((struct pipe_context*)ctx, NULL, flags);
169}
170
171static void r600_destroy_context(struct pipe_context *context)
172{
173	struct r600_context *rctx = (struct r600_context *)context;
174
175	if (rctx->dummy_pixel_shader) {
176		rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
177	}
178	rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
179	util_unreference_framebuffer_state(&rctx->framebuffer);
180
181	util_blitter_destroy(rctx->blitter);
182
183	if (rctx->uploader) {
184		u_upload_destroy(rctx->uploader);
185	}
186	util_slab_destroy(&rctx->pool_transfers);
187	FREE(rctx);
188}
189
190static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
191{
192	struct r600_context *rctx = CALLOC_STRUCT(r600_context);
193	struct r600_screen* rscreen = (struct r600_screen *)screen;
194
195	if (rctx == NULL)
196		return NULL;
197
198	rctx->context.screen = screen;
199	rctx->context.priv = priv;
200	rctx->context.destroy = r600_destroy_context;
201	rctx->context.flush = r600_flush_from_st;
202
203	/* Easy accessing of screen/winsys. */
204	rctx->screen = rscreen;
205	rctx->ws = rscreen->ws;
206	rctx->family = rscreen->family;
207	rctx->chip_class = rscreen->chip_class;
208
209	si_init_blit_functions(rctx);
210	r600_init_query_functions(rctx);
211	r600_init_context_resource_functions(rctx);
212	si_init_surface_functions(rctx);
213
214	rctx->context.create_video_decoder = vl_create_decoder;
215	rctx->context.create_video_buffer = vl_video_buffer_create;
216
217	switch (rctx->chip_class) {
218	case TAHITI:
219		si_init_state_functions(rctx);
220		if (si_context_init(rctx)) {
221			r600_destroy_context(&rctx->context);
222			return NULL;
223		}
224		si_init_config(rctx);
225		break;
226	default:
227		R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
228		r600_destroy_context(&rctx->context);
229		return NULL;
230	}
231
232	rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
233
234	util_slab_create(&rctx->pool_transfers,
235			 sizeof(struct pipe_transfer), 64,
236			 UTIL_SLAB_SINGLETHREADED);
237
238        rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
239                                         PIPE_BIND_INDEX_BUFFER |
240                                         PIPE_BIND_CONSTANT_BUFFER);
241        if (!rctx->uploader) {
242		r600_destroy_context(&rctx->context);
243		return NULL;
244	}
245
246	rctx->blitter = util_blitter_create(&rctx->context);
247	if (rctx->blitter == NULL) {
248		r600_destroy_context(&rctx->context);
249		return NULL;
250	}
251
252	si_get_backend_mask(rctx); /* this emits commands and must be last */
253
254	rctx->dummy_pixel_shader =
255		util_make_fragment_cloneinput_shader(&rctx->context, 0,
256						     TGSI_SEMANTIC_GENERIC,
257						     TGSI_INTERPOLATE_CONSTANT);
258	rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
259
260	return &rctx->context;
261}
262
263/*
264 * pipe_screen
265 */
266static const char* r600_get_vendor(struct pipe_screen* pscreen)
267{
268	return "X.Org";
269}
270
271static const char *r600_get_family_name(enum radeon_family family)
272{
273	switch(family) {
274	case CHIP_TAHITI: return "AMD TAHITI";
275	case CHIP_PITCAIRN: return "AMD PITCAIRN";
276	case CHIP_VERDE: return "AMD CAPE VERDE";
277	default: return "AMD unknown";
278	}
279}
280
281static const char* r600_get_name(struct pipe_screen* pscreen)
282{
283	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
284
285	return r600_get_family_name(rscreen->family);
286}
287
288static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
289{
290	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
291	enum radeon_family family = rscreen->family;
292
293	switch (param) {
294	/* Supported features (boolean caps). */
295	case PIPE_CAP_NPOT_TEXTURES:
296	case PIPE_CAP_TWO_SIDED_STENCIL:
297	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
298	case PIPE_CAP_ANISOTROPIC_FILTER:
299	case PIPE_CAP_POINT_SPRITE:
300	case PIPE_CAP_OCCLUSION_QUERY:
301	case PIPE_CAP_TEXTURE_SHADOW_MAP:
302	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
303	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
304	case PIPE_CAP_TEXTURE_SWIZZLE:
305	case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
306	case PIPE_CAP_DEPTH_CLIP_DISABLE:
307	case PIPE_CAP_SHADER_STENCIL_EXPORT:
308	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
309	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
310	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
311	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
312	case PIPE_CAP_SM3:
313	case PIPE_CAP_SEAMLESS_CUBE_MAP:
314	case PIPE_CAP_PRIMITIVE_RESTART:
315	case PIPE_CAP_CONDITIONAL_RENDER:
316	case PIPE_CAP_TEXTURE_BARRIER:
317	case PIPE_CAP_INDEP_BLEND_ENABLE:
318	case PIPE_CAP_INDEP_BLEND_FUNC:
319	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
320	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
321	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
322	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
323	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
324	case PIPE_CAP_USER_INDEX_BUFFERS:
325	case PIPE_CAP_USER_CONSTANT_BUFFERS:
326	case PIPE_CAP_START_INSTANCE:
327		return 1;
328
329	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
330		return 256;
331
332	case PIPE_CAP_GLSL_FEATURE_LEVEL:
333		return debug_get_bool_option("R600_GLSL130", FALSE) ? 130 : 120;
334
335	/* Unsupported features. */
336	case PIPE_CAP_TGSI_INSTANCEID:
337	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
338	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
339	case PIPE_CAP_SCALED_RESOLVE:
340	case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
341	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
342	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
343	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
344	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
345	case PIPE_CAP_USER_VERTEX_BUFFERS:
346		return 0;
347
348	/* Stream output. */
349#if 0
350	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
351		return debug_get_bool_option("R600_STREAMOUT", FALSE) ? 4 : 0;
352	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
353		return debug_get_bool_option("R600_STREAMOUT", FALSE) ? 1 : 0;
354	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
355	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
356		return 16*4;
357#endif
358	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
359	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
360	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
361	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
362		return 0;
363
364	/* Texturing. */
365	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
366	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
367	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
368			return 15;
369	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
370		return rscreen->info.drm_minor >= 9 ? 16384 : 0;
371	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
372		return 32;
373
374	/* Render targets. */
375	case PIPE_CAP_MAX_RENDER_TARGETS:
376		/* FIXME some r6xx are buggy and can only do 4 */
377		return 8;
378
379	/* Timer queries, present when the clock frequency is non zero. */
380	case PIPE_CAP_TIMER_QUERY:
381		return rscreen->info.r600_clock_crystal_freq != 0;
382
383	case PIPE_CAP_MIN_TEXEL_OFFSET:
384		return -8;
385
386	case PIPE_CAP_MAX_TEXEL_OFFSET:
387		return 7;
388	}
389	return 0;
390}
391
392static float r600_get_paramf(struct pipe_screen* pscreen,
393			     enum pipe_capf param)
394{
395	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
396	enum radeon_family family = rscreen->family;
397
398	switch (param) {
399	case PIPE_CAPF_MAX_LINE_WIDTH:
400	case PIPE_CAPF_MAX_LINE_WIDTH_AA:
401	case PIPE_CAPF_MAX_POINT_WIDTH:
402	case PIPE_CAPF_MAX_POINT_WIDTH_AA:
403		return 16384.0f;
404	case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
405		return 16.0f;
406	case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
407		return 16.0f;
408	case PIPE_CAPF_GUARD_BAND_LEFT:
409	case PIPE_CAPF_GUARD_BAND_TOP:
410	case PIPE_CAPF_GUARD_BAND_RIGHT:
411	case PIPE_CAPF_GUARD_BAND_BOTTOM:
412		return 0.0f;
413	}
414	return 0.0f;
415}
416
417static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
418{
419	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
420	switch(shader)
421	{
422	case PIPE_SHADER_FRAGMENT:
423	case PIPE_SHADER_VERTEX:
424		break;
425	case PIPE_SHADER_GEOMETRY:
426		/* TODO: support and enable geometry programs */
427		return 0;
428	default:
429		/* TODO: support tessellation */
430		return 0;
431	}
432
433	/* TODO: all these should be fixed, since r600 surely supports much more! */
434	switch (param) {
435	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
436	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
437	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
438	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
439		return 16384;
440	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
441		return 8; /* FIXME */
442	case PIPE_SHADER_CAP_MAX_INPUTS:
443		if(shader == PIPE_SHADER_FRAGMENT)
444			return 34;
445		else
446			return 32;
447	case PIPE_SHADER_CAP_MAX_TEMPS:
448		return 256; /* Max native temporaries. */
449	case PIPE_SHADER_CAP_MAX_ADDRS:
450		/* FIXME Isn't this equal to TEMPS? */
451		return 1; /* Max native address registers */
452	case PIPE_SHADER_CAP_MAX_CONSTS:
453		return R600_MAX_CONST_BUFFER_SIZE;
454	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
455		return R600_MAX_CONST_BUFFERS;
456	case PIPE_SHADER_CAP_MAX_PREDS:
457		return 0; /* FIXME */
458	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
459		return 1;
460	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
461	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
462	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
463	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
464		return 0;
465	case PIPE_SHADER_CAP_INTEGERS:
466		return 1;
467	case PIPE_SHADER_CAP_SUBROUTINES:
468		return 0;
469	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
470		return 16;
471	}
472	return 0;
473}
474
475static int r600_get_video_param(struct pipe_screen *screen,
476				enum pipe_video_profile profile,
477				enum pipe_video_cap param)
478{
479	switch (param) {
480	case PIPE_VIDEO_CAP_SUPPORTED:
481		return vl_profile_supported(screen, profile);
482	case PIPE_VIDEO_CAP_NPOT_TEXTURES:
483		return 1;
484	case PIPE_VIDEO_CAP_MAX_WIDTH:
485	case PIPE_VIDEO_CAP_MAX_HEIGHT:
486		return vl_video_buffer_max_size(screen);
487	case PIPE_VIDEO_CAP_PREFERED_FORMAT:
488		return PIPE_FORMAT_NV12;
489	default:
490		return 0;
491	}
492}
493
494static void r600_destroy_screen(struct pipe_screen* pscreen)
495{
496	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
497
498	if (rscreen == NULL)
499		return;
500
501	if (rscreen->fences.bo) {
502		struct r600_fence_block *entry, *tmp;
503
504		LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, &rscreen->fences.blocks, head) {
505			LIST_DEL(&entry->head);
506			FREE(entry);
507		}
508
509		rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
510		si_resource_reference(&rscreen->fences.bo, NULL);
511	}
512	pipe_mutex_destroy(rscreen->fences.mutex);
513
514	rscreen->ws->destroy(rscreen->ws);
515	FREE(rscreen);
516}
517
518static void r600_fence_reference(struct pipe_screen *pscreen,
519                                 struct pipe_fence_handle **ptr,
520                                 struct pipe_fence_handle *fence)
521{
522	struct r600_fence **oldf = (struct r600_fence**)ptr;
523	struct r600_fence *newf = (struct r600_fence*)fence;
524
525	if (pipe_reference(&(*oldf)->reference, &newf->reference)) {
526		struct r600_screen *rscreen = (struct r600_screen *)pscreen;
527		pipe_mutex_lock(rscreen->fences.mutex);
528		si_resource_reference(&(*oldf)->sleep_bo, NULL);
529		LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool);
530		pipe_mutex_unlock(rscreen->fences.mutex);
531	}
532
533	*ptr = fence;
534}
535
536static boolean r600_fence_signalled(struct pipe_screen *pscreen,
537                                    struct pipe_fence_handle *fence)
538{
539	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
540	struct r600_fence *rfence = (struct r600_fence*)fence;
541
542	return rscreen->fences.data[rfence->index];
543}
544
545static boolean r600_fence_finish(struct pipe_screen *pscreen,
546                                 struct pipe_fence_handle *fence,
547                                 uint64_t timeout)
548{
549	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
550	struct r600_fence *rfence = (struct r600_fence*)fence;
551	int64_t start_time = 0;
552	unsigned spins = 0;
553
554	if (timeout != PIPE_TIMEOUT_INFINITE) {
555		start_time = os_time_get();
556
557		/* Convert to microseconds. */
558		timeout /= 1000;
559	}
560
561	while (rscreen->fences.data[rfence->index] == 0) {
562		/* Special-case infinite timeout - wait for the dummy BO to become idle */
563		if (timeout == PIPE_TIMEOUT_INFINITE) {
564			rscreen->ws->buffer_wait(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE);
565			break;
566		}
567
568		/* The dummy BO will be busy until the CS including the fence has completed, or
569		 * the GPU is reset. Don't bother continuing to spin when the BO is idle. */
570		if (!rscreen->ws->buffer_is_busy(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE))
571			break;
572
573		if (++spins % 256)
574			continue;
575#ifdef PIPE_OS_UNIX
576		sched_yield();
577#else
578		os_time_sleep(10);
579#endif
580		if (timeout != PIPE_TIMEOUT_INFINITE &&
581		    os_time_get() - start_time >= timeout) {
582			break;
583		}
584	}
585
586	return rscreen->fences.data[rfence->index] != 0;
587}
588
589static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
590{
591	switch (tiling_config & 0xf) {
592	case 0:
593		rscreen->tiling_info.num_channels = 1;
594		break;
595	case 1:
596		rscreen->tiling_info.num_channels = 2;
597		break;
598	case 2:
599		rscreen->tiling_info.num_channels = 4;
600		break;
601	case 3:
602		rscreen->tiling_info.num_channels = 8;
603		break;
604	default:
605		return -EINVAL;
606	}
607
608	switch ((tiling_config & 0xf0) >> 4) {
609	case 0:
610		rscreen->tiling_info.num_banks = 4;
611		break;
612	case 1:
613		rscreen->tiling_info.num_banks = 8;
614		break;
615	case 2:
616		rscreen->tiling_info.num_banks = 16;
617		break;
618	default:
619		return -EINVAL;
620	}
621
622	switch ((tiling_config & 0xf00) >> 8) {
623	case 0:
624		rscreen->tiling_info.group_bytes = 256;
625		break;
626	case 1:
627		rscreen->tiling_info.group_bytes = 512;
628		break;
629	default:
630		return -EINVAL;
631	}
632	return 0;
633}
634
635static int r600_init_tiling(struct r600_screen *rscreen)
636{
637	uint32_t tiling_config = rscreen->info.r600_tiling_config;
638
639	/* set default group bytes, overridden by tiling info ioctl */
640	rscreen->tiling_info.group_bytes = 512;
641
642	if (!tiling_config)
643		return 0;
644
645	return evergreen_interpret_tiling(rscreen, tiling_config);
646}
647
648static unsigned radeon_family_from_device(unsigned device)
649{
650	switch (device) {
651#define CHIPSET(pciid, name, family) case pciid: return CHIP_##family;
652#include "pci_ids/radeonsi_pci_ids.h"
653#undef CHIPSET
654	default:
655		return CHIP_UNKNOWN;
656	}
657}
658
659struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
660{
661	struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
662	if (rscreen == NULL) {
663		return NULL;
664	}
665
666	rscreen->ws = ws;
667	ws->query_info(ws, &rscreen->info);
668
669	rscreen->family = radeon_family_from_device(rscreen->info.pci_id);
670	if (rscreen->family == CHIP_UNKNOWN) {
671		fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
672		FREE(rscreen);
673		return NULL;
674	}
675
676	/* setup class */
677	if (rscreen->family >= CHIP_TAHITI) {
678		rscreen->chip_class = TAHITI;
679	} else {
680		fprintf(stderr, "r600: Unsupported family %d\n", rscreen->family);
681		FREE(rscreen);
682		return NULL;
683	}
684
685	if (r600_init_tiling(rscreen)) {
686		FREE(rscreen);
687		return NULL;
688	}
689
690	rscreen->screen.destroy = r600_destroy_screen;
691	rscreen->screen.get_name = r600_get_name;
692	rscreen->screen.get_vendor = r600_get_vendor;
693	rscreen->screen.get_param = r600_get_param;
694	rscreen->screen.get_shader_param = r600_get_shader_param;
695	rscreen->screen.get_paramf = r600_get_paramf;
696	rscreen->screen.get_video_param = r600_get_video_param;
697	rscreen->screen.is_format_supported = si_is_format_supported;
698	rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
699	rscreen->screen.context_create = r600_create_context;
700	rscreen->screen.fence_reference = r600_fence_reference;
701	rscreen->screen.fence_signalled = r600_fence_signalled;
702	rscreen->screen.fence_finish = r600_fence_finish;
703	r600_init_screen_resource_functions(&rscreen->screen);
704
705	util_format_s3tc_init();
706
707	rscreen->fences.bo = NULL;
708	rscreen->fences.data = NULL;
709	rscreen->fences.next_index = 0;
710	LIST_INITHEAD(&rscreen->fences.pool);
711	LIST_INITHEAD(&rscreen->fences.blocks);
712	pipe_mutex_init(rscreen->fences.mutex);
713
714	return &rscreen->screen;
715}
716