13464ebd5Sriastradh/*
23464ebd5Sriastradh * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
33464ebd5Sriastradh *
43464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
53464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"),
63464ebd5Sriastradh * to deal in the Software without restriction, including without limitation
73464ebd5Sriastradh * on the rights to use, copy, modify, merge, publish, distribute, sub
83464ebd5Sriastradh * license, and/or sell copies of the Software, and to permit persons to whom
93464ebd5Sriastradh * the Software is furnished to do so, subject to the following conditions:
103464ebd5Sriastradh *
113464ebd5Sriastradh * The above copyright notice and this permission notice (including the next
123464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the
133464ebd5Sriastradh * Software.
143464ebd5Sriastradh *
153464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
163464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
173464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
183464ebd5Sriastradh * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
193464ebd5Sriastradh * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
203464ebd5Sriastradh * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
213464ebd5Sriastradh * USE OR OTHER DEALINGS IN THE SOFTWARE.
223464ebd5Sriastradh */
233464ebd5Sriastradh#include "r600_pipe.h"
24af69d88dSmrg#include "r600_public.h"
25af69d88dSmrg#include "r600_isa.h"
26af69d88dSmrg#include "evergreen_compute.h"
27af69d88dSmrg#include "r600d.h"
283464ebd5Sriastradh
29af69d88dSmrg#include "sb/sb_public.h"
303464ebd5Sriastradh
31af69d88dSmrg#include <errno.h>
32af69d88dSmrg#include "pipe/p_shader_tokens.h"
33af69d88dSmrg#include "util/u_debug.h"
34af69d88dSmrg#include "util/u_memory.h"
3501e04c3fSmrg#include "util/u_screen.h"
36af69d88dSmrg#include "util/u_simple_shaders.h"
37af69d88dSmrg#include "util/u_upload_mgr.h"
38af69d88dSmrg#include "util/u_math.h"
39af69d88dSmrg#include "vl/vl_decoder.h"
40af69d88dSmrg#include "vl/vl_video_buffer.h"
4101e04c3fSmrg#include "radeon_video.h"
4201e04c3fSmrg#include "radeon_uvd.h"
4301e04c3fSmrg#include "util/os_time.h"
443464ebd5Sriastradh
45af69d88dSmrgstatic const struct debug_named_value r600_debug_options[] = {
46af69d88dSmrg	/* features */
47af69d88dSmrg	{ "nocpdma", DBG_NO_CP_DMA, "Disable CP DMA" },
483464ebd5Sriastradh
49af69d88dSmrg	/* shader backend */
50af69d88dSmrg	{ "nosb", DBG_NO_SB, "Disable sb backend for graphics shaders" },
51af69d88dSmrg	{ "sbcl", DBG_SB_CS, "Enable sb backend for compute shaders" },
52af69d88dSmrg	{ "sbdry", DBG_SB_DRY_RUN, "Don't use optimized bytecode (just print the dumps)" },
53af69d88dSmrg	{ "sbstat", DBG_SB_STAT, "Print optimization statistics for shaders" },
54af69d88dSmrg	{ "sbdump", DBG_SB_DUMP, "Print IR dumps after some optimization passes" },
55af69d88dSmrg	{ "sbnofallback", DBG_SB_NO_FALLBACK, "Abort on errors instead of fallback" },
56af69d88dSmrg	{ "sbdisasm", DBG_SB_DISASM, "Use sb disassembler for shader dumps" },
57af69d88dSmrg	{ "sbsafemath", DBG_SB_SAFEMATH, "Disable unsafe math optimizations" },
587ec681f3Smrg        { "nirsb", DBG_NIR_SB, "Enable NIR with SB optimizer"},
593464ebd5Sriastradh
60af69d88dSmrg	DEBUG_NAMED_VALUE_END /* must be last */
61af69d88dSmrg};
623464ebd5Sriastradh
63af69d88dSmrg/*
64af69d88dSmrg * pipe_context
65af69d88dSmrg */
663464ebd5Sriastradh
673464ebd5Sriastradhstatic void r600_destroy_context(struct pipe_context *context)
683464ebd5Sriastradh{
69af69d88dSmrg	struct r600_context *rctx = (struct r600_context *)context;
7001e04c3fSmrg	unsigned sh, i;
713464ebd5Sriastradh
72af69d88dSmrg	r600_isa_destroy(rctx->isa);
733464ebd5Sriastradh
74af69d88dSmrg	r600_sb_context_destroy(rctx->sb_context);
753464ebd5Sriastradh
7601e04c3fSmrg	for (sh = 0; sh < (rctx->b.chip_class < EVERGREEN ? R600_NUM_HW_STAGES : EG_NUM_HW_STAGES); sh++) {
7701e04c3fSmrg		r600_resource_reference(&rctx->scratch_buffers[sh].buffer, NULL);
7801e04c3fSmrg	}
7901e04c3fSmrg	r600_resource_reference(&rctx->dummy_cmask, NULL);
8001e04c3fSmrg	r600_resource_reference(&rctx->dummy_fmask, NULL);
8101e04c3fSmrg
8201e04c3fSmrg	if (rctx->append_fence)
8301e04c3fSmrg		pipe_resource_reference((struct pipe_resource**)&rctx->append_fence, NULL);
8401e04c3fSmrg	for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
857ec681f3Smrg		rctx->b.b.set_constant_buffer(&rctx->b.b, sh, R600_BUFFER_INFO_CONST_BUFFER, false, NULL);
8601e04c3fSmrg		free(rctx->driver_consts[sh].constants);
8701e04c3fSmrg	}
8801e04c3fSmrg
8901e04c3fSmrg	if (rctx->fixed_func_tcs_shader)
9001e04c3fSmrg		rctx->b.b.delete_tcs_state(&rctx->b.b, rctx->fixed_func_tcs_shader);
913464ebd5Sriastradh
92af69d88dSmrg	if (rctx->dummy_pixel_shader) {
93af69d88dSmrg		rctx->b.b.delete_fs_state(&rctx->b.b, rctx->dummy_pixel_shader);
943464ebd5Sriastradh	}
95af69d88dSmrg	if (rctx->custom_dsa_flush) {
96af69d88dSmrg		rctx->b.b.delete_depth_stencil_alpha_state(&rctx->b.b, rctx->custom_dsa_flush);
97af69d88dSmrg	}
98af69d88dSmrg	if (rctx->custom_blend_resolve) {
99af69d88dSmrg		rctx->b.b.delete_blend_state(&rctx->b.b, rctx->custom_blend_resolve);
100af69d88dSmrg	}
101af69d88dSmrg	if (rctx->custom_blend_decompress) {
102af69d88dSmrg		rctx->b.b.delete_blend_state(&rctx->b.b, rctx->custom_blend_decompress);
103af69d88dSmrg	}
104af69d88dSmrg	if (rctx->custom_blend_fastclear) {
105af69d88dSmrg		rctx->b.b.delete_blend_state(&rctx->b.b, rctx->custom_blend_fastclear);
106af69d88dSmrg	}
107af69d88dSmrg	util_unreference_framebuffer_state(&rctx->framebuffer.state);
1083464ebd5Sriastradh
10901e04c3fSmrg	if (rctx->gs_rings.gsvs_ring.buffer)
11001e04c3fSmrg		pipe_resource_reference(&rctx->gs_rings.gsvs_ring.buffer, NULL);
11101e04c3fSmrg
11201e04c3fSmrg	if (rctx->gs_rings.esgs_ring.buffer)
11301e04c3fSmrg		pipe_resource_reference(&rctx->gs_rings.esgs_ring.buffer, NULL);
11401e04c3fSmrg
11501e04c3fSmrg	for (sh = 0; sh < PIPE_SHADER_TYPES; ++sh)
11601e04c3fSmrg		for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; ++i)
1177ec681f3Smrg			rctx->b.b.set_constant_buffer(context, sh, i, false, NULL);
11801e04c3fSmrg
119af69d88dSmrg	if (rctx->blitter) {
120af69d88dSmrg		util_blitter_destroy(rctx->blitter);
121af69d88dSmrg	}
1227ec681f3Smrg	u_suballocator_destroy(&rctx->allocator_fetch_shader);
1233464ebd5Sriastradh
124af69d88dSmrg	r600_release_command_buffer(&rctx->start_cs_cmd);
125af69d88dSmrg
126af69d88dSmrg	FREE(rctx->start_compute_cs_cmd.buf);
1273464ebd5Sriastradh
128af69d88dSmrg	r600_common_context_cleanup(&rctx->b);
12901e04c3fSmrg
13001e04c3fSmrg	r600_resource_reference(&rctx->trace_buf, NULL);
13101e04c3fSmrg	r600_resource_reference(&rctx->last_trace_buf, NULL);
13201e04c3fSmrg	radeon_clear_saved_cs(&rctx->last_gfx);
13301e04c3fSmrg
1343464ebd5Sriastradh	FREE(rctx);
1353464ebd5Sriastradh}
1363464ebd5Sriastradh
13701e04c3fSmrgstatic struct pipe_context *r600_create_context(struct pipe_screen *screen,
13801e04c3fSmrg                                                void *priv, unsigned flags)
1393464ebd5Sriastradh{
140af69d88dSmrg	struct r600_context *rctx = CALLOC_STRUCT(r600_context);
1413464ebd5Sriastradh	struct r600_screen* rscreen = (struct r600_screen *)screen;
142af69d88dSmrg	struct radeon_winsys *ws = rscreen->b.ws;
1433464ebd5Sriastradh
14401e04c3fSmrg	if (!rctx)
1453464ebd5Sriastradh		return NULL;
1463464ebd5Sriastradh
147af69d88dSmrg	rctx->b.b.screen = screen;
14801e04c3fSmrg	assert(!priv);
14901e04c3fSmrg	rctx->b.b.priv = NULL; /* for threaded_context_unwrap_sync */
150af69d88dSmrg	rctx->b.b.destroy = r600_destroy_context;
15101e04c3fSmrg	rctx->b.set_atom_dirty = (void *)r600_set_atom_dirty;
1523464ebd5Sriastradh
15301e04c3fSmrg	if (!r600_common_context_init(&rctx->b, &rscreen->b, flags))
154af69d88dSmrg		goto fail;
1553464ebd5Sriastradh
1563464ebd5Sriastradh	rctx->screen = rscreen;
1577ec681f3Smrg	list_inithead(&rctx->texture_buffers);
1583464ebd5Sriastradh
1593464ebd5Sriastradh	r600_init_blit_functions(rctx);
1603464ebd5Sriastradh
1617ec681f3Smrg	if (rscreen->b.info.has_video_hw.uvd_decode) {
162af69d88dSmrg		rctx->b.b.create_video_codec = r600_uvd_create_decoder;
163af69d88dSmrg		rctx->b.b.create_video_buffer = r600_video_buffer_create;
164af69d88dSmrg	} else {
165af69d88dSmrg		rctx->b.b.create_video_codec = vl_create_decoder;
166af69d88dSmrg		rctx->b.b.create_video_buffer = vl_video_buffer_create;
1673464ebd5Sriastradh	}
1683464ebd5Sriastradh
16901e04c3fSmrg	if (getenv("R600_TRACE"))
17001e04c3fSmrg		rctx->is_debug = true;
171af69d88dSmrg	r600_init_common_state_functions(rctx);
1723464ebd5Sriastradh
173af69d88dSmrg	switch (rctx->b.chip_class) {
174af69d88dSmrg	case R600:
175af69d88dSmrg	case R700:
176af69d88dSmrg		r600_init_state_functions(rctx);
177af69d88dSmrg		r600_init_atom_start_cs(rctx);
1783464ebd5Sriastradh		rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
179af69d88dSmrg		rctx->custom_blend_resolve = rctx->b.chip_class == R700 ? r700_create_resolve_blend(rctx)
180af69d88dSmrg								      : r600_create_resolve_blend(rctx);
181af69d88dSmrg		rctx->custom_blend_decompress = r600_create_decompress_blend(rctx);
182af69d88dSmrg		rctx->has_vertex_cache = !(rctx->b.family == CHIP_RV610 ||
183af69d88dSmrg					   rctx->b.family == CHIP_RV620 ||
184af69d88dSmrg					   rctx->b.family == CHIP_RS780 ||
185af69d88dSmrg					   rctx->b.family == CHIP_RS880 ||
186af69d88dSmrg					   rctx->b.family == CHIP_RV710);
187af69d88dSmrg		break;
188af69d88dSmrg	case EVERGREEN:
189af69d88dSmrg	case CAYMAN:
190af69d88dSmrg		evergreen_init_state_functions(rctx);
191af69d88dSmrg		evergreen_init_atom_start_cs(rctx);
192af69d88dSmrg		evergreen_init_atom_start_compute_cs(rctx);
1933464ebd5Sriastradh		rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
194af69d88dSmrg		rctx->custom_blend_resolve = evergreen_create_resolve_blend(rctx);
195af69d88dSmrg		rctx->custom_blend_decompress = evergreen_create_decompress_blend(rctx);
196af69d88dSmrg		rctx->custom_blend_fastclear = evergreen_create_fastclear_blend(rctx);
197af69d88dSmrg		rctx->has_vertex_cache = !(rctx->b.family == CHIP_CEDAR ||
198af69d88dSmrg					   rctx->b.family == CHIP_PALM ||
199af69d88dSmrg					   rctx->b.family == CHIP_SUMO ||
200af69d88dSmrg					   rctx->b.family == CHIP_SUMO2 ||
201af69d88dSmrg					   rctx->b.family == CHIP_CAICOS ||
202af69d88dSmrg					   rctx->b.family == CHIP_CAYMAN ||
203af69d88dSmrg					   rctx->b.family == CHIP_ARUBA);
20401e04c3fSmrg
20501e04c3fSmrg		rctx->append_fence = pipe_buffer_create(rctx->b.b.screen, PIPE_BIND_CUSTOM,
20601e04c3fSmrg							 PIPE_USAGE_DEFAULT, 32);
207af69d88dSmrg		break;
208af69d88dSmrg	default:
209af69d88dSmrg		R600_ERR("Unsupported chip class %d.\n", rctx->b.chip_class);
210af69d88dSmrg		goto fail;
211af69d88dSmrg	}
2123464ebd5Sriastradh
2137ec681f3Smrg	ws->cs_create(&rctx->b.gfx.cs, rctx->b.ctx, RING_GFX,
2147ec681f3Smrg                      r600_context_gfx_flush, rctx, false);
21501e04c3fSmrg	rctx->b.gfx.flush = r600_context_gfx_flush;
216af69d88dSmrg
2177ec681f3Smrg	u_suballocator_init(&rctx->allocator_fetch_shader, &rctx->b.b, 64 * 1024,
2187ec681f3Smrg                            0, PIPE_USAGE_DEFAULT, 0, FALSE);
219af69d88dSmrg
220af69d88dSmrg	rctx->isa = calloc(1, sizeof(struct r600_isa));
221af69d88dSmrg	if (!rctx->isa || r600_isa_init(rctx, rctx->isa))
222af69d88dSmrg		goto fail;
223af69d88dSmrg
22401e04c3fSmrg	if (rscreen->b.debug_flags & DBG_FORCE_DMA)
22501e04c3fSmrg		rctx->b.b.resource_copy_region = rctx->b.dma_copy;
22601e04c3fSmrg
227af69d88dSmrg	rctx->blitter = util_blitter_create(&rctx->b.b);
228af69d88dSmrg	if (rctx->blitter == NULL)
229af69d88dSmrg		goto fail;
230af69d88dSmrg	util_blitter_set_texture_multisample(rctx->blitter, rscreen->has_msaa);
231af69d88dSmrg	rctx->blitter->draw_rectangle = r600_draw_rectangle;
232af69d88dSmrg
233af69d88dSmrg	r600_begin_new_cs(rctx);
234af69d88dSmrg
235af69d88dSmrg	rctx->dummy_pixel_shader =
236af69d88dSmrg		util_make_fragment_cloneinput_shader(&rctx->b.b, 0,
237af69d88dSmrg						     TGSI_SEMANTIC_GENERIC,
238af69d88dSmrg						     TGSI_INTERPOLATE_CONSTANT);
239af69d88dSmrg	rctx->b.b.bind_fs_state(&rctx->b.b, rctx->dummy_pixel_shader);
240af69d88dSmrg
241af69d88dSmrg	return &rctx->b.b;
242af69d88dSmrg
243af69d88dSmrgfail:
244af69d88dSmrg	r600_destroy_context(&rctx->b.b);
245af69d88dSmrg	return NULL;
2463464ebd5Sriastradh}
2473464ebd5Sriastradh
2487ec681f3Smrgstatic bool is_nir_enabled(struct r600_common_screen *screen) {
2497ec681f3Smrg   return ((screen->debug_flags & DBG_NIR_PREFERRED) &&
2507ec681f3Smrg       screen->family >= CHIP_CEDAR);
2517ec681f3Smrg}
2527ec681f3Smrg
2533464ebd5Sriastradh/*
2543464ebd5Sriastradh * pipe_screen
2553464ebd5Sriastradh */
2563464ebd5Sriastradh
2573464ebd5Sriastradhstatic int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
2583464ebd5Sriastradh{
2593464ebd5Sriastradh	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
260af69d88dSmrg	enum radeon_family family = rscreen->b.family;
2613464ebd5Sriastradh
2623464ebd5Sriastradh	switch (param) {
2633464ebd5Sriastradh	/* Supported features (boolean caps). */
2643464ebd5Sriastradh	case PIPE_CAP_NPOT_TEXTURES:
265af69d88dSmrg	case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
26601e04c3fSmrg	case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
2673464ebd5Sriastradh	case PIPE_CAP_ANISOTROPIC_FILTER:
2683464ebd5Sriastradh	case PIPE_CAP_POINT_SPRITE:
2693464ebd5Sriastradh	case PIPE_CAP_OCCLUSION_QUERY:
2703464ebd5Sriastradh	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
27101e04c3fSmrg	case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
2723464ebd5Sriastradh	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
2733464ebd5Sriastradh	case PIPE_CAP_TEXTURE_SWIZZLE:
274af69d88dSmrg	case PIPE_CAP_DEPTH_CLIP_DISABLE:
27501e04c3fSmrg	case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
2763464ebd5Sriastradh	case PIPE_CAP_SHADER_STENCIL_EXPORT:
2773464ebd5Sriastradh	case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
2783464ebd5Sriastradh	case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
2793464ebd5Sriastradh	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
2803464ebd5Sriastradh	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
2817ec681f3Smrg	case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
2827ec681f3Smrg	case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
2837ec681f3Smrg	case PIPE_CAP_VERTEX_SHADER_SATURATE:
2843464ebd5Sriastradh	case PIPE_CAP_SEAMLESS_CUBE_MAP:
285af69d88dSmrg	case PIPE_CAP_PRIMITIVE_RESTART:
2867ec681f3Smrg	case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
287af69d88dSmrg	case PIPE_CAP_CONDITIONAL_RENDER:
288af69d88dSmrg	case PIPE_CAP_TEXTURE_BARRIER:
289af69d88dSmrg	case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
290af69d88dSmrg	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
291af69d88dSmrg	case PIPE_CAP_TGSI_INSTANCEID:
292af69d88dSmrg	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
293af69d88dSmrg	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
294af69d88dSmrg	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
295af69d88dSmrg	case PIPE_CAP_START_INSTANCE:
296af69d88dSmrg	case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
297af69d88dSmrg	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
29801e04c3fSmrg	case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
299af69d88dSmrg	case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
300af69d88dSmrg	case PIPE_CAP_TEXTURE_MULTISAMPLE:
301af69d88dSmrg	case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
302af69d88dSmrg	case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
30301e04c3fSmrg	case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
30401e04c3fSmrg	case PIPE_CAP_SAMPLE_SHADING:
30501e04c3fSmrg	case PIPE_CAP_CLIP_HALFZ:
30601e04c3fSmrg	case PIPE_CAP_POLYGON_OFFSET_CLAMP:
30701e04c3fSmrg	case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
30801e04c3fSmrg	case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
30901e04c3fSmrg	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
31001e04c3fSmrg	case PIPE_CAP_TGSI_TXQS:
31101e04c3fSmrg	case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
31201e04c3fSmrg	case PIPE_CAP_INVALIDATE_BUFFER:
31301e04c3fSmrg	case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
31401e04c3fSmrg	case PIPE_CAP_QUERY_MEMORY_INFO:
31501e04c3fSmrg	case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
31601e04c3fSmrg	case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
31701e04c3fSmrg	case PIPE_CAP_CLEAR_TEXTURE:
31801e04c3fSmrg	case PIPE_CAP_TGSI_MUL_ZERO_WINS:
31901e04c3fSmrg	case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
32001e04c3fSmrg	case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
32101e04c3fSmrg	case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
3227ec681f3Smrg        case PIPE_CAP_NIR_ATOMICS_AS_DEREF:
323af69d88dSmrg		return 1;
324af69d88dSmrg
3257ec681f3Smrg	case PIPE_CAP_SHAREABLE_SHADERS:
3267ec681f3Smrg		return 0;
3277ec681f3Smrg
32801e04c3fSmrg	case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
32901e04c3fSmrg		/* Optimal number for good TexSubImage performance on Polaris10. */
33001e04c3fSmrg		return 64 * 1024 * 1024;
33101e04c3fSmrg
33201e04c3fSmrg	case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
3337ec681f3Smrg		return rscreen->b.info.drm_minor >= 43;
33401e04c3fSmrg
33501e04c3fSmrg	case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
33601e04c3fSmrg		return !R600_BIG_ENDIAN && rscreen->b.info.has_userptr;
33701e04c3fSmrg
338af69d88dSmrg	case PIPE_CAP_COMPUTE:
339af69d88dSmrg		return rscreen->b.chip_class > R700;
340af69d88dSmrg
341af69d88dSmrg	case PIPE_CAP_TGSI_TEXCOORD:
3427ec681f3Smrg		return 1;
343af69d88dSmrg
3447ec681f3Smrg	case PIPE_CAP_NIR_IMAGES_AS_DEREF:
345af69d88dSmrg	case PIPE_CAP_FAKE_SW_MSAA:
346af69d88dSmrg		return 0;
347af69d88dSmrg
348af69d88dSmrg	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
34901e04c3fSmrg		return MIN2(rscreen->b.info.max_alloc_size, INT_MAX);
350af69d88dSmrg
351af69d88dSmrg        case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
352af69d88dSmrg                return R600_MAP_BUFFER_ALIGNMENT;
353af69d88dSmrg
354af69d88dSmrg	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
355af69d88dSmrg		return 256;
356af69d88dSmrg
357af69d88dSmrg	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
3587ec681f3Smrg		return 4;
3593464ebd5Sriastradh
360af69d88dSmrg	case PIPE_CAP_GLSL_FEATURE_LEVEL:
361af69d88dSmrg		if (family >= CHIP_CEDAR)
3627ec681f3Smrg		   return is_nir_enabled(&rscreen->b) ? 450 : 430;
363af69d88dSmrg		/* pre-evergreen geom shaders need newer kernel */
364af69d88dSmrg		if (rscreen->b.info.drm_minor >= 37)
365af69d88dSmrg		   return 330;
366af69d88dSmrg		return 140;
367af69d88dSmrg
36801e04c3fSmrg	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
36901e04c3fSmrg		return 140;
37001e04c3fSmrg
3713464ebd5Sriastradh	/* Supported except the original R600. */
3723464ebd5Sriastradh	case PIPE_CAP_INDEP_BLEND_ENABLE:
3733464ebd5Sriastradh	case PIPE_CAP_INDEP_BLEND_FUNC:
3743464ebd5Sriastradh		/* R600 doesn't support per-MRT blends */
3753464ebd5Sriastradh		return family == CHIP_R600 ? 0 : 1;
3763464ebd5Sriastradh
3773464ebd5Sriastradh	/* Supported on Evergreen. */
3783464ebd5Sriastradh	case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
379af69d88dSmrg	case PIPE_CAP_CUBE_MAP_ARRAY:
380af69d88dSmrg	case PIPE_CAP_TEXTURE_GATHER_SM5:
381af69d88dSmrg	case PIPE_CAP_TEXTURE_QUERY_LOD:
382af69d88dSmrg	case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
38301e04c3fSmrg	case PIPE_CAP_SAMPLER_VIEW_TARGET:
38401e04c3fSmrg	case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
38501e04c3fSmrg	case PIPE_CAP_TGSI_CLOCK:
38601e04c3fSmrg	case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
38701e04c3fSmrg	case PIPE_CAP_QUERY_BUFFER_OBJECT:
3883464ebd5Sriastradh		return family >= CHIP_CEDAR ? 1 : 0;
389af69d88dSmrg	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
390af69d88dSmrg		return family >= CHIP_CEDAR ? 4 : 0;
39101e04c3fSmrg	case PIPE_CAP_DRAW_INDIRECT:
39201e04c3fSmrg		/* kernel command checker support is also required */
39301e04c3fSmrg		return family >= CHIP_CEDAR && rscreen->b.info.drm_minor >= 41;
39401e04c3fSmrg
39501e04c3fSmrg	case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
39601e04c3fSmrg		return family >= CHIP_CEDAR ? 0 : 1;
39701e04c3fSmrg
39801e04c3fSmrg	case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
39901e04c3fSmrg		return 8;
40001e04c3fSmrg
40101e04c3fSmrg	case PIPE_CAP_MAX_GS_INVOCATIONS:
40201e04c3fSmrg		return 32;
40301e04c3fSmrg
40401e04c3fSmrg	/* shader buffer objects */
40501e04c3fSmrg	case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
40601e04c3fSmrg		return 1 << 27;
40701e04c3fSmrg	case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
40801e04c3fSmrg		return 8;
4093464ebd5Sriastradh
41001e04c3fSmrg	case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
41101e04c3fSmrg		return 0;
41201e04c3fSmrg
4137ec681f3Smrg        case PIPE_CAP_INT64:
41401e04c3fSmrg	case PIPE_CAP_DOUBLES:
41501e04c3fSmrg		if (rscreen->b.family == CHIP_ARUBA ||
41601e04c3fSmrg		    rscreen->b.family == CHIP_CAYMAN ||
41701e04c3fSmrg		    rscreen->b.family == CHIP_CYPRESS ||
41801e04c3fSmrg		    rscreen->b.family == CHIP_HEMLOCK)
41901e04c3fSmrg			return 1;
4207ec681f3Smrg                if (is_nir_enabled(&rscreen->b))
4217ec681f3Smrg                   return 1;
42201e04c3fSmrg		return 0;
4237ec681f3Smrg        case PIPE_CAP_INT64_DIVMOD:
4247ec681f3Smrg           /* it is actually not supported, but the nir lowering hdanles this corectly wheras
4257ec681f3Smrg            * the glsl lowering path seems to not initialize the buildins correctly.
4267ec681f3Smrg            */
4277ec681f3Smrg           return is_nir_enabled(&rscreen->b);
42801e04c3fSmrg	case PIPE_CAP_CULL_DISTANCE:
42901e04c3fSmrg		return 1;
43001e04c3fSmrg
43101e04c3fSmrg	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
43201e04c3fSmrg		if (family >= CHIP_CEDAR)
43301e04c3fSmrg			return 256;
4343464ebd5Sriastradh		return 0;
4353464ebd5Sriastradh
43601e04c3fSmrg	case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
43701e04c3fSmrg		if (family >= CHIP_CEDAR)
43801e04c3fSmrg			return 30;
43901e04c3fSmrg		else
44001e04c3fSmrg			return 0;
441af69d88dSmrg	/* Stream output. */
442af69d88dSmrg	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
443af69d88dSmrg		return rscreen->b.has_streamout ? 4 : 0;
444af69d88dSmrg	case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
44501e04c3fSmrg	case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
446af69d88dSmrg		return rscreen->b.has_streamout ? 1 : 0;
447af69d88dSmrg	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
448af69d88dSmrg	case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
449af69d88dSmrg		return 32*4;
450af69d88dSmrg
451af69d88dSmrg	/* Geometry shader output. */
452af69d88dSmrg	case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
453af69d88dSmrg		return 1024;
454af69d88dSmrg	case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
455af69d88dSmrg		return 16384;
456af69d88dSmrg	case PIPE_CAP_MAX_VERTEX_STREAMS:
45701e04c3fSmrg		return family >= CHIP_CEDAR ? 4 : 1;
45801e04c3fSmrg
45901e04c3fSmrg	case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
46001e04c3fSmrg		/* Should be 2047, but 2048 is a requirement for GL 4.4 */
46101e04c3fSmrg		return 2048;
4623464ebd5Sriastradh
4633464ebd5Sriastradh	/* Texturing. */
4647ec681f3Smrg	case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
4657ec681f3Smrg		if (family >= CHIP_CEDAR)
4667ec681f3Smrg			return 16384;
4677ec681f3Smrg		else
4687ec681f3Smrg			return 8192;
4693464ebd5Sriastradh	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
4703464ebd5Sriastradh		if (family >= CHIP_CEDAR)
4713464ebd5Sriastradh			return 15;
4723464ebd5Sriastradh		else
4733464ebd5Sriastradh			return 14;
474af69d88dSmrg	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
475af69d88dSmrg		/* textures support 8192, but layered rendering supports 2048 */
476af69d88dSmrg		return 12;
477af69d88dSmrg	case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
478af69d88dSmrg		/* textures support 8192, but layered rendering supports 2048 */
47901e04c3fSmrg		return 2048;
4803464ebd5Sriastradh
4813464ebd5Sriastradh	/* Render targets. */
4823464ebd5Sriastradh	case PIPE_CAP_MAX_RENDER_TARGETS:
483af69d88dSmrg		/* XXX some r6xx are buggy and can only do 4 */
4843464ebd5Sriastradh		return 8;
4853464ebd5Sriastradh
486af69d88dSmrg	case PIPE_CAP_MAX_VIEWPORTS:
48701e04c3fSmrg		return R600_MAX_VIEWPORTS;
48801e04c3fSmrg	case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
48901e04c3fSmrg	case PIPE_CAP_RASTERIZER_SUBPIXEL_BITS:
49001e04c3fSmrg		return 8;
4913464ebd5Sriastradh
492af69d88dSmrg	/* Timer queries, present when the clock frequency is non zero. */
493af69d88dSmrg	case PIPE_CAP_QUERY_TIME_ELAPSED:
49401e04c3fSmrg		return rscreen->b.info.clock_crystal_freq != 0;
495af69d88dSmrg	case PIPE_CAP_QUERY_TIMESTAMP:
496af69d88dSmrg		return rscreen->b.info.drm_minor >= 20 &&
49701e04c3fSmrg		       rscreen->b.info.clock_crystal_freq != 0;
498af69d88dSmrg
499af69d88dSmrg	case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
500af69d88dSmrg	case PIPE_CAP_MIN_TEXEL_OFFSET:
501af69d88dSmrg		return -8;
502af69d88dSmrg
503af69d88dSmrg	case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
504af69d88dSmrg	case PIPE_CAP_MAX_TEXEL_OFFSET:
505af69d88dSmrg		return 7;
506af69d88dSmrg
5079f464c52Smaya	case PIPE_CAP_MAX_VARYINGS:
5089f464c52Smaya		return 32;
5099f464c52Smaya
510af69d88dSmrg	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
511af69d88dSmrg		return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600;
512af69d88dSmrg	case PIPE_CAP_ENDIANNESS:
513af69d88dSmrg		return PIPE_ENDIAN_LITTLE;
514af69d88dSmrg
515af69d88dSmrg	case PIPE_CAP_VENDOR_ID:
51601e04c3fSmrg		return ATI_VENDOR_ID;
517af69d88dSmrg	case PIPE_CAP_DEVICE_ID:
518af69d88dSmrg		return rscreen->b.info.pci_id;
519af69d88dSmrg	case PIPE_CAP_ACCELERATED:
520af69d88dSmrg		return 1;
521af69d88dSmrg	case PIPE_CAP_VIDEO_MEMORY:
522af69d88dSmrg		return rscreen->b.info.vram_size >> 20;
523af69d88dSmrg	case PIPE_CAP_UMA:
5243464ebd5Sriastradh		return 0;
52501e04c3fSmrg	case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
52601e04c3fSmrg		return rscreen->b.chip_class >= R700;
52701e04c3fSmrg	case PIPE_CAP_PCI_GROUP:
52801e04c3fSmrg		return rscreen->b.info.pci_domain;
52901e04c3fSmrg	case PIPE_CAP_PCI_BUS:
53001e04c3fSmrg		return rscreen->b.info.pci_bus;
53101e04c3fSmrg	case PIPE_CAP_PCI_DEVICE:
53201e04c3fSmrg		return rscreen->b.info.pci_dev;
53301e04c3fSmrg	case PIPE_CAP_PCI_FUNCTION:
53401e04c3fSmrg		return rscreen->b.info.pci_func;
53501e04c3fSmrg
53601e04c3fSmrg	case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTERS:
53701e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR && rscreen->has_atomics)
53801e04c3fSmrg			return 8;
53901e04c3fSmrg		return 0;
54001e04c3fSmrg	case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTER_BUFFERS:
54101e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR && rscreen->has_atomics)
54201e04c3fSmrg			return EG_MAX_ATOMIC_BUFFERS;
54301e04c3fSmrg		return 0;
54401e04c3fSmrg
54501e04c3fSmrg	default:
54601e04c3fSmrg		return u_pipe_screen_get_param_defaults(pscreen, param);
5473464ebd5Sriastradh	}
5483464ebd5Sriastradh}
5493464ebd5Sriastradh
55001e04c3fSmrgstatic int r600_get_shader_param(struct pipe_screen* pscreen,
55101e04c3fSmrg				 enum pipe_shader_type shader,
55201e04c3fSmrg				 enum pipe_shader_cap param)
5533464ebd5Sriastradh{
5543464ebd5Sriastradh	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
5553464ebd5Sriastradh
5563464ebd5Sriastradh	switch(shader)
5573464ebd5Sriastradh	{
5583464ebd5Sriastradh	case PIPE_SHADER_FRAGMENT:
5593464ebd5Sriastradh	case PIPE_SHADER_VERTEX:
5603464ebd5Sriastradh		break;
5613464ebd5Sriastradh	case PIPE_SHADER_GEOMETRY:
562af69d88dSmrg		if (rscreen->b.family >= CHIP_CEDAR)
563af69d88dSmrg			break;
564af69d88dSmrg		/* pre-evergreen geom shaders need newer kernel */
565af69d88dSmrg		if (rscreen->b.info.drm_minor >= 37)
566af69d88dSmrg			break;
5673464ebd5Sriastradh		return 0;
56801e04c3fSmrg	case PIPE_SHADER_TESS_CTRL:
56901e04c3fSmrg	case PIPE_SHADER_TESS_EVAL:
5707ec681f3Smrg	case PIPE_SHADER_COMPUTE:
57101e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR)
57201e04c3fSmrg			break;
5737ec681f3Smrg		FALLTHROUGH;
5743464ebd5Sriastradh	default:
5753464ebd5Sriastradh		return 0;
5763464ebd5Sriastradh	}
5773464ebd5Sriastradh
5783464ebd5Sriastradh	switch (param) {
5793464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
5803464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
5813464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
5823464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
5833464ebd5Sriastradh		return 16384;
5843464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
585af69d88dSmrg		return 32;
5863464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_INPUTS:
587af69d88dSmrg		return shader == PIPE_SHADER_VERTEX ? 16 : 32;
58801e04c3fSmrg	case PIPE_SHADER_CAP_MAX_OUTPUTS:
58901e04c3fSmrg		return shader == PIPE_SHADER_FRAGMENT ? 8 : 32;
5903464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_TEMPS:
5913464ebd5Sriastradh		return 256; /* Max native temporaries. */
592af69d88dSmrg	case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
593af69d88dSmrg		if (shader == PIPE_SHADER_COMPUTE) {
594af69d88dSmrg			uint64_t max_const_buffer_size;
5957ec681f3Smrg			enum pipe_shader_ir ir_type = is_nir_enabled(&rscreen->b) ?
5967ec681f3Smrg				PIPE_SHADER_IR_NIR: PIPE_SHADER_IR_TGSI;
5977ec681f3Smrg			pscreen->get_compute_param(pscreen, ir_type,
5987ec681f3Smrg						   PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE,
5997ec681f3Smrg						   &max_const_buffer_size);
60001e04c3fSmrg			return MIN2(max_const_buffer_size, INT_MAX);
601af69d88dSmrg
602af69d88dSmrg		} else {
603af69d88dSmrg			return R600_MAX_CONST_BUFFER_SIZE;
604af69d88dSmrg		}
6053464ebd5Sriastradh	case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
606af69d88dSmrg		return R600_MAX_USER_CONST_BUFFERS;
6073464ebd5Sriastradh	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
6083464ebd5Sriastradh		return 1;
609af69d88dSmrg	case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
610af69d88dSmrg		return 1;
6113464ebd5Sriastradh	case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
6123464ebd5Sriastradh	case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
6133464ebd5Sriastradh	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
6143464ebd5Sriastradh	case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
6153464ebd5Sriastradh		return 1;
6163464ebd5Sriastradh	case PIPE_SHADER_CAP_SUBROUTINES:
61701e04c3fSmrg	case PIPE_SHADER_CAP_INT64_ATOMICS:
61801e04c3fSmrg	case PIPE_SHADER_CAP_FP16:
6197ec681f3Smrg        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
6207ec681f3Smrg	case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
6217ec681f3Smrg        case PIPE_SHADER_CAP_INT16:
6227ec681f3Smrg        case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
6233464ebd5Sriastradh		return 0;
624af69d88dSmrg	case PIPE_SHADER_CAP_INTEGERS:
62501e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
626af69d88dSmrg		return 1;
627af69d88dSmrg	case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
628af69d88dSmrg	case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
629af69d88dSmrg		return 16;
6307ec681f3Smrg	case PIPE_SHADER_CAP_PREFERRED_IR:
6317ec681f3Smrg		if (is_nir_enabled(&rscreen->b))
6327ec681f3Smrg			return PIPE_SHADER_IR_NIR;
63301e04c3fSmrg		return PIPE_SHADER_IR_TGSI;
63401e04c3fSmrg	case PIPE_SHADER_CAP_SUPPORTED_IRS: {
63501e04c3fSmrg		int ir = 0;
63601e04c3fSmrg		if (shader == PIPE_SHADER_COMPUTE)
63701e04c3fSmrg			ir = 1 << PIPE_SHADER_IR_NATIVE;
6387ec681f3Smrg		if (rscreen->b.family >= CHIP_CEDAR) {
63901e04c3fSmrg			ir |= 1 << PIPE_SHADER_IR_TGSI;
6407ec681f3Smrg			if (is_nir_enabled(&rscreen->b))
6417ec681f3Smrg				ir |= 1 << PIPE_SHADER_IR_NIR;
6427ec681f3Smrg		}
64301e04c3fSmrg		return ir;
64401e04c3fSmrg	}
64501e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
64601e04c3fSmrg		if (rscreen->b.family == CHIP_ARUBA ||
64701e04c3fSmrg		    rscreen->b.family == CHIP_CAYMAN ||
64801e04c3fSmrg		    rscreen->b.family == CHIP_CYPRESS ||
64901e04c3fSmrg		    rscreen->b.family == CHIP_HEMLOCK)
65001e04c3fSmrg			return 1;
65101e04c3fSmrg		return 0;
65201e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
65301e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
65401e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
65501e04c3fSmrg	case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
65601e04c3fSmrg	case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
65701e04c3fSmrg		return 0;
65801e04c3fSmrg	case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
65901e04c3fSmrg	case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
66001e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR &&
66101e04c3fSmrg		    (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE))
66201e04c3fSmrg		    return 8;
66301e04c3fSmrg		return 0;
66401e04c3fSmrg	case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
66501e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR && rscreen->has_atomics)
66601e04c3fSmrg			return 8;
66701e04c3fSmrg		return 0;
66801e04c3fSmrg	case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
66901e04c3fSmrg		/* having to allocate the atomics out amongst shaders stages is messy,
67001e04c3fSmrg		   so give compute 8 buffers and all the others one */
67101e04c3fSmrg		if (rscreen->b.family >= CHIP_CEDAR && rscreen->has_atomics) {
67201e04c3fSmrg			return EG_MAX_ATOMIC_BUFFERS;
673af69d88dSmrg		}
6743464ebd5Sriastradh		return 0;
67501e04c3fSmrg	case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
67601e04c3fSmrg		/* due to a bug in the shader compiler, some loops hang
67701e04c3fSmrg		 * if they are not unrolled, see:
67801e04c3fSmrg		 *    https://bugs.freedesktop.org/show_bug.cgi?id=86720
67901e04c3fSmrg		 */
68001e04c3fSmrg		return 255;
6813464ebd5Sriastradh	}
682af69d88dSmrg	return 0;
6833464ebd5Sriastradh}
6843464ebd5Sriastradh
685af69d88dSmrgstatic void r600_destroy_screen(struct pipe_screen* pscreen)
6863464ebd5Sriastradh{
687af69d88dSmrg	struct r600_screen *rscreen = (struct r600_screen *)pscreen;
6883464ebd5Sriastradh
68901e04c3fSmrg	if (!rscreen)
690af69d88dSmrg		return;
6913464ebd5Sriastradh
692af69d88dSmrg	if (!rscreen->b.ws->unref(rscreen->b.ws))
693af69d88dSmrg		return;
6943464ebd5Sriastradh
695af69d88dSmrg	if (rscreen->global_pool) {
696af69d88dSmrg		compute_memory_pool_delete(rscreen->global_pool);
6973464ebd5Sriastradh	}
6983464ebd5Sriastradh
699af69d88dSmrg	r600_destroy_common_screen(&rscreen->b);
700af69d88dSmrg}
7013464ebd5Sriastradh
702af69d88dSmrgstatic struct pipe_resource *r600_resource_create(struct pipe_screen *screen,
703af69d88dSmrg						  const struct pipe_resource *templ)
704af69d88dSmrg{
705af69d88dSmrg	if (templ->target == PIPE_BUFFER &&
706af69d88dSmrg	    (templ->bind & PIPE_BIND_GLOBAL))
707af69d88dSmrg		return r600_compute_global_buffer_create(screen, templ);
7083464ebd5Sriastradh
709af69d88dSmrg	return r600_resource_create_common(screen, templ);
7103464ebd5Sriastradh}
7113464ebd5Sriastradh
71201e04c3fSmrgstruct pipe_screen *r600_screen_create(struct radeon_winsys *ws,
71301e04c3fSmrg				       const struct pipe_screen_config *config)
7143464ebd5Sriastradh{
715af69d88dSmrg	struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
7163464ebd5Sriastradh
71701e04c3fSmrg	if (!rscreen) {
718af69d88dSmrg		return NULL;
719af69d88dSmrg	}
7203464ebd5Sriastradh
721af69d88dSmrg	/* Set functions first. */
722af69d88dSmrg	rscreen->b.b.context_create = r600_create_context;
723af69d88dSmrg	rscreen->b.b.destroy = r600_destroy_screen;
724af69d88dSmrg	rscreen->b.b.get_param = r600_get_param;
725af69d88dSmrg	rscreen->b.b.get_shader_param = r600_get_shader_param;
726af69d88dSmrg	rscreen->b.b.resource_create = r600_resource_create;
7273464ebd5Sriastradh
728af69d88dSmrg	if (!r600_common_screen_init(&rscreen->b, ws)) {
729af69d88dSmrg		FREE(rscreen);
730af69d88dSmrg		return NULL;
731af69d88dSmrg	}
7323464ebd5Sriastradh
733af69d88dSmrg	if (rscreen->b.info.chip_class >= EVERGREEN) {
734af69d88dSmrg		rscreen->b.b.is_format_supported = evergreen_is_format_supported;
735af69d88dSmrg	} else {
736af69d88dSmrg		rscreen->b.b.is_format_supported = r600_is_format_supported;
737af69d88dSmrg	}
7383464ebd5Sriastradh
739af69d88dSmrg	rscreen->b.debug_flags |= debug_get_flags_option("R600_DEBUG", r600_debug_options, 0);
740af69d88dSmrg	if (debug_get_bool_option("R600_DEBUG_COMPUTE", FALSE))
741af69d88dSmrg		rscreen->b.debug_flags |= DBG_COMPUTE;
742af69d88dSmrg	if (debug_get_bool_option("R600_DUMP_SHADERS", FALSE))
74301e04c3fSmrg		rscreen->b.debug_flags |= DBG_ALL_SHADERS | DBG_FS;
74401e04c3fSmrg	if (!debug_get_bool_option("R600_HYPERZ", TRUE))
74501e04c3fSmrg		rscreen->b.debug_flags |= DBG_NO_HYPERZ;
746af69d88dSmrg
747af69d88dSmrg	if (rscreen->b.family == CHIP_UNKNOWN) {
748af69d88dSmrg		fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->b.info.pci_id);
749af69d88dSmrg		FREE(rscreen);
750af69d88dSmrg		return NULL;
7513464ebd5Sriastradh	}
7523464ebd5Sriastradh
753af69d88dSmrg	/* Figure out streamout kernel support. */
754af69d88dSmrg	switch (rscreen->b.chip_class) {
755af69d88dSmrg	case R600:
756af69d88dSmrg		if (rscreen->b.family < CHIP_RS780) {
757af69d88dSmrg			rscreen->b.has_streamout = rscreen->b.info.drm_minor >= 14;
758af69d88dSmrg		} else {
759af69d88dSmrg			rscreen->b.has_streamout = rscreen->b.info.drm_minor >= 23;
760af69d88dSmrg		}
761af69d88dSmrg		break;
762af69d88dSmrg	case R700:
763af69d88dSmrg		rscreen->b.has_streamout = rscreen->b.info.drm_minor >= 17;
764af69d88dSmrg		break;
765af69d88dSmrg	case EVERGREEN:
766af69d88dSmrg	case CAYMAN:
767af69d88dSmrg		rscreen->b.has_streamout = rscreen->b.info.drm_minor >= 14;
768af69d88dSmrg		break;
769af69d88dSmrg	default:
770af69d88dSmrg		rscreen->b.has_streamout = FALSE;
771af69d88dSmrg		break;
772af69d88dSmrg	}
7733464ebd5Sriastradh
774af69d88dSmrg	/* MSAA support. */
775af69d88dSmrg	switch (rscreen->b.chip_class) {
776af69d88dSmrg	case R600:
777af69d88dSmrg	case R700:
778af69d88dSmrg		rscreen->has_msaa = rscreen->b.info.drm_minor >= 22;
779af69d88dSmrg		rscreen->has_compressed_msaa_texturing = false;
780af69d88dSmrg		break;
781af69d88dSmrg	case EVERGREEN:
782af69d88dSmrg		rscreen->has_msaa = rscreen->b.info.drm_minor >= 19;
783af69d88dSmrg		rscreen->has_compressed_msaa_texturing = rscreen->b.info.drm_minor >= 24;
784af69d88dSmrg		break;
785af69d88dSmrg	case CAYMAN:
786af69d88dSmrg		rscreen->has_msaa = rscreen->b.info.drm_minor >= 19;
787af69d88dSmrg		rscreen->has_compressed_msaa_texturing = true;
788af69d88dSmrg		break;
789af69d88dSmrg	default:
790af69d88dSmrg		rscreen->has_msaa = FALSE;
791af69d88dSmrg		rscreen->has_compressed_msaa_texturing = false;
792af69d88dSmrg	}
7933464ebd5Sriastradh
794af69d88dSmrg	rscreen->b.has_cp_dma = rscreen->b.info.drm_minor >= 27 &&
795af69d88dSmrg			      !(rscreen->b.debug_flags & DBG_NO_CP_DMA);
7963464ebd5Sriastradh
79701e04c3fSmrg	rscreen->b.barrier_flags.cp_to_L2 =
79801e04c3fSmrg		R600_CONTEXT_INV_VERTEX_CACHE |
79901e04c3fSmrg		R600_CONTEXT_INV_TEX_CACHE |
80001e04c3fSmrg		R600_CONTEXT_INV_CONST_CACHE;
80101e04c3fSmrg	rscreen->b.barrier_flags.compute_to_L2 = R600_CONTEXT_CS_PARTIAL_FLUSH | R600_CONTEXT_FLUSH_AND_INV;
80201e04c3fSmrg
803af69d88dSmrg	rscreen->global_pool = compute_memory_pool_new(rscreen);
8043464ebd5Sriastradh
805af69d88dSmrg	/* Create the auxiliary context. This must be done last. */
80601e04c3fSmrg	rscreen->b.aux_context = rscreen->b.b.context_create(&rscreen->b.b, NULL, 0);
8073464ebd5Sriastradh
80801e04c3fSmrg	rscreen->has_atomics = rscreen->b.info.drm_minor >= 44;
809af69d88dSmrg#if 0 /* This is for testing whether aux_context and buffer clearing work correctly. */
810af69d88dSmrg	struct pipe_resource templ = {};
8113464ebd5Sriastradh
812af69d88dSmrg	templ.width0 = 4;
813af69d88dSmrg	templ.height0 = 2048;
814af69d88dSmrg	templ.depth0 = 1;
815af69d88dSmrg	templ.array_size = 1;
816af69d88dSmrg	templ.target = PIPE_TEXTURE_2D;
817af69d88dSmrg	templ.format = PIPE_FORMAT_R8G8B8A8_UNORM;
818af69d88dSmrg	templ.usage = PIPE_USAGE_DEFAULT;
8193464ebd5Sriastradh
820af69d88dSmrg	struct r600_resource *res = r600_resource(rscreen->screen.resource_create(&rscreen->screen, &templ));
8217ec681f3Smrg	unsigned char *map = ws->buffer_map(res->buf, NULL, PIPE_MAP_WRITE);
8223464ebd5Sriastradh
823af69d88dSmrg	memset(map, 0, 256);
8243464ebd5Sriastradh
825af69d88dSmrg	r600_screen_clear_buffer(rscreen, &res->b.b, 4, 4, 0xCC);
826af69d88dSmrg	r600_screen_clear_buffer(rscreen, &res->b.b, 8, 4, 0xDD);
827af69d88dSmrg	r600_screen_clear_buffer(rscreen, &res->b.b, 12, 4, 0xEE);
828af69d88dSmrg	r600_screen_clear_buffer(rscreen, &res->b.b, 20, 4, 0xFF);
829af69d88dSmrg	r600_screen_clear_buffer(rscreen, &res->b.b, 32, 20, 0x87);
830af69d88dSmrg
831af69d88dSmrg	ws->buffer_wait(res->buf, RADEON_USAGE_WRITE);
832af69d88dSmrg
833af69d88dSmrg	int i;
834af69d88dSmrg	for (i = 0; i < 256; i++) {
835af69d88dSmrg		printf("%02X", map[i]);
836af69d88dSmrg		if (i % 16 == 15)
837af69d88dSmrg			printf("\n");
8383464ebd5Sriastradh	}
839af69d88dSmrg#endif
8403464ebd5Sriastradh
84101e04c3fSmrg	if (rscreen->b.debug_flags & DBG_TEST_DMA)
84201e04c3fSmrg		r600_test_dma(&rscreen->b);
84301e04c3fSmrg
84401e04c3fSmrg	r600_query_fix_enabled_rb_mask(&rscreen->b);
845af69d88dSmrg	return &rscreen->b.b;
8463464ebd5Sriastradh}
847