101e04c3fSmrg/*
201e04c3fSmrg * Copyright 2014, 2015 Red Hat.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * on the rights to use, copy, modify, merge, publish, distribute, sub
801e04c3fSmrg * license, and/or sell copies of the Software, and to permit persons to whom
901e04c3fSmrg * the Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
1901e04c3fSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2001e04c3fSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2101e04c3fSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg#include "util/u_memory.h"
247ec681f3Smrg#include "util/format/u_format.h"
257ec681f3Smrg#include "util/format/u_format_s3tc.h"
2601e04c3fSmrg#include "util/u_screen.h"
2701e04c3fSmrg#include "util/u_video.h"
2801e04c3fSmrg#include "util/u_math.h"
297ec681f3Smrg#include "util/u_inlines.h"
3001e04c3fSmrg#include "util/os_time.h"
317ec681f3Smrg#include "util/xmlconfig.h"
3201e04c3fSmrg#include "pipe/p_defines.h"
3301e04c3fSmrg#include "pipe/p_screen.h"
347ec681f3Smrg#include "nir/nir_to_tgsi.h"
3501e04c3fSmrg
3601e04c3fSmrg#include "tgsi/tgsi_exec.h"
3701e04c3fSmrg
3801e04c3fSmrg#include "virgl_screen.h"
3901e04c3fSmrg#include "virgl_resource.h"
4001e04c3fSmrg#include "virgl_public.h"
4101e04c3fSmrg#include "virgl_context.h"
427ec681f3Smrg#include "virtio-gpu/virgl_protocol.h"
437ec681f3Smrg#include "virgl_encode.h"
4401e04c3fSmrg
4501e04c3fSmrgint virgl_debug = 0;
467ec681f3Smrgstatic const struct debug_named_value virgl_debug_options[] = {
477ec681f3Smrg   { "verbose",   VIRGL_DEBUG_VERBOSE,             NULL },
487ec681f3Smrg   { "tgsi",      VIRGL_DEBUG_TGSI,                NULL },
497ec681f3Smrg   { "nir",       VIRGL_DEBUG_NIR,                 NULL },
507ec681f3Smrg   { "noemubgra", VIRGL_DEBUG_NO_EMULATE_BGRA,     "Disable tweak to emulate BGRA as RGBA on GLES hosts"},
517ec681f3Smrg   { "nobgraswz", VIRGL_DEBUG_NO_BGRA_DEST_SWIZZLE,"Disable tweak to swizzle emulated BGRA on GLES hosts" },
527ec681f3Smrg   { "sync",      VIRGL_DEBUG_SYNC,                "Sync after every flush" },
537ec681f3Smrg   { "xfer",      VIRGL_DEBUG_XFER,                "Do not optimize for transfers" },
547ec681f3Smrg   { "nocoherent", VIRGL_DEBUG_NO_COHERENT,        "Disable coherent memory"},
5501e04c3fSmrg   DEBUG_NAMED_VALUE_END
5601e04c3fSmrg};
577ec681f3SmrgDEBUG_GET_ONCE_FLAGS_OPTION(virgl_debug, "VIRGL_DEBUG", virgl_debug_options, 0)
5801e04c3fSmrg
5901e04c3fSmrgstatic const char *
6001e04c3fSmrgvirgl_get_vendor(struct pipe_screen *screen)
6101e04c3fSmrg{
627ec681f3Smrg   return "Mesa/X.org";
6301e04c3fSmrg}
6401e04c3fSmrg
6501e04c3fSmrg
6601e04c3fSmrgstatic const char *
6701e04c3fSmrgvirgl_get_name(struct pipe_screen *screen)
6801e04c3fSmrg{
697ec681f3Smrg   struct virgl_screen *vscreen = virgl_screen(screen);
707ec681f3Smrg   if (vscreen->caps.caps.v2.host_feature_check_version >= 5)
717ec681f3Smrg      return vscreen->caps.caps.v2.renderer;
727ec681f3Smrg
7301e04c3fSmrg   return "virgl";
7401e04c3fSmrg}
7501e04c3fSmrg
7601e04c3fSmrgstatic int
7701e04c3fSmrgvirgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
7801e04c3fSmrg{
7901e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
8001e04c3fSmrg   switch (param) {
8101e04c3fSmrg   case PIPE_CAP_NPOT_TEXTURES:
8201e04c3fSmrg      return 1;
837ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
847ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
857ec681f3Smrg   case PIPE_CAP_VERTEX_SHADER_SATURATE:
8601e04c3fSmrg      return 1;
8701e04c3fSmrg   case PIPE_CAP_ANISOTROPIC_FILTER:
887ec681f3Smrg      return vscreen->caps.caps.v2.max_anisotropy > 1.0;
8901e04c3fSmrg   case PIPE_CAP_POINT_SPRITE:
9001e04c3fSmrg      return 1;
9101e04c3fSmrg   case PIPE_CAP_MAX_RENDER_TARGETS:
9201e04c3fSmrg      return vscreen->caps.caps.v1.max_render_targets;
9301e04c3fSmrg   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
9401e04c3fSmrg      return vscreen->caps.caps.v1.max_dual_source_render_targets;
9501e04c3fSmrg   case PIPE_CAP_OCCLUSION_QUERY:
9601e04c3fSmrg      return vscreen->caps.caps.v1.bset.occlusion_query;
9701e04c3fSmrg   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
9801e04c3fSmrg   case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
9901e04c3fSmrg      return vscreen->caps.caps.v1.bset.mirror_clamp;
10001e04c3fSmrg   case PIPE_CAP_TEXTURE_SWIZZLE:
10101e04c3fSmrg      return 1;
1027ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
10301e04c3fSmrg      if (vscreen->caps.caps.v2.max_texture_2d_size)
1047ec681f3Smrg         return vscreen->caps.caps.v2.max_texture_2d_size;
1057ec681f3Smrg      return 16384;
10601e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
10701e04c3fSmrg      if (vscreen->caps.caps.v2.max_texture_3d_size)
10801e04c3fSmrg         return 1 + util_logbase2(vscreen->caps.caps.v2.max_texture_3d_size);
10901e04c3fSmrg      return 9; /* 256 x 256 x 256 */
11001e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
11101e04c3fSmrg      if (vscreen->caps.caps.v2.max_texture_cube_size)
11201e04c3fSmrg         return 1 + util_logbase2(vscreen->caps.caps.v2.max_texture_cube_size);
11301e04c3fSmrg      return 13; /* 4K x 4K */
11401e04c3fSmrg   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
11501e04c3fSmrg      return 1;
11601e04c3fSmrg   case PIPE_CAP_INDEP_BLEND_ENABLE:
11701e04c3fSmrg      return vscreen->caps.caps.v1.bset.indep_blend_enable;
11801e04c3fSmrg   case PIPE_CAP_INDEP_BLEND_FUNC:
11901e04c3fSmrg      return vscreen->caps.caps.v1.bset.indep_blend_func;
12001e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
12101e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
12201e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
12301e04c3fSmrg      return 1;
12401e04c3fSmrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
12501e04c3fSmrg      return vscreen->caps.caps.v1.bset.fragment_coord_conventions;
12601e04c3fSmrg   case PIPE_CAP_DEPTH_CLIP_DISABLE:
1277ec681f3Smrg      if (vscreen->caps.caps.v1.bset.depth_clip_disable)
1287ec681f3Smrg         return 1;
1297ec681f3Smrg      if (vscreen->caps.caps.v2.host_feature_check_version >= 3)
1307ec681f3Smrg         return 2;
1317ec681f3Smrg      return 0;
13201e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
13301e04c3fSmrg      return vscreen->caps.caps.v1.max_streamout_buffers;
13401e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
13501e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
13601e04c3fSmrg      return 16*4;
13701e04c3fSmrg   case PIPE_CAP_PRIMITIVE_RESTART:
1387ec681f3Smrg   case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
13901e04c3fSmrg      return vscreen->caps.caps.v1.bset.primitive_restart;
14001e04c3fSmrg   case PIPE_CAP_SHADER_STENCIL_EXPORT:
14101e04c3fSmrg      return vscreen->caps.caps.v1.bset.shader_stencil_export;
14201e04c3fSmrg   case PIPE_CAP_TGSI_INSTANCEID:
14301e04c3fSmrg   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
14401e04c3fSmrg      return 1;
14501e04c3fSmrg   case PIPE_CAP_SEAMLESS_CUBE_MAP:
14601e04c3fSmrg      return vscreen->caps.caps.v1.bset.seamless_cube_map;
14701e04c3fSmrg   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
14801e04c3fSmrg      return vscreen->caps.caps.v1.bset.seamless_cube_map_per_texture;
14901e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
15001e04c3fSmrg      return vscreen->caps.caps.v1.max_texture_array_layers;
15101e04c3fSmrg   case PIPE_CAP_MIN_TEXEL_OFFSET:
15201e04c3fSmrg      return vscreen->caps.caps.v2.min_texel_offset;
15301e04c3fSmrg   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
15401e04c3fSmrg      return vscreen->caps.caps.v2.min_texture_gather_offset;
15501e04c3fSmrg   case PIPE_CAP_MAX_TEXEL_OFFSET:
15601e04c3fSmrg      return vscreen->caps.caps.v2.max_texel_offset;
15701e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
15801e04c3fSmrg      return vscreen->caps.caps.v2.max_texture_gather_offset;
15901e04c3fSmrg   case PIPE_CAP_CONDITIONAL_RENDER:
16001e04c3fSmrg      return vscreen->caps.caps.v1.bset.conditional_render;
16101e04c3fSmrg   case PIPE_CAP_TEXTURE_BARRIER:
16201e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_BARRIER;
16301e04c3fSmrg   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
16401e04c3fSmrg      return 1;
16501e04c3fSmrg   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
16601e04c3fSmrg   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
16701e04c3fSmrg      return vscreen->caps.caps.v1.bset.color_clamping;
16801e04c3fSmrg   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
1699f464c52Smaya      return (vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_FBO_MIXED_COLOR_FORMATS) ||
1709f464c52Smaya            (vscreen->caps.caps.v2.host_feature_check_version < 1);
17101e04c3fSmrg   case PIPE_CAP_GLSL_FEATURE_LEVEL:
17201e04c3fSmrg      return vscreen->caps.caps.v1.glsl_level;
17301e04c3fSmrg   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
17401e04c3fSmrg      return MIN2(vscreen->caps.caps.v1.glsl_level, 140);
17501e04c3fSmrg   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
1767ec681f3Smrg      return 1;
17701e04c3fSmrg   case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
17801e04c3fSmrg      return 0;
17901e04c3fSmrg   case PIPE_CAP_COMPUTE:
18001e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COMPUTE_SHADER;
18101e04c3fSmrg   case PIPE_CAP_USER_VERTEX_BUFFERS:
18201e04c3fSmrg      return 0;
18301e04c3fSmrg   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
18401e04c3fSmrg      return vscreen->caps.caps.v2.uniform_buffer_offset_alignment;
18501e04c3fSmrg   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
18601e04c3fSmrg   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
18701e04c3fSmrg      return vscreen->caps.caps.v1.bset.streamout_pause_resume;
18801e04c3fSmrg   case PIPE_CAP_START_INSTANCE:
18901e04c3fSmrg      return vscreen->caps.caps.v1.bset.start_instance;
19001e04c3fSmrg   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
19101e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
19201e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
19301e04c3fSmrg   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
19401e04c3fSmrg   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
1957ec681f3Smrg   case PIPE_CAP_NIR_IMAGES_AS_DEREF:
19601e04c3fSmrg      return 0;
19701e04c3fSmrg   case PIPE_CAP_QUERY_TIMESTAMP:
19801e04c3fSmrg      return 1;
19901e04c3fSmrg   case PIPE_CAP_QUERY_TIME_ELAPSED:
2009f464c52Smaya      return 1;
20101e04c3fSmrg   case PIPE_CAP_TGSI_TEXCOORD:
20201e04c3fSmrg      return 0;
20301e04c3fSmrg   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
20401e04c3fSmrg      return VIRGL_MAP_BUFFER_ALIGNMENT;
20501e04c3fSmrg   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
20601e04c3fSmrg      return vscreen->caps.caps.v1.max_tbo_size > 0;
20701e04c3fSmrg   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
20801e04c3fSmrg      return vscreen->caps.caps.v2.texture_buffer_offset_alignment;
20901e04c3fSmrg   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
21001e04c3fSmrg      return 0;
21101e04c3fSmrg   case PIPE_CAP_CUBE_MAP_ARRAY:
21201e04c3fSmrg      return vscreen->caps.caps.v1.bset.cube_map_array;
21301e04c3fSmrg   case PIPE_CAP_TEXTURE_MULTISAMPLE:
21401e04c3fSmrg      return vscreen->caps.caps.v1.bset.texture_multisample;
21501e04c3fSmrg   case PIPE_CAP_MAX_VIEWPORTS:
21601e04c3fSmrg      return vscreen->caps.caps.v1.max_viewports;
21701e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
21801e04c3fSmrg      return vscreen->caps.caps.v1.max_tbo_size;
21901e04c3fSmrg   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
22001e04c3fSmrg   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
22101e04c3fSmrg   case PIPE_CAP_ENDIANNESS:
22201e04c3fSmrg      return 0;
22301e04c3fSmrg   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
22401e04c3fSmrg   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
22501e04c3fSmrg      return 1;
22601e04c3fSmrg   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
22701e04c3fSmrg      return 0;
22801e04c3fSmrg   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
22901e04c3fSmrg      return vscreen->caps.caps.v2.max_geom_output_vertices;
23001e04c3fSmrg   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
23101e04c3fSmrg      return vscreen->caps.caps.v2.max_geom_total_output_components;
23201e04c3fSmrg   case PIPE_CAP_TEXTURE_QUERY_LOD:
23301e04c3fSmrg      return vscreen->caps.caps.v1.bset.texture_query_lod;
23401e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
23501e04c3fSmrg      return vscreen->caps.caps.v1.max_texture_gather_components;
23601e04c3fSmrg   case PIPE_CAP_DRAW_INDIRECT:
23701e04c3fSmrg      return vscreen->caps.caps.v1.bset.has_indirect_draw;
23801e04c3fSmrg   case PIPE_CAP_SAMPLE_SHADING:
23901e04c3fSmrg   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
24001e04c3fSmrg      return vscreen->caps.caps.v1.bset.has_sample_shading;
24101e04c3fSmrg   case PIPE_CAP_CULL_DISTANCE:
24201e04c3fSmrg      return vscreen->caps.caps.v1.bset.has_cull;
24301e04c3fSmrg   case PIPE_CAP_MAX_VERTEX_STREAMS:
2449f464c52Smaya      return ((vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TRANSFORM_FEEDBACK3) ||
2459f464c52Smaya              (vscreen->caps.caps.v2.host_feature_check_version < 2)) ? 4 : 1;
24601e04c3fSmrg   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
24701e04c3fSmrg      return vscreen->caps.caps.v1.bset.conditional_render_inverted;
24801e04c3fSmrg   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
24901e04c3fSmrg      return vscreen->caps.caps.v1.bset.derivative_control;
25001e04c3fSmrg   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
25101e04c3fSmrg      return vscreen->caps.caps.v1.bset.polygon_offset_clamp;
25201e04c3fSmrg   case PIPE_CAP_QUERY_SO_OVERFLOW:
25301e04c3fSmrg      return vscreen->caps.caps.v1.bset.transform_feedback_overflow_query;
25401e04c3fSmrg   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
25501e04c3fSmrg      return vscreen->caps.caps.v2.shader_buffer_offset_alignment;
25601e04c3fSmrg   case PIPE_CAP_DOUBLES:
2579f464c52Smaya      return vscreen->caps.caps.v1.bset.has_fp64 ||
2589f464c52Smaya            (vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_FAKE_FP64);
25901e04c3fSmrg   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
26001e04c3fSmrg      return vscreen->caps.caps.v2.max_shader_patch_varyings;
26101e04c3fSmrg   case PIPE_CAP_SAMPLER_VIEW_TARGET:
26201e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TEXTURE_VIEW;
26301e04c3fSmrg   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
26401e04c3fSmrg      return vscreen->caps.caps.v2.max_vertex_attrib_stride;
26501e04c3fSmrg   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
26601e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COPY_IMAGE;
26701e04c3fSmrg   case PIPE_CAP_TGSI_TXQS:
26801e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TXQS;
26901e04c3fSmrg   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
27001e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_FB_NO_ATTACH;
27101e04c3fSmrg   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
27201e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_ROBUST_BUFFER_ACCESS;
2737ec681f3Smrg   case PIPE_CAP_FBFETCH:
2747ec681f3Smrg      return (vscreen->caps.caps.v2.capability_bits &
2757ec681f3Smrg              VIRGL_CAP_TGSI_FBFETCH) ? 1 : 0;
2767ec681f3Smrg   case PIPE_CAP_BLEND_EQUATION_ADVANCED:
2777ec681f3Smrg      return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_BLEND_EQUATION;
27801e04c3fSmrg   case PIPE_CAP_TGSI_CLOCK:
27901e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_SHADER_CLOCK;
28001e04c3fSmrg   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
28101e04c3fSmrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_TGSI_COMPONENTS;
28201e04c3fSmrg   case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
28301e04c3fSmrg      return vscreen->caps.caps.v2.max_combined_shader_buffers;
28401e04c3fSmrg   case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTERS:
28501e04c3fSmrg      return vscreen->caps.caps.v2.max_combined_atomic_counters;
28601e04c3fSmrg   case PIPE_CAP_MAX_COMBINED_HW_ATOMIC_COUNTER_BUFFERS:
28701e04c3fSmrg      return vscreen->caps.caps.v2.max_combined_atomic_counter_buffers;
2889f464c52Smaya   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
2899f464c52Smaya   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
2909f464c52Smaya      return 1; /* TODO: need to introduce a hw-cap for this */
2919f464c52Smaya   case PIPE_CAP_QUERY_BUFFER_OBJECT:
2929f464c52Smaya      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_QBO;
2939f464c52Smaya   case PIPE_CAP_MAX_VARYINGS:
2949f464c52Smaya      if (vscreen->caps.caps.v1.glsl_level < 150)
2959f464c52Smaya         return vscreen->caps.caps.v2.max_vertex_attribs;
2969f464c52Smaya      return 32;
2979f464c52Smaya   case PIPE_CAP_FAKE_SW_MSAA:
2989f464c52Smaya      /* If the host supports only one sample (e.g., if it is using softpipe),
2999f464c52Smaya       * fake multisampling to able to advertise higher GL versions. */
3009f464c52Smaya      return (vscreen->caps.caps.v1.max_samples == 1) ? 1 : 0;
3019f464c52Smaya   case PIPE_CAP_MULTI_DRAW_INDIRECT:
3029f464c52Smaya      return !!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_MULTI_DRAW_INDIRECT);
3039f464c52Smaya   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
3049f464c52Smaya      return !!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_INDIRECT_PARAMS);
30501e04c3fSmrg   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
3067ec681f3Smrg      return (vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_ARB_BUFFER_STORAGE) &&
3077ec681f3Smrg             (vscreen->caps.caps.v2.host_feature_check_version >= 4) &&
3087ec681f3Smrg              vscreen->vws->supports_coherent && !vscreen->no_coherent;
30901e04c3fSmrg   case PIPE_CAP_PCI_GROUP:
31001e04c3fSmrg   case PIPE_CAP_PCI_BUS:
31101e04c3fSmrg   case PIPE_CAP_PCI_DEVICE:
31201e04c3fSmrg   case PIPE_CAP_PCI_FUNCTION:
31301e04c3fSmrg   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
31401e04c3fSmrg   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
31501e04c3fSmrg      return 0;
3167ec681f3Smrg   case PIPE_CAP_CLEAR_TEXTURE:
3177ec681f3Smrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_CLEAR_TEXTURE;
3187ec681f3Smrg   case PIPE_CAP_CLIP_HALFZ:
3197ec681f3Smrg      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_CLIP_HALFZ;
32001e04c3fSmrg   case PIPE_CAP_MAX_GS_INVOCATIONS:
32101e04c3fSmrg      return 32;
32201e04c3fSmrg   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
32301e04c3fSmrg      return 1 << 27;
32401e04c3fSmrg   case PIPE_CAP_VENDOR_ID:
32501e04c3fSmrg      return 0x1af4;
32601e04c3fSmrg   case PIPE_CAP_DEVICE_ID:
32701e04c3fSmrg      return 0x1010;
32801e04c3fSmrg   case PIPE_CAP_ACCELERATED:
32901e04c3fSmrg      return 1;
33001e04c3fSmrg   case PIPE_CAP_UMA:
33101e04c3fSmrg   case PIPE_CAP_VIDEO_MEMORY:
3327ec681f3Smrg      if (vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_VIDEO_MEMORY)
3337ec681f3Smrg         return vscreen->caps.caps.v2.max_video_memory;
33401e04c3fSmrg      return 0;
33501e04c3fSmrg   case PIPE_CAP_NATIVE_FENCE_FD:
3369f464c52Smaya      return vscreen->vws->supports_fences;
3379f464c52Smaya   case PIPE_CAP_DEST_SURFACE_SRGB_CONTROL:
3389f464c52Smaya      return (vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_SRGB_WRITE_CONTROL) ||
3399f464c52Smaya            (vscreen->caps.caps.v2.host_feature_check_version < 1);
3409f464c52Smaya   case PIPE_CAP_TGSI_SKIP_SHRINK_IO_ARRAYS:
3419f464c52Smaya      return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_INDIRECT_INPUT_ADDR;
3427ec681f3Smrg   case PIPE_CAP_SHAREABLE_SHADERS:
3437ec681f3Smrg      /* Shader creation emits the shader through the context's command buffer
3447ec681f3Smrg       * in virgl_encode_shader_state().
3457ec681f3Smrg       */
3467ec681f3Smrg      return 0;
3477ec681f3Smrg   case PIPE_CAP_QUERY_MEMORY_INFO:
3487ec681f3Smrg      return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_MEMINFO;
3497ec681f3Smrg   case PIPE_CAP_STRING_MARKER:
3507ec681f3Smrg       return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_STRING_MARKER;
3517ec681f3Smrg   case PIPE_CAP_SURFACE_SAMPLE_COUNT:
3527ec681f3Smrg       return vscreen->caps.caps.v2.capability_bits_v2 & VIRGL_CAP_V2_IMPLICIT_MSAA;
35301e04c3fSmrg   default:
35401e04c3fSmrg      return u_pipe_screen_get_param_defaults(screen, param);
35501e04c3fSmrg   }
35601e04c3fSmrg}
35701e04c3fSmrg
35801e04c3fSmrgstatic int
35901e04c3fSmrgvirgl_get_shader_param(struct pipe_screen *screen,
36001e04c3fSmrg                       enum pipe_shader_type shader,
36101e04c3fSmrg                       enum pipe_shader_cap param)
36201e04c3fSmrg{
36301e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
36401e04c3fSmrg
36501e04c3fSmrg   if ((shader == PIPE_SHADER_TESS_CTRL || shader == PIPE_SHADER_TESS_EVAL) &&
36601e04c3fSmrg       !vscreen->caps.caps.v1.bset.has_tessellation_shaders)
36701e04c3fSmrg      return 0;
36801e04c3fSmrg
36901e04c3fSmrg   if (shader == PIPE_SHADER_COMPUTE &&
37001e04c3fSmrg       !(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COMPUTE_SHADER))
37101e04c3fSmrg     return 0;
37201e04c3fSmrg
37301e04c3fSmrg   switch(shader)
37401e04c3fSmrg   {
37501e04c3fSmrg   case PIPE_SHADER_FRAGMENT:
37601e04c3fSmrg   case PIPE_SHADER_VERTEX:
37701e04c3fSmrg   case PIPE_SHADER_GEOMETRY:
37801e04c3fSmrg   case PIPE_SHADER_TESS_CTRL:
37901e04c3fSmrg   case PIPE_SHADER_TESS_EVAL:
38001e04c3fSmrg   case PIPE_SHADER_COMPUTE:
38101e04c3fSmrg      switch (param) {
38201e04c3fSmrg      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
38301e04c3fSmrg      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
38401e04c3fSmrg      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
38501e04c3fSmrg      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
38601e04c3fSmrg         return INT_MAX;
38701e04c3fSmrg      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
38801e04c3fSmrg      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
38901e04c3fSmrg      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
39001e04c3fSmrg         return 1;
3919f464c52Smaya      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
3929f464c52Smaya      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
3939f464c52Smaya         return vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_INDIRECT_INPUT_ADDR;
39401e04c3fSmrg      case PIPE_SHADER_CAP_MAX_INPUTS:
39501e04c3fSmrg         if (vscreen->caps.caps.v1.glsl_level < 150)
39601e04c3fSmrg            return vscreen->caps.caps.v2.max_vertex_attribs;
39701e04c3fSmrg         return (shader == PIPE_SHADER_VERTEX ||
39801e04c3fSmrg                 shader == PIPE_SHADER_GEOMETRY) ? vscreen->caps.caps.v2.max_vertex_attribs : 32;
39901e04c3fSmrg      case PIPE_SHADER_CAP_MAX_OUTPUTS:
40001e04c3fSmrg         if (shader == PIPE_SHADER_FRAGMENT)
40101e04c3fSmrg            return vscreen->caps.caps.v1.max_render_targets;
40201e04c3fSmrg         return vscreen->caps.caps.v2.max_vertex_outputs;
40301e04c3fSmrg     // case PIPE_SHADER_CAP_MAX_CONSTS:
40401e04c3fSmrg     //    return 4096;
40501e04c3fSmrg      case PIPE_SHADER_CAP_MAX_TEMPS:
40601e04c3fSmrg         return 256;
40701e04c3fSmrg      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
40801e04c3fSmrg         return vscreen->caps.caps.v1.max_uniform_blocks;
40901e04c3fSmrg    //  case PIPE_SHADER_CAP_MAX_ADDRS:
41001e04c3fSmrg     //    return 1;
41101e04c3fSmrg      case PIPE_SHADER_CAP_SUBROUTINES:
41201e04c3fSmrg         return 1;
41301e04c3fSmrg      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
41401e04c3fSmrg            return 16;
41501e04c3fSmrg      case PIPE_SHADER_CAP_INTEGERS:
41601e04c3fSmrg         return vscreen->caps.caps.v1.glsl_level >= 130;
41701e04c3fSmrg      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
41801e04c3fSmrg         return 32;
41901e04c3fSmrg      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
42001e04c3fSmrg         return 4096 * sizeof(float[4]);
42101e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
42201e04c3fSmrg         if (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE)
42301e04c3fSmrg            return vscreen->caps.caps.v2.max_shader_buffer_frag_compute;
42401e04c3fSmrg         else
42501e04c3fSmrg            return vscreen->caps.caps.v2.max_shader_buffer_other_stages;
42601e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
42701e04c3fSmrg         if (shader == PIPE_SHADER_FRAGMENT || shader == PIPE_SHADER_COMPUTE)
42801e04c3fSmrg            return vscreen->caps.caps.v2.max_shader_image_frag_compute;
42901e04c3fSmrg         else
43001e04c3fSmrg            return vscreen->caps.caps.v2.max_shader_image_other_stages;
4317ec681f3Smrg      case PIPE_SHADER_CAP_PREFERRED_IR:
4327ec681f3Smrg         return (virgl_debug & VIRGL_DEBUG_NIR) ? PIPE_SHADER_IR_NIR : PIPE_SHADER_IR_TGSI;
43301e04c3fSmrg      case PIPE_SHADER_CAP_SUPPORTED_IRS:
4347ec681f3Smrg         return (1 << PIPE_SHADER_IR_TGSI) | ((virgl_debug & VIRGL_DEBUG_NIR) ? (1 << PIPE_SHADER_IR_NIR) : 0);
43501e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
43601e04c3fSmrg         return vscreen->caps.caps.v2.max_atomic_counters[shader];
43701e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
43801e04c3fSmrg         return vscreen->caps.caps.v2.max_atomic_counter_buffers[shader];
43901e04c3fSmrg      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
44001e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
44101e04c3fSmrg      case PIPE_SHADER_CAP_INT64_ATOMICS:
44201e04c3fSmrg      case PIPE_SHADER_CAP_FP16:
4437ec681f3Smrg      case PIPE_SHADER_CAP_FP16_DERIVATIVES:
4447ec681f3Smrg      case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
4457ec681f3Smrg      case PIPE_SHADER_CAP_INT16:
4467ec681f3Smrg      case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
44701e04c3fSmrg         return 0;
44801e04c3fSmrg      default:
44901e04c3fSmrg         return 0;
45001e04c3fSmrg      }
45101e04c3fSmrg   default:
45201e04c3fSmrg      return 0;
45301e04c3fSmrg   }
45401e04c3fSmrg}
45501e04c3fSmrg
45601e04c3fSmrgstatic float
45701e04c3fSmrgvirgl_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
45801e04c3fSmrg{
45901e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
46001e04c3fSmrg   switch (param) {
46101e04c3fSmrg   case PIPE_CAPF_MAX_LINE_WIDTH:
46201e04c3fSmrg      return vscreen->caps.caps.v2.max_aliased_line_width;
46301e04c3fSmrg   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
46401e04c3fSmrg      return vscreen->caps.caps.v2.max_smooth_line_width;
46501e04c3fSmrg   case PIPE_CAPF_MAX_POINT_WIDTH:
46601e04c3fSmrg      return vscreen->caps.caps.v2.max_aliased_point_size;
46701e04c3fSmrg   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
46801e04c3fSmrg      return vscreen->caps.caps.v2.max_smooth_point_size;
46901e04c3fSmrg   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
4707ec681f3Smrg      return vscreen->caps.caps.v2.max_anisotropy;
47101e04c3fSmrg   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
47201e04c3fSmrg      return vscreen->caps.caps.v2.max_texture_lod_bias;
47301e04c3fSmrg   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
47401e04c3fSmrg   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
47501e04c3fSmrg   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
47601e04c3fSmrg      return 0.0f;
47701e04c3fSmrg   }
47801e04c3fSmrg   /* should only get here on unhandled cases */
47901e04c3fSmrg   debug_printf("Unexpected PIPE_CAPF %d query\n", param);
48001e04c3fSmrg   return 0.0;
48101e04c3fSmrg}
48201e04c3fSmrg
48301e04c3fSmrgstatic int
48401e04c3fSmrgvirgl_get_compute_param(struct pipe_screen *screen,
48501e04c3fSmrg                        enum pipe_shader_ir ir_type,
48601e04c3fSmrg                        enum pipe_compute_cap param,
48701e04c3fSmrg                        void *ret)
48801e04c3fSmrg{
48901e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
49001e04c3fSmrg   if (!(vscreen->caps.caps.v2.capability_bits & VIRGL_CAP_COMPUTE_SHADER))
49101e04c3fSmrg      return 0;
49201e04c3fSmrg   switch (param) {
49301e04c3fSmrg   case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
49401e04c3fSmrg      if (ret) {
49501e04c3fSmrg         uint64_t *grid_size = ret;
49601e04c3fSmrg         grid_size[0] = vscreen->caps.caps.v2.max_compute_grid_size[0];
49701e04c3fSmrg         grid_size[1] = vscreen->caps.caps.v2.max_compute_grid_size[1];
49801e04c3fSmrg         grid_size[2] = vscreen->caps.caps.v2.max_compute_grid_size[2];
49901e04c3fSmrg      }
50001e04c3fSmrg      return 3 * sizeof(uint64_t) ;
50101e04c3fSmrg   case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
50201e04c3fSmrg      if (ret) {
50301e04c3fSmrg         uint64_t *block_size = ret;
50401e04c3fSmrg         block_size[0] = vscreen->caps.caps.v2.max_compute_block_size[0];
50501e04c3fSmrg         block_size[1] = vscreen->caps.caps.v2.max_compute_block_size[1];
50601e04c3fSmrg         block_size[2] = vscreen->caps.caps.v2.max_compute_block_size[2];
50701e04c3fSmrg      }
50801e04c3fSmrg      return 3 * sizeof(uint64_t);
50901e04c3fSmrg   case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
51001e04c3fSmrg      if (ret) {
51101e04c3fSmrg         uint64_t *max_threads_per_block = ret;
51201e04c3fSmrg         *max_threads_per_block = vscreen->caps.caps.v2.max_compute_work_group_invocations;
51301e04c3fSmrg      }
51401e04c3fSmrg      return sizeof(uint64_t);
51501e04c3fSmrg   case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
51601e04c3fSmrg      if (ret) {
51701e04c3fSmrg         uint64_t *max_local_size = ret;
51801e04c3fSmrg         /* Value reported by the closed source driver. */
51901e04c3fSmrg         *max_local_size = vscreen->caps.caps.v2.max_compute_shared_memory_size;
52001e04c3fSmrg      }
52101e04c3fSmrg      return sizeof(uint64_t);
52201e04c3fSmrg   default:
52301e04c3fSmrg      break;
52401e04c3fSmrg   }
52501e04c3fSmrg   return 0;
52601e04c3fSmrg}
52701e04c3fSmrg
5287ec681f3Smrgstatic bool
5299f464c52Smayahas_format_bit(struct virgl_supported_format_mask *mask,
5309f464c52Smaya               enum virgl_formats fmt)
5319f464c52Smaya{
5329f464c52Smaya   assert(fmt < VIRGL_FORMAT_MAX);
5339f464c52Smaya   unsigned val = (unsigned)fmt;
5349f464c52Smaya   unsigned idx = val / 32;
5359f464c52Smaya   unsigned bit = val % 32;
5369f464c52Smaya   assert(idx < ARRAY_SIZE(mask->bitmask));
5377ec681f3Smrg   return (mask->bitmask[idx] & (1u << bit)) != 0;
5389f464c52Smaya}
5399f464c52Smaya
5407ec681f3Smrgbool
5419f464c52Smayavirgl_has_readback_format(struct pipe_screen *screen,
5429f464c52Smaya                          enum virgl_formats fmt)
5439f464c52Smaya{
5449f464c52Smaya   struct virgl_screen *vscreen = virgl_screen(screen);
5459f464c52Smaya   return has_format_bit(&vscreen->caps.caps.v2.supported_readback_formats,
5469f464c52Smaya                         fmt);
5479f464c52Smaya}
5489f464c52Smaya
5497ec681f3Smrgstatic bool
55001e04c3fSmrgvirgl_is_vertex_format_supported(struct pipe_screen *screen,
55101e04c3fSmrg                                 enum pipe_format format)
55201e04c3fSmrg{
55301e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
55401e04c3fSmrg   const struct util_format_description *format_desc;
55501e04c3fSmrg   int i;
55601e04c3fSmrg
55701e04c3fSmrg   format_desc = util_format_description(format);
55801e04c3fSmrg   if (!format_desc)
5597ec681f3Smrg      return false;
56001e04c3fSmrg
56101e04c3fSmrg   if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
56201e04c3fSmrg      int vformat = VIRGL_FORMAT_R11G11B10_FLOAT;
56301e04c3fSmrg      int big = vformat / 32;
56401e04c3fSmrg      int small = vformat % 32;
56501e04c3fSmrg      if (!(vscreen->caps.caps.v1.vertexbuffer.bitmask[big] & (1 << small)))
5667ec681f3Smrg         return false;
5677ec681f3Smrg      return true;
56801e04c3fSmrg   }
56901e04c3fSmrg
57001e04c3fSmrg   /* Find the first non-VOID channel. */
57101e04c3fSmrg   for (i = 0; i < 4; i++) {
57201e04c3fSmrg      if (format_desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
57301e04c3fSmrg         break;
57401e04c3fSmrg      }
57501e04c3fSmrg   }
57601e04c3fSmrg
57701e04c3fSmrg   if (i == 4)
5787ec681f3Smrg      return false;
57901e04c3fSmrg
58001e04c3fSmrg   if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
5817ec681f3Smrg      return false;
58201e04c3fSmrg
58301e04c3fSmrg   if (format_desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
5847ec681f3Smrg      return false;
5857ec681f3Smrg   return true;
5867ec681f3Smrg}
5877ec681f3Smrg
5887ec681f3Smrgstatic bool
5897ec681f3Smrgvirgl_format_check_bitmask(enum pipe_format format,
5907ec681f3Smrg                           uint32_t bitmask[16],
5917ec681f3Smrg                           bool may_emulate_bgra)
5927ec681f3Smrg{
5937ec681f3Smrg   enum virgl_formats vformat = pipe_to_virgl_format(format);
5947ec681f3Smrg   int big = vformat / 32;
5957ec681f3Smrg   int small = vformat % 32;
5967ec681f3Smrg   if ((bitmask[big] & (1 << small)))
5977ec681f3Smrg      return true;
5987ec681f3Smrg
5997ec681f3Smrg   /* On GLES hosts we don't advertise BGRx_SRGB, but we may be able
6007ec681f3Smrg    * emulate it by using a swizzled RGBx */
6017ec681f3Smrg   if (may_emulate_bgra) {
6027ec681f3Smrg      if (format == PIPE_FORMAT_B8G8R8A8_SRGB)
6037ec681f3Smrg         format = PIPE_FORMAT_R8G8B8A8_SRGB;
6047ec681f3Smrg      else if (format == PIPE_FORMAT_B8G8R8X8_SRGB)
6057ec681f3Smrg         format = PIPE_FORMAT_R8G8B8X8_SRGB;
6067ec681f3Smrg      else {
6077ec681f3Smrg         return false;
6087ec681f3Smrg      }
6097ec681f3Smrg
6107ec681f3Smrg      vformat = pipe_to_virgl_format(format);
6117ec681f3Smrg      big = vformat / 32;
6127ec681f3Smrg      small = vformat % 32;
6137ec681f3Smrg      if (bitmask[big] & (1 << small))
6147ec681f3Smrg         return true;
6157ec681f3Smrg   }
6167ec681f3Smrg   return false;
61701e04c3fSmrg}
61801e04c3fSmrg
61901e04c3fSmrg/**
62001e04c3fSmrg * Query format support for creating a texture, drawing surface, etc.
62101e04c3fSmrg * \param format  the format to test
62201e04c3fSmrg * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
62301e04c3fSmrg */
6247ec681f3Smrgstatic bool
62501e04c3fSmrgvirgl_is_format_supported( struct pipe_screen *screen,
62601e04c3fSmrg                                 enum pipe_format format,
62701e04c3fSmrg                                 enum pipe_texture_target target,
62801e04c3fSmrg                                 unsigned sample_count,
62901e04c3fSmrg                                 unsigned storage_sample_count,
63001e04c3fSmrg                                 unsigned bind)
63101e04c3fSmrg{
63201e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
63301e04c3fSmrg   const struct util_format_description *format_desc;
63401e04c3fSmrg   int i;
63501e04c3fSmrg
6367ec681f3Smrg   union virgl_caps *caps = &vscreen->caps.caps;
6377ec681f3Smrg   boolean may_emulate_bgra = (caps->v2.capability_bits &
6387ec681f3Smrg                               VIRGL_CAP_APP_TWEAK_SUPPORT) &&
6397ec681f3Smrg                               vscreen->tweak_gles_emulate_bgra;
6407ec681f3Smrg
64101e04c3fSmrg   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
64201e04c3fSmrg      return false;
64301e04c3fSmrg
6447ec681f3Smrg   if (!util_is_power_of_two_or_zero(sample_count))
6457ec681f3Smrg      return false;
6467ec681f3Smrg
64701e04c3fSmrg   assert(target == PIPE_BUFFER ||
64801e04c3fSmrg          target == PIPE_TEXTURE_1D ||
64901e04c3fSmrg          target == PIPE_TEXTURE_1D_ARRAY ||
65001e04c3fSmrg          target == PIPE_TEXTURE_2D ||
65101e04c3fSmrg          target == PIPE_TEXTURE_2D_ARRAY ||
65201e04c3fSmrg          target == PIPE_TEXTURE_RECT ||
65301e04c3fSmrg          target == PIPE_TEXTURE_3D ||
65401e04c3fSmrg          target == PIPE_TEXTURE_CUBE ||
65501e04c3fSmrg          target == PIPE_TEXTURE_CUBE_ARRAY);
65601e04c3fSmrg
65701e04c3fSmrg   format_desc = util_format_description(format);
65801e04c3fSmrg   if (!format_desc)
6597ec681f3Smrg      return false;
66001e04c3fSmrg
66101e04c3fSmrg   if (util_format_is_intensity(format))
6627ec681f3Smrg      return false;
66301e04c3fSmrg
66401e04c3fSmrg   if (sample_count > 1) {
6657ec681f3Smrg      if (!caps->v1.bset.texture_multisample)
6667ec681f3Smrg         return false;
66701e04c3fSmrg
66801e04c3fSmrg      if (bind & PIPE_BIND_SHADER_IMAGE) {
6697ec681f3Smrg         if (sample_count > caps->v2.max_image_samples)
6707ec681f3Smrg            return false;
67101e04c3fSmrg      }
67201e04c3fSmrg
6737ec681f3Smrg      if (sample_count > caps->v1.max_samples)
6747ec681f3Smrg         return false;
67501e04c3fSmrg   }
67601e04c3fSmrg
67701e04c3fSmrg   if (bind & PIPE_BIND_VERTEX_BUFFER) {
67801e04c3fSmrg      return virgl_is_vertex_format_supported(screen, format);
67901e04c3fSmrg   }
68001e04c3fSmrg
6819f464c52Smaya   if (util_format_is_compressed(format) && target == PIPE_BUFFER)
6827ec681f3Smrg      return false;
6839f464c52Smaya
68401e04c3fSmrg   /* Allow 3-comp 32 bit textures only for TBOs (needed for ARB_tbo_rgb32) */
68501e04c3fSmrg   if ((format == PIPE_FORMAT_R32G32B32_FLOAT ||
68601e04c3fSmrg       format == PIPE_FORMAT_R32G32B32_SINT ||
68701e04c3fSmrg       format == PIPE_FORMAT_R32G32B32_UINT) &&
68801e04c3fSmrg       target != PIPE_BUFFER)
6897ec681f3Smrg      return false;
69001e04c3fSmrg
6919f464c52Smaya   if ((format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC ||
6929f464c52Smaya        format_desc->layout == UTIL_FORMAT_LAYOUT_ETC ||
6939f464c52Smaya        format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) &&
6949f464c52Smaya       target == PIPE_TEXTURE_3D)
6957ec681f3Smrg      return false;
6967ec681f3Smrg
6979f464c52Smaya
69801e04c3fSmrg   if (bind & PIPE_BIND_RENDER_TARGET) {
69901e04c3fSmrg      /* For ARB_framebuffer_no_attachments. */
70001e04c3fSmrg      if (format == PIPE_FORMAT_NONE)
70101e04c3fSmrg         return TRUE;
70201e04c3fSmrg
70301e04c3fSmrg      if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
7047ec681f3Smrg         return false;
70501e04c3fSmrg
70601e04c3fSmrg      /*
70701e04c3fSmrg       * Although possible, it is unnatural to render into compressed or YUV
70801e04c3fSmrg       * surfaces. So disable these here to avoid going into weird paths
7097ec681f3Smrg       * inside gallium frontends.
71001e04c3fSmrg       */
71101e04c3fSmrg      if (format_desc->block.width != 1 ||
71201e04c3fSmrg          format_desc->block.height != 1)
7137ec681f3Smrg         return false;
71401e04c3fSmrg
7157ec681f3Smrg      if (!virgl_format_check_bitmask(format,
7167ec681f3Smrg                                      caps->v1.render.bitmask,
7177ec681f3Smrg                                      may_emulate_bgra))
7187ec681f3Smrg         return false;
71901e04c3fSmrg   }
72001e04c3fSmrg
72101e04c3fSmrg   if (bind & PIPE_BIND_DEPTH_STENCIL) {
72201e04c3fSmrg      if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
7237ec681f3Smrg         return false;
7247ec681f3Smrg   }
7257ec681f3Smrg
7267ec681f3Smrg   if (bind & PIPE_BIND_SCANOUT) {
7277ec681f3Smrg      if (!virgl_format_check_bitmask(format, caps->v2.scanout.bitmask, false))
7287ec681f3Smrg         return false;
72901e04c3fSmrg   }
73001e04c3fSmrg
73101e04c3fSmrg   /*
73201e04c3fSmrg    * All other operations (sampling, transfer, etc).
73301e04c3fSmrg    */
73401e04c3fSmrg
73501e04c3fSmrg   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
73601e04c3fSmrg      goto out_lookup;
73701e04c3fSmrg   }
73801e04c3fSmrg   if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
73901e04c3fSmrg      goto out_lookup;
74001e04c3fSmrg   }
74101e04c3fSmrg   if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
74201e04c3fSmrg      goto out_lookup;
74301e04c3fSmrg   }
7447ec681f3Smrg   if (format_desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
7457ec681f3Smrg      goto out_lookup;
7467ec681f3Smrg   }
74701e04c3fSmrg
74801e04c3fSmrg   if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
74901e04c3fSmrg      goto out_lookup;
75001e04c3fSmrg   } else if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
75101e04c3fSmrg      goto out_lookup;
75201e04c3fSmrg   }
75301e04c3fSmrg
7547ec681f3Smrg   if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
7557ec681f3Smrg     goto out_lookup;
7567ec681f3Smrg   }
7577ec681f3Smrg
75801e04c3fSmrg   /* Find the first non-VOID channel. */
75901e04c3fSmrg   for (i = 0; i < 4; i++) {
76001e04c3fSmrg      if (format_desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
76101e04c3fSmrg         break;
76201e04c3fSmrg      }
76301e04c3fSmrg   }
76401e04c3fSmrg
76501e04c3fSmrg   if (i == 4)
7667ec681f3Smrg      return false;
76701e04c3fSmrg
76801e04c3fSmrg   /* no L4A4 */
76901e04c3fSmrg   if (format_desc->nr_channels < 4 && format_desc->channel[i].size == 4)
7707ec681f3Smrg      return false;
77101e04c3fSmrg
77201e04c3fSmrg out_lookup:
7737ec681f3Smrg   return virgl_format_check_bitmask(format,
7747ec681f3Smrg                                     caps->v1.sampler.bitmask,
7757ec681f3Smrg                                     may_emulate_bgra);
77601e04c3fSmrg}
77701e04c3fSmrg
77801e04c3fSmrgstatic void virgl_flush_frontbuffer(struct pipe_screen *screen,
7797ec681f3Smrg                                    struct pipe_context *ctx,
78001e04c3fSmrg                                      struct pipe_resource *res,
78101e04c3fSmrg                                      unsigned level, unsigned layer,
78201e04c3fSmrg                                    void *winsys_drawable_handle, struct pipe_box *sub_box)
78301e04c3fSmrg{
78401e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
78501e04c3fSmrg   struct virgl_winsys *vws = vscreen->vws;
78601e04c3fSmrg   struct virgl_resource *vres = virgl_resource(res);
78701e04c3fSmrg
78801e04c3fSmrg   if (vws->flush_frontbuffer)
78901e04c3fSmrg      vws->flush_frontbuffer(vws, vres->hw_res, level, layer, winsys_drawable_handle,
79001e04c3fSmrg                             sub_box);
79101e04c3fSmrg}
79201e04c3fSmrg
79301e04c3fSmrgstatic void virgl_fence_reference(struct pipe_screen *screen,
79401e04c3fSmrg                                  struct pipe_fence_handle **ptr,
79501e04c3fSmrg                                  struct pipe_fence_handle *fence)
79601e04c3fSmrg{
79701e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
79801e04c3fSmrg   struct virgl_winsys *vws = vscreen->vws;
79901e04c3fSmrg
80001e04c3fSmrg   vws->fence_reference(vws, ptr, fence);
80101e04c3fSmrg}
80201e04c3fSmrg
8037ec681f3Smrgstatic bool virgl_fence_finish(struct pipe_screen *screen,
8047ec681f3Smrg                               struct pipe_context *ctx,
8057ec681f3Smrg                               struct pipe_fence_handle *fence,
8067ec681f3Smrg                               uint64_t timeout)
80701e04c3fSmrg{
80801e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
80901e04c3fSmrg   struct virgl_winsys *vws = vscreen->vws;
8107ec681f3Smrg   struct virgl_context *vctx = virgl_context(ctx);
8117ec681f3Smrg
8127ec681f3Smrg   if (vctx && timeout)
8137ec681f3Smrg      virgl_flush_eq(vctx, NULL, NULL);
81401e04c3fSmrg
81501e04c3fSmrg   return vws->fence_wait(vws, fence, timeout);
81601e04c3fSmrg}
81701e04c3fSmrg
8189f464c52Smayastatic int virgl_fence_get_fd(struct pipe_screen *screen,
8199f464c52Smaya            struct pipe_fence_handle *fence)
8209f464c52Smaya{
8219f464c52Smaya   struct virgl_screen *vscreen = virgl_screen(screen);
8229f464c52Smaya   struct virgl_winsys *vws = vscreen->vws;
8239f464c52Smaya
8249f464c52Smaya   return vws->fence_get_fd(vws, fence);
8259f464c52Smaya}
8269f464c52Smaya
82701e04c3fSmrgstatic uint64_t
82801e04c3fSmrgvirgl_get_timestamp(struct pipe_screen *_screen)
82901e04c3fSmrg{
83001e04c3fSmrg   return os_time_get_nano();
83101e04c3fSmrg}
83201e04c3fSmrg
83301e04c3fSmrgstatic void
83401e04c3fSmrgvirgl_destroy_screen(struct pipe_screen *screen)
83501e04c3fSmrg{
83601e04c3fSmrg   struct virgl_screen *vscreen = virgl_screen(screen);
83701e04c3fSmrg   struct virgl_winsys *vws = vscreen->vws;
83801e04c3fSmrg
8399f464c52Smaya   slab_destroy_parent(&vscreen->transfer_pool);
84001e04c3fSmrg
84101e04c3fSmrg   if (vws)
84201e04c3fSmrg      vws->destroy(vws);
8437ec681f3Smrg
8447ec681f3Smrg   disk_cache_destroy(vscreen->disk_cache);
8457ec681f3Smrg
84601e04c3fSmrg   FREE(vscreen);
84701e04c3fSmrg}
84801e04c3fSmrg
8499f464c52Smayastatic void
8507ec681f3Smrgfixup_formats(union virgl_caps *caps, struct virgl_supported_format_mask *mask)
8519f464c52Smaya{
8527ec681f3Smrg   const size_t size = ARRAY_SIZE(mask->bitmask);
8539f464c52Smaya   for (int i = 0; i < size; ++i) {
8547ec681f3Smrg      if (mask->bitmask[i] != 0)
8557ec681f3Smrg         return; /* we got some formats, we definitely have a new protocol */
8569f464c52Smaya   }
8579f464c52Smaya
8589f464c52Smaya   /* old protocol used; fall back to considering all sampleable formats valid
8599f464c52Smaya    * readback-formats
8609f464c52Smaya    */
8617ec681f3Smrg   for (int i = 0; i < size; ++i)
8627ec681f3Smrg      mask->bitmask[i] = caps->v1.sampler.bitmask[i];
8637ec681f3Smrg}
8647ec681f3Smrg
8657ec681f3Smrgstatic void virgl_query_memory_info(struct pipe_screen *screen, struct pipe_memory_info *info)
8667ec681f3Smrg{
8677ec681f3Smrg   struct virgl_screen *vscreen = virgl_screen(screen);
8687ec681f3Smrg   struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
8697ec681f3Smrg   struct virgl_context *vctx = virgl_context(ctx);
8707ec681f3Smrg   struct virgl_resource *res;
8717ec681f3Smrg   struct virgl_memory_info virgl_info = {0};
8727ec681f3Smrg   const static struct pipe_resource templ = {
8737ec681f3Smrg      .target = PIPE_BUFFER,
8747ec681f3Smrg      .format = PIPE_FORMAT_R8_UNORM,
8757ec681f3Smrg      .bind = PIPE_BIND_CUSTOM,
8767ec681f3Smrg      .width0 = sizeof(struct virgl_memory_info),
8777ec681f3Smrg      .height0 = 1,
8787ec681f3Smrg      .depth0 = 1,
8797ec681f3Smrg      .array_size = 1,
8807ec681f3Smrg      .last_level = 0,
8817ec681f3Smrg      .nr_samples = 0,
8827ec681f3Smrg      .flags = 0
8837ec681f3Smrg   };
8847ec681f3Smrg
8857ec681f3Smrg   res = (struct virgl_resource*) screen->resource_create(screen, &templ);
8867ec681f3Smrg
8877ec681f3Smrg   virgl_encode_get_memory_info(vctx, res);
8887ec681f3Smrg   ctx->flush(ctx, NULL, 0);
8897ec681f3Smrg   vscreen->vws->resource_wait(vscreen->vws, res->hw_res);
8907ec681f3Smrg   pipe_buffer_read(ctx, &res->b, 0, sizeof(struct virgl_memory_info), &virgl_info);
8917ec681f3Smrg
8927ec681f3Smrg   info->avail_device_memory = virgl_info.avail_device_memory;
8937ec681f3Smrg   info->avail_staging_memory = virgl_info.avail_staging_memory;
8947ec681f3Smrg   info->device_memory_evicted = virgl_info.device_memory_evicted;
8957ec681f3Smrg   info->nr_device_memory_evictions = virgl_info.nr_device_memory_evictions;
8967ec681f3Smrg   info->total_device_memory = virgl_info.total_device_memory;
8977ec681f3Smrg   info->total_staging_memory = virgl_info.total_staging_memory;
8987ec681f3Smrg
8997ec681f3Smrg   screen->resource_destroy(screen, &res->b);
9007ec681f3Smrg   ctx->destroy(ctx);
9017ec681f3Smrg}
9027ec681f3Smrg
9037ec681f3Smrgstatic struct disk_cache *virgl_get_disk_shader_cache (struct pipe_screen *pscreen)
9047ec681f3Smrg{
9057ec681f3Smrg   struct virgl_screen *screen = virgl_screen(pscreen);
9067ec681f3Smrg
9077ec681f3Smrg   return screen->disk_cache;
9087ec681f3Smrg}
9097ec681f3Smrg
9107ec681f3Smrgstatic void virgl_disk_cache_create(struct virgl_screen *screen)
9117ec681f3Smrg{
9127ec681f3Smrg   const struct build_id_note *note =
9137ec681f3Smrg      build_id_find_nhdr_for_addr(virgl_disk_cache_create);
9147ec681f3Smrg   unsigned build_id_len = build_id_length(note);
9157ec681f3Smrg   assert(note && build_id_len == 20); /* sha1 */
9167ec681f3Smrg
9177ec681f3Smrg   const uint8_t *id_sha1 = build_id_data(note);
9187ec681f3Smrg   assert(id_sha1);
9197ec681f3Smrg
9207ec681f3Smrg   struct mesa_sha1 sha1_ctx;
9217ec681f3Smrg   _mesa_sha1_init(&sha1_ctx);
9227ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, id_sha1, build_id_len);
9237ec681f3Smrg
9247ec681f3Smrg   uint32_t shader_debug_flags = virgl_debug & VIRGL_DEBUG_NIR;
9257ec681f3Smrg   _mesa_sha1_update(&sha1_ctx, &shader_debug_flags, sizeof(shader_debug_flags));
9267ec681f3Smrg
9277ec681f3Smrg   uint8_t sha1[20];
9287ec681f3Smrg   _mesa_sha1_final(&sha1_ctx, sha1);
9297ec681f3Smrg   char timestamp[41];
9307ec681f3Smrg   _mesa_sha1_format(timestamp, sha1);
9317ec681f3Smrg
9327ec681f3Smrg   screen->disk_cache = disk_cache_create("virgl", timestamp, 0);
9337ec681f3Smrg}
9347ec681f3Smrg
9357ec681f3Smrgstatic void
9367ec681f3Smrgfixup_renderer(union virgl_caps *caps)
9377ec681f3Smrg{
9387ec681f3Smrg   if (caps->v2.host_feature_check_version < 5)
9397ec681f3Smrg      return;
9407ec681f3Smrg
9417ec681f3Smrg   char renderer[64];
9427ec681f3Smrg   int renderer_len = snprintf(renderer, sizeof(renderer), "virgl (%s)",
9437ec681f3Smrg                               caps->v2.renderer);
9447ec681f3Smrg   if (renderer_len >= 64) {
9457ec681f3Smrg      memcpy(renderer + 59, "...)", 4);
9467ec681f3Smrg      renderer_len = 63;
9479f464c52Smaya   }
9487ec681f3Smrg   memcpy(caps->v2.renderer, renderer, renderer_len + 1);
9499f464c52Smaya}
9509f464c52Smaya
95101e04c3fSmrgstruct pipe_screen *
9527ec681f3Smrgvirgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *config)
95301e04c3fSmrg{
95401e04c3fSmrg   struct virgl_screen *screen = CALLOC_STRUCT(virgl_screen);
95501e04c3fSmrg
9567ec681f3Smrg   const char *VIRGL_GLES_EMULATE_BGRA = "gles_emulate_bgra";
9577ec681f3Smrg   const char *VIRGL_GLES_APPLY_BGRA_DEST_SWIZZLE = "gles_apply_bgra_dest_swizzle";
9587ec681f3Smrg   const char *VIRGL_GLES_SAMPLES_PASSED_VALUE = "gles_samples_passed_value";
9597ec681f3Smrg
96001e04c3fSmrg   if (!screen)
96101e04c3fSmrg      return NULL;
96201e04c3fSmrg
96301e04c3fSmrg   virgl_debug = debug_get_option_virgl_debug();
96401e04c3fSmrg
9657ec681f3Smrg   if (config && config->options) {
9667ec681f3Smrg      driParseConfigFiles(config->options, config->options_info, 0, "virtio_gpu",
9677ec681f3Smrg                          NULL, NULL, NULL, 0, NULL, 0);
9687ec681f3Smrg
9697ec681f3Smrg      screen->tweak_gles_emulate_bgra =
9707ec681f3Smrg            driQueryOptionb(config->options, VIRGL_GLES_EMULATE_BGRA);
9717ec681f3Smrg      screen->tweak_gles_apply_bgra_dest_swizzle =
9727ec681f3Smrg            driQueryOptionb(config->options, VIRGL_GLES_APPLY_BGRA_DEST_SWIZZLE);
9737ec681f3Smrg      screen->tweak_gles_tf3_value =
9747ec681f3Smrg            driQueryOptioni(config->options, VIRGL_GLES_SAMPLES_PASSED_VALUE);
9757ec681f3Smrg   }
9767ec681f3Smrg   screen->tweak_gles_emulate_bgra &= !(virgl_debug & VIRGL_DEBUG_NO_EMULATE_BGRA);
9777ec681f3Smrg   screen->tweak_gles_apply_bgra_dest_swizzle &= !(virgl_debug & VIRGL_DEBUG_NO_BGRA_DEST_SWIZZLE);
9787ec681f3Smrg   screen->no_coherent = virgl_debug & VIRGL_DEBUG_NO_COHERENT;
9797ec681f3Smrg
98001e04c3fSmrg   screen->vws = vws;
98101e04c3fSmrg   screen->base.get_name = virgl_get_name;
98201e04c3fSmrg   screen->base.get_vendor = virgl_get_vendor;
98301e04c3fSmrg   screen->base.get_param = virgl_get_param;
98401e04c3fSmrg   screen->base.get_shader_param = virgl_get_shader_param;
98501e04c3fSmrg   screen->base.get_compute_param = virgl_get_compute_param;
98601e04c3fSmrg   screen->base.get_paramf = virgl_get_paramf;
9877ec681f3Smrg   screen->base.get_compiler_options = nir_to_tgsi_get_compiler_options;
98801e04c3fSmrg   screen->base.is_format_supported = virgl_is_format_supported;
98901e04c3fSmrg   screen->base.destroy = virgl_destroy_screen;
99001e04c3fSmrg   screen->base.context_create = virgl_context_create;
99101e04c3fSmrg   screen->base.flush_frontbuffer = virgl_flush_frontbuffer;
99201e04c3fSmrg   screen->base.get_timestamp = virgl_get_timestamp;
99301e04c3fSmrg   screen->base.fence_reference = virgl_fence_reference;
99401e04c3fSmrg   //screen->base.fence_signalled = virgl_fence_signalled;
99501e04c3fSmrg   screen->base.fence_finish = virgl_fence_finish;
9969f464c52Smaya   screen->base.fence_get_fd = virgl_fence_get_fd;
9977ec681f3Smrg   screen->base.query_memory_info = virgl_query_memory_info;
9987ec681f3Smrg   screen->base.get_disk_shader_cache = virgl_get_disk_shader_cache;
99901e04c3fSmrg
100001e04c3fSmrg   virgl_init_screen_resource_functions(&screen->base);
100101e04c3fSmrg
100201e04c3fSmrg   vws->get_caps(vws, &screen->caps);
10037ec681f3Smrg   fixup_formats(&screen->caps.caps,
10047ec681f3Smrg                 &screen->caps.caps.v2.supported_readback_formats);
10057ec681f3Smrg   fixup_formats(&screen->caps.caps, &screen->caps.caps.v2.scanout);
10067ec681f3Smrg   fixup_renderer(&screen->caps.caps);
100701e04c3fSmrg
10087ec681f3Smrg   union virgl_caps *caps = &screen->caps.caps;
10097ec681f3Smrg   screen->tweak_gles_emulate_bgra &= !virgl_format_check_bitmask(PIPE_FORMAT_B8G8R8A8_SRGB, caps->v1.render.bitmask, false);
101001e04c3fSmrg   screen->refcnt = 1;
101101e04c3fSmrg
10129f464c52Smaya   slab_create_parent(&screen->transfer_pool, sizeof(struct virgl_transfer), 16);
101301e04c3fSmrg
10147ec681f3Smrg   virgl_disk_cache_create(screen);
101501e04c3fSmrg   return &screen->base;
101601e04c3fSmrg}
1017