Home | History | Annotate | Download | only in radeonsi
      1 /*
      2  * Copyright 2010 Jerome Glisse <glisse (at) 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  */
     56 static 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 
    128 out:
    129 	pipe_mutex_unlock(rscreen->fences.mutex);
    130 	return fence;
    131 }
    132 
    133 
    134 void 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 
    160 static void r600_flush_from_st(struct pipe_context *ctx,
    161 			       struct pipe_fence_handle **fence)
    162 {
    163 	radeonsi_flush(ctx, fence, 0);
    164 }
    165 
    166 static void r600_flush_from_winsys(void *ctx, unsigned flags)
    167 {
    168 	radeonsi_flush((struct pipe_context*)ctx, NULL, flags);
    169 }
    170 
    171 static 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 
    190 static 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  */
    266 static const char* r600_get_vendor(struct pipe_screen* pscreen)
    267 {
    268 	return "X.Org";
    269 }
    270 
    271 static 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 
    281 static 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 
    288 static 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 
    392 static 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 
    417 static 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 
    475 static 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 
    494 static 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 
    518 static 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 
    536 static 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 
    545 static 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 
    589 static 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 
    635 static 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 
    648 static 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 
    659 struct 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