diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index d7a0ced08f5..2ff330bf398 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -865,6 +865,305 @@ fd_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, return 0; } +static void +fd_init_screen_caps(struct fd_screen *screen) +{ + struct pipe_caps *caps = (struct pipe_caps *)&screen->base.caps; + + u_init_pipe_screen_caps(&screen->base, 1); + + /* this is probably not totally correct.. but it's a start: */ + + /* Supported features (boolean caps). */ + caps->npot_textures = true; + caps->mixed_framebuffer_sizes = true; + caps->anisotropic_filter = true; + caps->blend_equation_separate = true; + caps->texture_swizzle = true; + caps->fs_coord_origin_upper_left = true; + caps->seamless_cube_map = true; + caps->vertex_color_unclamped = true; + caps->quads_follow_provoking_vertex_convention = true; + caps->string_marker = true; + caps->mixed_color_depth_bits = true; + caps->texture_barrier = true; + caps->invalidate_buffer = true; + caps->glsl_tess_levels_as_inputs = true; + caps->texture_mirror_clamp_to_edge = true; + caps->gl_spirv = true; + caps->fbfetch_coherent = true; + caps->has_const_bw = true; + + caps->copy_between_compressed_and_plain_formats = + caps->multi_draw_indirect = + caps->draw_parameters = + caps->multi_draw_indirect_params = + caps->depth_bounds_test = is_a6xx(screen); + + caps->vertex_input_alignment = + is_a2xx(screen) ? PIPE_VERTEX_INPUT_ALIGNMENT_4BYTE : PIPE_VERTEX_INPUT_ALIGNMENT_NONE; + + caps->fs_coord_pixel_center_integer = is_a2xx(screen); + caps->fs_coord_pixel_center_half_integer = !is_a2xx(screen); + + caps->packed_uniforms = !is_a2xx(screen); + + caps->robust_buffer_access_behavior = + caps->device_reset_status_query = screen->has_robustness; + + caps->compute = has_compute(screen); + + caps->texture_transfer_modes = screen->gen >= 6 ? PIPE_TEXTURE_TRANSFER_BLIT : 0; + + caps->pci_group = + caps->pci_bus = + caps->pci_device = + caps->pci_function = 0; + + caps->supported_prim_modes = + caps->supported_prim_modes_with_restart = screen->primtypes_mask; + + caps->fragment_shader_texture_lod = + caps->fragment_shader_derivatives = + caps->primitive_restart = + caps->primitive_restart_fixed_index = + caps->vs_instanceid = + caps->vertex_element_instance_divisor = + caps->indep_blend_enable = + caps->indep_blend_func = + caps->texture_buffer_objects = + caps->texture_half_float_linear = + caps->conditional_render = + caps->conditional_render_inverted = + caps->seamless_cube_map_per_texture = + caps->clip_halfz = + is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + + caps->texture_multisample = + caps->image_store_formatted = + caps->image_load_formatted = is_a5xx(screen) || is_a6xx(screen); + + caps->fake_sw_msaa = !caps->texture_multisample; + + caps->surface_sample_count = is_a6xx(screen); + + caps->depth_clip_disable = is_a3xx(screen) || is_a4xx(screen) || is_a6xx(screen); + + caps->post_depth_coverage = + caps->depth_clip_disable_separate = + caps->demote_to_helper_invocation = is_a6xx(screen); + + caps->sampler_reduction_minmax = + caps->sampler_reduction_minmax_arb = + is_a6xx(screen) && screen->info->a6xx.has_sampler_minmax; + + caps->programmable_sample_locations = + is_a6xx(screen) && screen->info->a6xx.has_sample_locations; + + caps->polygon_offset_clamp = is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + + caps->prefer_imm_arrays_as_constbuf = false; + + caps->texture_buffer_offset_alignment = is_a3xx(screen) ? 16 : + (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen) ? 64 : 0); + caps->max_texel_buffer_elements_uint = + /* We could possibly emulate more by pretending 2d/rect textures and + * splitting high bits of index into 2nd dimension.. + */ + is_a3xx(screen) ? A3XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT : + /* Note that the Vulkan blob on a540 and 640 report a + * maxTexelBufferElements of just 65536 (the GLES3.2 and Vulkan + * minimum). + */ + (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen) ? + A4XX_MAX_TEXEL_BUFFER_ELEMENTS_UINT : 0); + + caps->texture_border_color_quirk = PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_FREEDRENO; + + caps->texture_float_linear = + caps->cube_map_array = + caps->sampler_view_target = + caps->texture_query_lod = is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + + /* Note that a5xx can do this, it just can't (at least with + * current firmware) do draw_indirect with base_instance. + * Since draw_indirect is needed sooner (gles31 and gl40 vs + * gl42), hide base_instance on a5xx. :-/ + */ + caps->start_instance = is_a4xx(screen) || is_a6xx(screen); + + caps->constant_buffer_offset_alignment = 64; + + caps->int64 = + caps->doubles = is_ir3(screen); + + caps->glsl_feature_level = + caps->glsl_feature_level_compatibility = + is_a6xx(screen) ? 460 : (is_ir3(screen) ? 140 : 120); + + caps->essl_feature_level = + is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen) ? 320 : + (is_ir3(screen) ? 300 : 120); + + caps->shader_buffer_offset_alignment = + is_a6xx(screen) ? 64 : (is_a5xx(screen) || is_a4xx(screen) ? 4 : 0); + + caps->max_texture_gather_components = + is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen) ? 4 : 0; + + /* TODO if we need this, do it in nir/ir3 backend to avoid breaking + * precompile: */ + caps->force_persample_interp = false; + + caps->fbfetch = + fd_device_version(screen->dev) >= FD_VERSION_GMEM_BASE && is_a6xx(screen) ? + screen->max_rts : 0; + caps->sample_shading = is_a6xx(screen); + + caps->context_priority_mask = screen->priority_mask; + + caps->draw_indirect = is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + + caps->framebuffer_no_attachment = + is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + + /* name is confusing, but this turns on std430 packing */ + caps->load_constbuf = is_ir3(screen); + + caps->nir_images_as_deref = false; + + caps->vs_layer_viewport = + caps->tes_layer_viewport = is_a6xx(screen); + + caps->max_viewports = is_a6xx(screen) ? 16 : 1; + + caps->max_varyings = is_a6xx(screen) ? 31 : 16; + + /* We don't really have a limit on this, it all goes into the main + * memory buffer. Needs to be at least 120 / 4 (minimum requirement + * for GL_MAX_TESS_PATCH_COMPONENTS). + */ + caps->max_shader_patch_varyings = 128; + + caps->max_texture_upload_memory_budget = 64 * 1024 * 1024; + + caps->shareable_shaders = is_ir3(screen); + + /* Geometry shaders.. */ + caps->max_geometry_output_vertices = 256; + caps->max_geometry_total_output_components = 2048; + caps->max_gs_invocations = 32; + + /* Only a2xx has the half-border clamp mode in HW, just have mesa/st lower + * it for later HW. + */ + caps->gl_clamp = is_a2xx(screen); + + caps->clip_planes = + /* Gens that support GS, have GS lowered into a quasi-VS which confuses + * the frontend clip-plane lowering. So we handle this in the backend + * + */ + screen->base.get_shader_param(&screen->base, PIPE_SHADER_GEOMETRY, + PIPE_SHADER_CAP_MAX_INSTRUCTIONS) ? 1 : + /* On a3xx, there is HW support for GL user clip planes that + * occasionally has to fall back to shader key-based lowering to clip + * distances in the VS, and we don't support clip distances so that is + * always shader-based lowering in the FS. + * + * On a4xx, there is no HW support for clip planes, so they are + * always lowered to clip distances. We also lack SW support for the + * HW's clip distances in HW, so we do shader-based lowering in the FS + * in the driver backend. + * + * On a5xx-a6xx, we have the HW clip distances hooked up, so we just let + * mesa/st lower desktop GL's clip planes to clip distances in the last + * vertex shader stage. + * + * NOTE: but see comment above about geometry shaders + */ + (is_a5xx(screen) ? 0 : 1); + + /* Stream output. */ + caps->max_vertex_streams = is_a6xx(screen) ? /* has SO + GS */ + PIPE_MAX_SO_BUFFERS : 0; + caps->max_stream_output_buffers = is_ir3(screen) ? PIPE_MAX_SO_BUFFERS : 0; + caps->stream_output_pause_resume = + caps->stream_output_interleave_buffers = + caps->fs_position_is_sysval = + caps->tgsi_texcoord = + caps->shader_array_components = + caps->texture_query_samples = + caps->fs_fine_derivative = is_ir3(screen); + caps->shader_group_vote = is_a6xx(screen); + caps->fs_face_is_integer_sysval = true; + caps->fs_point_is_sysval = is_a2xx(screen); + caps->max_stream_output_separate_components = + caps->max_stream_output_interleaved_components = is_ir3(screen) ? + 16 * 4 /* should only be shader out limit? */ : 0; + + /* Texturing. */ + caps->max_texture_2d_size = + is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen) ? 16384 : 8192; + caps->max_texture_cube_levels = + is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen) ? 15 : 14; + + caps->max_texture_3d_levels = is_a3xx(screen) ? 11 : 12; + + caps->max_texture_array_layers = is_a6xx(screen) ? 2048 : + (is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) ? 256 : 0); + + /* Render targets. */ + caps->max_render_targets = screen->max_rts; + caps->max_dual_source_render_targets = (is_a3xx(screen) || is_a6xx(screen)) ? 1 : 0; + + /* Queries. */ + caps->occlusion_query = + is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen); + caps->query_timestamp = + caps->query_time_elapsed = + /* only a4xx, requires new enough kernel so we know max_freq: */ + (screen->max_freq > 0) && (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)); + caps->timer_resolution = ticks_to_ns(1); + caps->query_buffer_object = + caps->query_so_overflow = + caps->query_pipeline_statistics_single = is_a6xx(screen); + + caps->vendor_id = 0x5143; + caps->device_id = 0xFFFFFFFF; + + caps->video_memory = get_memory_size(screen) >> 20; + + /* Enables GL_ATI_meminfo */ + caps->query_memory_info = get_memory_size(screen) != 0; + + caps->uma = true; + caps->memobj = fd_device_version(screen->dev) >= FD_VERSION_MEMORY_FD; + caps->native_fence_fd = fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD; + caps->fence_signal = screen->has_syncobj; + caps->cull_distance = is_a6xx(screen); + caps->shader_stencil_export = is_a6xx(screen); + caps->two_sided_color = false; + caps->throttle = screen->driconf.enable_throttling; + + caps->min_line_width = + caps->min_line_width_aa = + caps->min_point_size = + caps->min_point_size_aa = 1; + + caps->point_size_granularity = + caps->line_width_granularity = 0.1f; + + caps->max_line_width = + caps->max_line_width_aa = 127.0f; + + caps->max_point_size = + caps->max_point_size_aa = 4092.0f; + + caps->max_texture_anisotropy = 16.0f; + caps->max_texture_lod_bias = 15.0f; +} + static const void * fd_get_compiler_options(struct pipe_screen *pscreen, enum pipe_shader_ir ir, enum pipe_shader_type shader) @@ -1261,6 +1560,8 @@ fd_screen_create(int fd, pscreen->get_device_uuid = fd_screen_get_device_uuid; pscreen->get_driver_uuid = fd_screen_get_driver_uuid; + fd_init_screen_caps(screen); + slab_create_parent(&screen->transfer_pool, sizeof(struct fd_transfer), 16); simple_mtx_init(&screen->aux_ctx_lock, mtx_plain);