r600_pipe.c revision ec848d2730afcc8a0c81bf74b7bb27936407c305
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_update_num_contexts(struct r600_screen *rscreen, int diff)
156{
157	pipe_mutex_lock(rscreen->mutex_num_contexts);
158	if (diff > 0) {
159		rscreen->num_contexts++;
160
161		if (rscreen->num_contexts > 1)
162			util_slab_set_thread_safety(&rscreen->pool_buffers,
163						    UTIL_SLAB_MULTITHREADED);
164	} else {
165		rscreen->num_contexts--;
166
167		if (rscreen->num_contexts <= 1)
168			util_slab_set_thread_safety(&rscreen->pool_buffers,
169						    UTIL_SLAB_SINGLETHREADED);
170	}
171	pipe_mutex_unlock(rscreen->mutex_num_contexts);
172}
173
174static void r600_destroy_context(struct pipe_context *context)
175{
176	struct r600_context *rctx = (struct r600_context *)context;
177
178	if (rctx->dummy_pixel_shader) {
179		rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
180	}
181	if (rctx->custom_dsa_flush) {
182		rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
183	}
184	util_unreference_framebuffer_state(&rctx->framebuffer);
185
186	r600_context_fini(rctx);
187
188	if (rctx->blitter) {
189		util_blitter_destroy(rctx->blitter);
190	}
191	for (int i = 0; i < R600_PIPE_NSTATES; i++) {
192		free(rctx->states[i]);
193	}
194
195	if (rctx->uploader) {
196		u_upload_destroy(rctx->uploader);
197	}
198	util_slab_destroy(&rctx->pool_transfers);
199
200	r600_update_num_contexts(rctx->screen, -1);
201
202	r600_release_command_buffer(&rctx->start_cs_cmd);
203
204	if (rctx->cs) {
205		rctx->ws->cs_destroy(rctx->cs);
206	}
207
208	FREE(rctx->range);
209	FREE(rctx);
210}
211
212static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
213{
214	struct r600_context *rctx = CALLOC_STRUCT(r600_context);
215	struct r600_screen* rscreen = (struct r600_screen *)screen;
216
217	if (rctx == NULL)
218		return NULL;
219
220	util_slab_create(&rctx->pool_transfers,
221			 sizeof(struct pipe_transfer), 64,
222			 UTIL_SLAB_SINGLETHREADED);
223
224	r600_update_num_contexts(rscreen, 1);
225
226	rctx->context.screen = screen;
227	rctx->context.priv = priv;
228	rctx->context.destroy = r600_destroy_context;
229	rctx->context.flush = r600_flush_from_st;
230
231	/* Easy accessing of screen/winsys. */
232	rctx->screen = rscreen;
233	rctx->ws = rscreen->ws;
234	rctx->family = rscreen->family;
235	rctx->chip_class = rscreen->chip_class;
236
237	LIST_INITHEAD(&rctx->dirty_states);
238	LIST_INITHEAD(&rctx->active_timer_queries);
239	LIST_INITHEAD(&rctx->active_nontimer_queries);
240	LIST_INITHEAD(&rctx->dirty);
241	LIST_INITHEAD(&rctx->resource_dirty);
242	LIST_INITHEAD(&rctx->enable_list);
243
244	rctx->range = CALLOC(NUM_RANGES, sizeof(struct r600_range));
245	if (!rctx->range)
246		goto fail;
247
248	r600_init_blit_functions(rctx);
249	r600_init_query_functions(rctx);
250	r600_init_context_resource_functions(rctx);
251	r600_init_surface_functions(rctx);
252	rctx->context.draw_vbo = r600_draw_vbo;
253
254	rctx->context.create_video_decoder = vl_create_decoder;
255	rctx->context.create_video_buffer = vl_video_buffer_create;
256
257	r600_init_common_atoms(rctx);
258
259	switch (rctx->chip_class) {
260	case R600:
261	case R700:
262		r600_init_state_functions(rctx);
263		r600_init_atom_start_cs(rctx);
264		if (r600_context_init(rctx))
265			goto fail;
266		rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
267		rctx->has_vertex_cache = !(rctx->family == CHIP_RV610 ||
268					   rctx->family == CHIP_RV620 ||
269					   rctx->family == CHIP_RS780 ||
270					   rctx->family == CHIP_RS880 ||
271					   rctx->family == CHIP_RV710);
272		break;
273	case EVERGREEN:
274	case CAYMAN:
275		evergreen_init_state_functions(rctx);
276		evergreen_init_atom_start_cs(rctx);
277		if (evergreen_context_init(rctx))
278			goto fail;
279		rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
280		rctx->has_vertex_cache = !(rctx->family == CHIP_CEDAR ||
281					   rctx->family == CHIP_PALM ||
282					   rctx->family == CHIP_SUMO ||
283					   rctx->family == CHIP_SUMO2 ||
284					   rctx->family == CHIP_CAICOS ||
285					   rctx->family == CHIP_CAYMAN ||
286					   rctx->family == CHIP_ARUBA);
287		break;
288	default:
289		R600_ERR("Unsupported chip class %d.\n", rctx->chip_class);
290		goto fail;
291	}
292
293	rctx->cs = rctx->ws->cs_create(rctx->ws);
294	rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
295	r600_emit_atom(rctx, &rctx->start_cs_cmd.atom);
296
297        rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
298                                         PIPE_BIND_INDEX_BUFFER |
299                                         PIPE_BIND_CONSTANT_BUFFER);
300        if (!rctx->uploader)
301                goto fail;
302
303	rctx->blitter = util_blitter_create(&rctx->context);
304	if (rctx->blitter == NULL)
305		goto fail;
306
307	r600_get_backend_mask(rctx); /* this emits commands and must be last */
308
309	if (rctx->chip_class == R600)
310		r600_set_max_scissor(rctx);
311
312	rctx->dummy_pixel_shader =
313		util_make_fragment_cloneinput_shader(&rctx->context, 0,
314						     TGSI_SEMANTIC_GENERIC,
315						     TGSI_INTERPOLATE_CONSTANT);
316	rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
317
318	return &rctx->context;
319
320fail:
321	r600_destroy_context(&rctx->context);
322	return NULL;
323}
324
325/*
326 * pipe_screen
327 */
328static const char* r600_get_vendor(struct pipe_screen* pscreen)
329{
330	return "X.Org";
331}
332
333static const char *r600_get_family_name(enum radeon_family family)
334{
335	switch(family) {
336	case CHIP_R600: return "AMD R600";
337	case CHIP_RV610: return "AMD RV610";
338	case CHIP_RV630: return "AMD RV630";
339	case CHIP_RV670: return "AMD RV670";
340	case CHIP_RV620: return "AMD RV620";
341	case CHIP_RV635: return "AMD RV635";
342	case CHIP_RS780: return "AMD RS780";
343	case CHIP_RS880: return "AMD RS880";
344	case CHIP_RV770: return "AMD RV770";
345	case CHIP_RV730: return "AMD RV730";
346	case CHIP_RV710: return "AMD RV710";
347	case CHIP_RV740: return "AMD RV740";
348	case CHIP_CEDAR: return "AMD CEDAR";
349	case CHIP_REDWOOD: return "AMD REDWOOD";
350	case CHIP_JUNIPER: return "AMD JUNIPER";
351	case CHIP_CYPRESS: return "AMD CYPRESS";
352	case CHIP_HEMLOCK: return "AMD HEMLOCK";
353	case CHIP_PALM: return "AMD PALM";
354	case CHIP_SUMO: return "AMD SUMO";
355	case CHIP_SUMO2: return "AMD SUMO2";
356	case CHIP_BARTS: return "AMD BARTS";
357	case CHIP_TURKS: return "AMD TURKS";
358	case CHIP_CAICOS: return "AMD CAICOS";
359	case CHIP_CAYMAN: return "AMD CAYMAN";
360	case CHIP_ARUBA: return "AMD ARUBA";
361	default: return "AMD unknown";
362	}
363}
364
365static const char* r600_get_name(struct pipe_screen* pscreen)
366{
367	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
368
369	return r600_get_family_name(rscreen->family);
370}
371
372static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
373{
374	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
375	enum radeon_family family = rscreen->family;
376
377	switch (param) {
378	/* Supported features (boolean caps). */
379	case PIPE_CAP_NPOT_TEXTURES:
380	case PIPE_CAP_TWO_SIDED_STENCIL:
381	case PIPE_CAP_ANISOTROPIC_FILTER:
382	case PIPE_CAP_POINT_SPRITE:
383	case PIPE_CAP_OCCLUSION_QUERY:
384	case PIPE_CAP_TEXTURE_SHADOW_MAP:
385	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
386	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
387	case PIPE_CAP_TEXTURE_SWIZZLE:
388	case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
389	case PIPE_CAP_DEPTH_CLIP_DISABLE:
390	case PIPE_CAP_SHADER_STENCIL_EXPORT:
391	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
392	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
393	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
394	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
395	case PIPE_CAP_SM3:
396	case PIPE_CAP_SEAMLESS_CUBE_MAP:
397	case PIPE_CAP_PRIMITIVE_RESTART:
398	case PIPE_CAP_CONDITIONAL_RENDER:
399	case PIPE_CAP_TEXTURE_BARRIER:
400	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
401	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
402	case PIPE_CAP_TGSI_INSTANCEID:
403	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
404	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
405	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
406	case PIPE_CAP_USER_INDEX_BUFFERS:
407	case PIPE_CAP_USER_CONSTANT_BUFFERS:
408		return 1;
409
410	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
411		return 256;
412
413	case PIPE_CAP_GLSL_FEATURE_LEVEL:
414		return rscreen->glsl_feature_level;
415
416	/* Supported except the original R600. */
417	case PIPE_CAP_INDEP_BLEND_ENABLE:
418	case PIPE_CAP_INDEP_BLEND_FUNC:
419		/* R600 doesn't support per-MRT blends */
420		return family == CHIP_R600 ? 0 : 1;
421
422	/* Supported on Evergreen. */
423	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
424		return family >= CHIP_CEDAR ? 1 : 0;
425
426	/* Unsupported features. */
427	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
428	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
429	case PIPE_CAP_SCALED_RESOLVE:
430	case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
431	case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
432	case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
433	case PIPE_CAP_VERTEX_COLOR_CLAMPED:
434	case PIPE_CAP_USER_VERTEX_BUFFERS:
435	case PIPE_CAP_COMPUTE:
436		return 0;
437
438	/* Stream output. */
439	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
440		return rscreen->info.r600_has_streamout ? 4 : 0;
441	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
442		return rscreen->info.r600_has_streamout ? 1 : 0;
443	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
444	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
445		return 16*4;
446
447	/* Texturing. */
448	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
449	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
450	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
451		if (family >= CHIP_CEDAR)
452			return 15;
453		else
454			return 14;
455	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
456		return rscreen->info.drm_minor >= 9 ?
457			(family >= CHIP_CEDAR ? 16384 : 8192) : 0;
458	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
459		return 32;
460
461	/* Render targets. */
462	case PIPE_CAP_MAX_RENDER_TARGETS:
463		/* XXX some r6xx are buggy and can only do 4 */
464		return 8;
465
466	/* Timer queries, present when the clock frequency is non zero. */
467	case PIPE_CAP_TIMER_QUERY:
468		return rscreen->info.r600_clock_crystal_freq != 0;
469
470	case PIPE_CAP_MIN_TEXEL_OFFSET:
471		return -8;
472
473	case PIPE_CAP_MAX_TEXEL_OFFSET:
474		return 7;
475
476	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
477		return (family < CHIP_RV770) ?  1 : 0;
478	}
479	return 0;
480}
481
482static float r600_get_paramf(struct pipe_screen* pscreen,
483			     enum pipe_capf param)
484{
485	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
486	enum radeon_family family = rscreen->family;
487
488	switch (param) {
489	case PIPE_CAPF_MAX_LINE_WIDTH:
490	case PIPE_CAPF_MAX_LINE_WIDTH_AA:
491	case PIPE_CAPF_MAX_POINT_WIDTH:
492	case PIPE_CAPF_MAX_POINT_WIDTH_AA:
493		if (family >= CHIP_CEDAR)
494			return 16384.0f;
495		else
496			return 8192.0f;
497	case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
498		return 16.0f;
499	case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
500		return 16.0f;
501	case PIPE_CAPF_GUARD_BAND_LEFT:
502	case PIPE_CAPF_GUARD_BAND_TOP:
503	case PIPE_CAPF_GUARD_BAND_RIGHT:
504	case PIPE_CAPF_GUARD_BAND_BOTTOM:
505		return 0.0f;
506	}
507	return 0.0f;
508}
509
510static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
511{
512	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
513	switch(shader)
514	{
515	case PIPE_SHADER_FRAGMENT:
516	case PIPE_SHADER_VERTEX:
517		break;
518	case PIPE_SHADER_GEOMETRY:
519		/* XXX: support and enable geometry programs */
520		return 0;
521	default:
522		/* XXX: support tessellation on Evergreen */
523		return 0;
524	}
525
526	/* XXX: all these should be fixed, since r600 surely supports much more! */
527	switch (param) {
528	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
529	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
530	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
531	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
532		return 16384;
533	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
534		return 8; /* XXX */
535	case PIPE_SHADER_CAP_MAX_INPUTS:
536		if(shader == PIPE_SHADER_FRAGMENT)
537			return 34;
538		else
539			return 32;
540	case PIPE_SHADER_CAP_MAX_TEMPS:
541		return 256; /* Max native temporaries. */
542	case PIPE_SHADER_CAP_MAX_ADDRS:
543		/* XXX Isn't this equal to TEMPS? */
544		return 1; /* Max native address registers */
545	case PIPE_SHADER_CAP_MAX_CONSTS:
546		return R600_MAX_CONST_BUFFER_SIZE;
547	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
548		return R600_MAX_CONST_BUFFERS-1;
549	case PIPE_SHADER_CAP_MAX_PREDS:
550		return 0; /* nothing uses this */
551	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
552		return 1;
553	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
554	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
555	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
556	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
557		return 1;
558	case PIPE_SHADER_CAP_SUBROUTINES:
559		return 0;
560	case PIPE_SHADER_CAP_INTEGERS:
561		return rscreen->glsl_feature_level >= 130;
562	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
563		return 16;
564	case PIPE_SHADER_CAP_PREFERRED_IR:
565		return PIPE_SHADER_IR_TGSI;
566	}
567	return 0;
568}
569
570static int r600_get_video_param(struct pipe_screen *screen,
571				enum pipe_video_profile profile,
572				enum pipe_video_cap param)
573{
574	switch (param) {
575	case PIPE_VIDEO_CAP_SUPPORTED:
576		return vl_profile_supported(screen, profile);
577	case PIPE_VIDEO_CAP_NPOT_TEXTURES:
578		return 1;
579	case PIPE_VIDEO_CAP_MAX_WIDTH:
580	case PIPE_VIDEO_CAP_MAX_HEIGHT:
581		return vl_video_buffer_max_size(screen);
582	case PIPE_VIDEO_CAP_PREFERED_FORMAT:
583		return PIPE_FORMAT_NV12;
584	case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
585		return false;
586	case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
587		return false;
588	case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
589		return true;
590	default:
591		return 0;
592	}
593}
594
595static void r600_destroy_screen(struct pipe_screen* pscreen)
596{
597	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
598
599	if (rscreen == NULL)
600		return;
601
602	if (rscreen->fences.bo) {
603		struct r600_fence_block *entry, *tmp;
604
605		LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, &rscreen->fences.blocks, head) {
606			LIST_DEL(&entry->head);
607			FREE(entry);
608		}
609
610		rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
611		pipe_resource_reference((struct pipe_resource**)&rscreen->fences.bo, NULL);
612	}
613	pipe_mutex_destroy(rscreen->fences.mutex);
614
615	rscreen->ws->destroy(rscreen->ws);
616
617	util_slab_destroy(&rscreen->pool_buffers);
618	pipe_mutex_destroy(rscreen->mutex_num_contexts);
619	FREE(rscreen);
620}
621
622static void r600_fence_reference(struct pipe_screen *pscreen,
623                                 struct pipe_fence_handle **ptr,
624                                 struct pipe_fence_handle *fence)
625{
626	struct r600_fence **oldf = (struct r600_fence**)ptr;
627	struct r600_fence *newf = (struct r600_fence*)fence;
628
629	if (pipe_reference(&(*oldf)->reference, &newf->reference)) {
630		struct r600_screen *rscreen = (struct r600_screen *)pscreen;
631		pipe_mutex_lock(rscreen->fences.mutex);
632		pipe_resource_reference((struct pipe_resource**)&(*oldf)->sleep_bo, NULL);
633		LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool);
634		pipe_mutex_unlock(rscreen->fences.mutex);
635	}
636
637	*ptr = fence;
638}
639
640static boolean r600_fence_signalled(struct pipe_screen *pscreen,
641                                    struct pipe_fence_handle *fence)
642{
643	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
644	struct r600_fence *rfence = (struct r600_fence*)fence;
645
646	return rscreen->fences.data[rfence->index];
647}
648
649static boolean r600_fence_finish(struct pipe_screen *pscreen,
650                                 struct pipe_fence_handle *fence,
651                                 uint64_t timeout)
652{
653	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
654	struct r600_fence *rfence = (struct r600_fence*)fence;
655	int64_t start_time = 0;
656	unsigned spins = 0;
657
658	if (timeout != PIPE_TIMEOUT_INFINITE) {
659		start_time = os_time_get();
660
661		/* Convert to microseconds. */
662		timeout /= 1000;
663	}
664
665	while (rscreen->fences.data[rfence->index] == 0) {
666		/* Special-case infinite timeout - wait for the dummy BO to become idle */
667		if (timeout == PIPE_TIMEOUT_INFINITE) {
668			rscreen->ws->buffer_wait(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE);
669			break;
670		}
671
672		/* The dummy BO will be busy until the CS including the fence has completed, or
673		 * the GPU is reset. Don't bother continuing to spin when the BO is idle. */
674		if (!rscreen->ws->buffer_is_busy(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE))
675			break;
676
677		if (++spins % 256)
678			continue;
679#ifdef PIPE_OS_UNIX
680		sched_yield();
681#else
682		os_time_sleep(10);
683#endif
684		if (timeout != PIPE_TIMEOUT_INFINITE &&
685		    os_time_get() - start_time >= timeout) {
686			break;
687		}
688	}
689
690	return rscreen->fences.data[rfence->index] != 0;
691}
692
693static int r600_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
694{
695	switch ((tiling_config & 0xe) >> 1) {
696	case 0:
697		rscreen->tiling_info.num_channels = 1;
698		break;
699	case 1:
700		rscreen->tiling_info.num_channels = 2;
701		break;
702	case 2:
703		rscreen->tiling_info.num_channels = 4;
704		break;
705	case 3:
706		rscreen->tiling_info.num_channels = 8;
707		break;
708	default:
709		return -EINVAL;
710	}
711
712	switch ((tiling_config & 0x30) >> 4) {
713	case 0:
714		rscreen->tiling_info.num_banks = 4;
715		break;
716	case 1:
717		rscreen->tiling_info.num_banks = 8;
718		break;
719	default:
720		return -EINVAL;
721
722	}
723	switch ((tiling_config & 0xc0) >> 6) {
724	case 0:
725		rscreen->tiling_info.group_bytes = 256;
726		break;
727	case 1:
728		rscreen->tiling_info.group_bytes = 512;
729		break;
730	default:
731		return -EINVAL;
732	}
733	return 0;
734}
735
736static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config)
737{
738	switch (tiling_config & 0xf) {
739	case 0:
740		rscreen->tiling_info.num_channels = 1;
741		break;
742	case 1:
743		rscreen->tiling_info.num_channels = 2;
744		break;
745	case 2:
746		rscreen->tiling_info.num_channels = 4;
747		break;
748	case 3:
749		rscreen->tiling_info.num_channels = 8;
750		break;
751	default:
752		return -EINVAL;
753	}
754
755	switch ((tiling_config & 0xf0) >> 4) {
756	case 0:
757		rscreen->tiling_info.num_banks = 4;
758		break;
759	case 1:
760		rscreen->tiling_info.num_banks = 8;
761		break;
762	case 2:
763		rscreen->tiling_info.num_banks = 16;
764		break;
765	default:
766		return -EINVAL;
767	}
768
769	switch ((tiling_config & 0xf00) >> 8) {
770	case 0:
771		rscreen->tiling_info.group_bytes = 256;
772		break;
773	case 1:
774		rscreen->tiling_info.group_bytes = 512;
775		break;
776	default:
777		return -EINVAL;
778	}
779	return 0;
780}
781
782static int r600_init_tiling(struct r600_screen *rscreen)
783{
784	uint32_t tiling_config = rscreen->info.r600_tiling_config;
785
786	/* set default group bytes, overridden by tiling info ioctl */
787	if (rscreen->chip_class <= R700) {
788		rscreen->tiling_info.group_bytes = 256;
789	} else {
790		rscreen->tiling_info.group_bytes = 512;
791	}
792
793	if (!tiling_config)
794		return 0;
795
796	if (rscreen->chip_class <= R700) {
797		return r600_interpret_tiling(rscreen, tiling_config);
798	} else {
799		return evergreen_interpret_tiling(rscreen, tiling_config);
800	}
801}
802
803static unsigned radeon_family_from_device(unsigned device)
804{
805	switch (device) {
806#define CHIPSET(pciid, name, family) case pciid: return CHIP_##family;
807#include "pci_ids/r600_pci_ids.h"
808#undef CHIPSET
809	default:
810		return CHIP_UNKNOWN;
811	}
812}
813
814struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
815{
816	struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
817
818	if (rscreen == NULL) {
819		return NULL;
820	}
821
822	rscreen->ws = ws;
823	ws->query_info(ws, &rscreen->info);
824
825	rscreen->family = radeon_family_from_device(rscreen->info.pci_id);
826	if (rscreen->family == CHIP_UNKNOWN) {
827		fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
828		FREE(rscreen);
829		return NULL;
830	}
831
832	/* setup class */
833	if (rscreen->family >= CHIP_CAYMAN) {
834		rscreen->chip_class = CAYMAN;
835	} else if (rscreen->family >= CHIP_CEDAR) {
836		rscreen->chip_class = EVERGREEN;
837	} else if (rscreen->family >= CHIP_RV770) {
838		rscreen->chip_class = R700;
839	} else {
840		rscreen->chip_class = R600;
841	}
842
843	/* XXX streamout is said to be broken on r700 and cayman */
844	if ((rscreen->chip_class == R700 ||
845	     rscreen->chip_class == CAYMAN) &&
846	    !debug_get_bool_option("R600_STREAMOUT", FALSE)) {
847		rscreen->info.r600_has_streamout = false;
848	}
849
850	if (r600_init_tiling(rscreen)) {
851		FREE(rscreen);
852		return NULL;
853	}
854
855	rscreen->screen.destroy = r600_destroy_screen;
856	rscreen->screen.get_name = r600_get_name;
857	rscreen->screen.get_vendor = r600_get_vendor;
858	rscreen->screen.get_param = r600_get_param;
859	rscreen->screen.get_shader_param = r600_get_shader_param;
860	rscreen->screen.get_paramf = r600_get_paramf;
861	rscreen->screen.get_video_param = r600_get_video_param;
862	if (rscreen->chip_class >= EVERGREEN) {
863		rscreen->screen.is_format_supported = evergreen_is_format_supported;
864	} else {
865		rscreen->screen.is_format_supported = r600_is_format_supported;
866	}
867	rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
868	rscreen->screen.context_create = r600_create_context;
869	rscreen->screen.fence_reference = r600_fence_reference;
870	rscreen->screen.fence_signalled = r600_fence_signalled;
871	rscreen->screen.fence_finish = r600_fence_finish;
872	r600_init_screen_resource_functions(&rscreen->screen);
873
874	util_format_s3tc_init();
875
876	util_slab_create(&rscreen->pool_buffers,
877			 sizeof(struct r600_resource), 64,
878			 UTIL_SLAB_SINGLETHREADED);
879
880	pipe_mutex_init(rscreen->mutex_num_contexts);
881
882	rscreen->fences.bo = NULL;
883	rscreen->fences.data = NULL;
884	rscreen->fences.next_index = 0;
885	LIST_INITHEAD(&rscreen->fences.pool);
886	LIST_INITHEAD(&rscreen->fences.blocks);
887	pipe_mutex_init(rscreen->fences.mutex);
888
889	rscreen->use_surface_alloc = debug_get_bool_option("R600_SURF", TRUE);
890	rscreen->glsl_feature_level = debug_get_bool_option("R600_GLSL130", TRUE) ? 130 : 120;
891
892	return &rscreen->screen;
893}
894