1 /*
2 * Copyright 2021 Google LLC
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "vkr_common.h"
7
8 #include <stdarg.h>
9 #include <stdio.h>
10
11 #include "venus-protocol/vn_protocol_renderer_info.h"
12
13 #include "vkr_context.h"
14 #include "vkr_cs.h"
15
16 static const struct vn_info_extension_table vkr_extension_table = {
17 /* Venus extensions */
18 .EXT_command_serialization = true,
19 .MESA_venus_protocol = true,
20 /* promoted to VK_VERSION_1_1 */
21 .KHR_16bit_storage = true,
22 .KHR_bind_memory2 = true,
23 .KHR_dedicated_allocation = true,
24 .KHR_descriptor_update_template = true,
25 .KHR_device_group = true,
26 .KHR_device_group_creation = true,
27 .KHR_external_fence = true,
28 .KHR_external_fence_capabilities = true,
29 .KHR_external_memory = true,
30 .KHR_external_memory_capabilities = true,
31 .KHR_external_semaphore = true,
32 .KHR_external_semaphore_capabilities = true,
33 .KHR_get_memory_requirements2 = true,
34 .KHR_get_physical_device_properties2 = true,
35 .KHR_maintenance1 = true,
36 .KHR_maintenance2 = true,
37 .KHR_maintenance3 = true,
38 .KHR_multiview = true,
39 .KHR_relaxed_block_layout = true,
40 .KHR_sampler_ycbcr_conversion = true,
41 .KHR_shader_draw_parameters = true,
42 .KHR_storage_buffer_storage_class = true,
43 .KHR_variable_pointers = true,
44 /* promoted to VK_VERSION_1_2 */
45 .KHR_8bit_storage = true,
46 .KHR_buffer_device_address = true,
47 .KHR_create_renderpass2 = true,
48 .KHR_depth_stencil_resolve = true,
49 .KHR_draw_indirect_count = true,
50 .KHR_driver_properties = true,
51 .KHR_image_format_list = true,
52 .KHR_imageless_framebuffer = true,
53 .KHR_sampler_mirror_clamp_to_edge = true,
54 .KHR_separate_depth_stencil_layouts = true,
55 .KHR_shader_atomic_int64 = true,
56 .KHR_shader_float16_int8 = true,
57 .KHR_shader_float_controls = true,
58 .KHR_shader_subgroup_extended_types = true,
59 .KHR_spirv_1_4 = true,
60 .KHR_timeline_semaphore = true,
61 .KHR_uniform_buffer_standard_layout = true,
62 .KHR_vulkan_memory_model = true,
63 .EXT_descriptor_indexing = true,
64 .EXT_host_query_reset = true,
65 .EXT_sampler_filter_minmax = true,
66 .EXT_scalar_block_layout = true,
67 .EXT_separate_stencil_usage = true,
68 .EXT_shader_viewport_index_layer = true,
69 /* promoted to VK_VERSION_1_3 */
70 .KHR_copy_commands2 = true,
71 .KHR_dynamic_rendering = true,
72 .KHR_format_feature_flags2 = false,
73 .KHR_maintenance4 = true,
74 .KHR_shader_integer_dot_product = true,
75 .KHR_shader_non_semantic_info = true,
76 .KHR_shader_terminate_invocation = true,
77 .KHR_synchronization2 = true,
78 .KHR_zero_initialize_workgroup_memory = true,
79 .EXT_4444_formats = true,
80 .EXT_extended_dynamic_state = true,
81 .EXT_extended_dynamic_state2 = true,
82 .EXT_image_robustness = true,
83 .EXT_inline_uniform_block = true,
84 .EXT_pipeline_creation_cache_control = true,
85 .EXT_pipeline_creation_feedback = true,
86 /* TODO(VK_EXT_private_data): Support natively in the guest */
87 .EXT_private_data = true,
88 .EXT_shader_demote_to_helper_invocation = true,
89 .EXT_subgroup_size_control = true,
90 .EXT_texel_buffer_alignment = true,
91 .EXT_texture_compression_astc_hdr = true,
92 .EXT_tooling_info = false, /* implementation in driver */
93 .EXT_ycbcr_2plane_444_formats = true,
94 /* KHR extensions */
95 .KHR_external_fence_fd = true,
96 .KHR_external_memory_fd = true,
97 .KHR_external_semaphore_fd = true,
98 .KHR_push_descriptor = true,
99 /* EXT extensions */
100 .EXT_calibrated_timestamps = true,
101 .EXT_conservative_rasterization = true,
102 .EXT_conditional_rendering = true,
103 .EXT_custom_border_color = true,
104 .EXT_depth_clip_control = true,
105 .EXT_depth_clip_enable = true,
106 .EXT_external_memory_dma_buf = true,
107 .EXT_image_drm_format_modifier = true,
108 .EXT_image_view_min_lod = true,
109 .EXT_index_type_uint8 = true,
110 .EXT_line_rasterization = true,
111 .EXT_multi_draw = true,
112 .EXT_mutable_descriptor_type = true,
113 .EXT_pci_bus_info = true,
114 .EXT_primitive_topology_list_restart = true,
115 .EXT_primitives_generated_query = true,
116 .EXT_provoking_vertex = true,
117 .EXT_queue_family_foreign = true,
118 .EXT_robustness2 = true,
119 .EXT_shader_stencil_export = true,
120 .EXT_transform_feedback = true,
121 .EXT_vertex_attribute_divisor = true,
122 /* vendor extensions */
123 .VALVE_mutable_descriptor_type = true,
124 };
125
126 void
vkr_log(const char * fmt,...)127 vkr_log(const char *fmt, ...)
128 {
129 const char prefix[] = "vkr: ";
130 char line[1024];
131 size_t len;
132 va_list va;
133 int ret;
134
135 len = ARRAY_SIZE(prefix) - 1;
136 memcpy(line, prefix, len);
137
138 va_start(va, fmt);
139 ret = vsnprintf(line + len, ARRAY_SIZE(line) - len, fmt, va);
140 va_end(va);
141
142 if (ret < 0) {
143 const char log_error[] = "log error";
144 memcpy(line + len, log_error, ARRAY_SIZE(log_error) - 1);
145 len += ARRAY_SIZE(log_error) - 1;
146 } else if ((size_t)ret < ARRAY_SIZE(line) - len) {
147 len += ret;
148 } else {
149 len = ARRAY_SIZE(line) - 1;
150 }
151
152 /* make room for newline */
153 if (len + 1 >= ARRAY_SIZE(line))
154 len--;
155
156 line[len++] = '\n';
157 line[len] = '\0';
158
159 virgl_log("%s", line);
160 }
161
162 void
vkr_extension_table_init(struct vn_info_extension_table * table,const char * const * exts,uint32_t count)163 vkr_extension_table_init(struct vn_info_extension_table *table,
164 const char *const *exts,
165 uint32_t count)
166 {
167 memset(table, 0, sizeof(*table));
168 for (uint32_t i = 0; i < count; i++) {
169 const int32_t index = vn_info_extension_index(exts[i]);
170 if (index >= 0)
171 table->enabled[index] = true;
172 }
173 }
174
175 uint32_t
vkr_extension_get_spec_version(const char * name)176 vkr_extension_get_spec_version(const char *name)
177 {
178 const int32_t index = vn_info_extension_index(name);
179 if (index < 0 || !vkr_extension_table.enabled[index])
180 return 0;
181
182 const struct vn_info_extension *ext = vn_info_extension_get(index);
183 return ext->spec_version;
184 }
185
186 void
object_array_fini(struct object_array * arr)187 object_array_fini(struct object_array *arr)
188 {
189 if (!arr->objects_stolen) {
190 for (uint32_t i = 0; i < arr->count; i++)
191 free(arr->objects[i]);
192 }
193
194 free(arr->objects);
195 free(arr->handle_storage);
196 }
197
198 bool
object_array_init(struct vkr_context * ctx,struct object_array * arr,uint32_t count,VkObjectType obj_type,size_t obj_size,size_t handle_size,const void * obj_id_handles)199 object_array_init(struct vkr_context *ctx,
200 struct object_array *arr,
201 uint32_t count,
202 VkObjectType obj_type,
203 size_t obj_size,
204 size_t handle_size,
205 const void *obj_id_handles)
206 {
207 arr->count = count;
208
209 arr->objects = malloc(sizeof(*arr->objects) * count);
210 if (!arr->objects)
211 return false;
212
213 arr->handle_storage = malloc(handle_size * count);
214 if (!arr->handle_storage) {
215 free(arr->objects);
216 return false;
217 }
218
219 arr->objects_stolen = false;
220 for (uint32_t i = 0; i < count; i++) {
221 const void *obj_id_handle = (const char *)obj_id_handles + handle_size * i;
222 struct vkr_object *obj =
223 vkr_context_alloc_object(ctx, obj_size, obj_type, obj_id_handle);
224 if (!obj) {
225 arr->count = i;
226 object_array_fini(arr);
227 return false;
228 }
229
230 arr->objects[i] = obj;
231 }
232
233 return true;
234 }
235