zink: implement load_instance_id
[mesa.git] / src / gallium / drivers / zink / zink_screen.c
1 /*
2 * Copyright 2018 Collabora Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "zink_screen.h"
25
26 #include "zink_compiler.h"
27 #include "zink_context.h"
28 #include "zink_fence.h"
29 #include "zink_public.h"
30 #include "zink_resource.h"
31
32 #include "os/os_process.h"
33 #include "util/u_debug.h"
34 #include "util/format/u_format.h"
35 #include "util/u_math.h"
36 #include "util/u_memory.h"
37 #include "util/u_screen.h"
38 #include "util/u_string.h"
39
40 #include "state_tracker/sw_winsys.h"
41
42 static const struct debug_named_value
43 debug_options[] = {
44 { "nir", ZINK_DEBUG_NIR, "Dump NIR during program compile" },
45 { "spirv", ZINK_DEBUG_SPIRV, "Dump SPIR-V during program compile" },
46 { "tgsi", ZINK_DEBUG_TGSI, "Dump TGSI during program compile" },
47 DEBUG_NAMED_VALUE_END
48 };
49
50 DEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", debug_options, 0)
51
52 uint32_t
53 zink_debug;
54
55 static const char *
56 zink_get_vendor(struct pipe_screen *pscreen)
57 {
58 return "Collabora Ltd";
59 }
60
61 static const char *
62 zink_get_device_vendor(struct pipe_screen *pscreen)
63 {
64 struct zink_screen *screen = zink_screen(pscreen);
65 static char buf[1000];
66 snprintf(buf, sizeof(buf), "Unknown (vendor-id: 0x%04x)", screen->props.vendorID);
67 return buf;
68 }
69
70 static const char *
71 zink_get_name(struct pipe_screen *pscreen)
72 {
73 struct zink_screen *screen = zink_screen(pscreen);
74 static char buf[1000];
75 snprintf(buf, sizeof(buf), "zink (%s)", screen->props.deviceName);
76 return buf;
77 }
78
79 static int
80 get_video_mem(struct zink_screen *screen)
81 {
82 VkDeviceSize size = 0;
83 for (uint32_t i = 0; i < screen->mem_props.memoryHeapCount; ++i)
84 size += screen->mem_props.memoryHeaps[i].size;
85 return (int)(size >> 20);
86 }
87
88 static int
89 zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
90 {
91 struct zink_screen *screen = zink_screen(pscreen);
92
93 switch (param) {
94 case PIPE_CAP_NPOT_TEXTURES:
95 return 1;
96
97 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
98 return screen->props.limits.maxFragmentDualSrcAttachments;
99
100 case PIPE_CAP_POINT_SPRITE:
101 return 1;
102
103 case PIPE_CAP_MAX_RENDER_TARGETS:
104 return screen->props.limits.maxColorAttachments;
105
106 case PIPE_CAP_OCCLUSION_QUERY:
107 return 1;
108
109 #if 0 /* TODO: Enable me */
110 case PIPE_CAP_QUERY_TIME_ELAPSED:
111 return 1;
112 #endif
113
114 case PIPE_CAP_TEXTURE_SWIZZLE:
115 return 1;
116
117 case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
118 return screen->props.limits.maxImageDimension2D;
119 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
120 return 1 + util_logbase2(screen->props.limits.maxImageDimension3D);
121 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
122 return 1 + util_logbase2(screen->props.limits.maxImageDimensionCube);
123
124 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
125 case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
126 case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
127 case PIPE_CAP_VERTEX_SHADER_SATURATE:
128 return 1;
129
130 case PIPE_CAP_INDEP_BLEND_ENABLE:
131 case PIPE_CAP_INDEP_BLEND_FUNC:
132 return 1;
133
134 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
135 return screen->props.limits.maxImageArrayLayers;
136
137 #if 0 /* TODO: Enable me */
138 case PIPE_CAP_DEPTH_CLIP_DISABLE:
139 return 0;
140 #endif
141
142 case PIPE_CAP_TGSI_INSTANCEID:
143 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
144 case PIPE_CAP_SEAMLESS_CUBE_MAP:
145 return 1;
146
147 case PIPE_CAP_MIN_TEXEL_OFFSET:
148 return screen->props.limits.minTexelOffset;
149 case PIPE_CAP_MAX_TEXEL_OFFSET:
150 return screen->props.limits.maxTexelOffset;
151
152 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
153 return 1;
154
155 case PIPE_CAP_GLSL_FEATURE_LEVEL:
156 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
157 return 120;
158
159 #if 0 /* TODO: Enable me */
160 case PIPE_CAP_COMPUTE:
161 return 1;
162 #endif
163
164 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
165 return screen->props.limits.minUniformBufferOffsetAlignment;
166
167 #if 0 /* TODO: Enable me */
168 case PIPE_CAP_QUERY_TIMESTAMP:
169 return 1;
170 #endif
171
172 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
173 return screen->props.limits.minMemoryMapAlignment;
174
175 case PIPE_CAP_CUBE_MAP_ARRAY:
176 return screen->feats.imageCubeArray;
177
178 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
179 return 1;
180
181 case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
182 return screen->props.limits.minTexelBufferOffsetAlignment;
183
184 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
185 return 0; /* unsure */
186
187 case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
188 return screen->props.limits.maxTexelBufferElements;
189
190 case PIPE_CAP_ENDIANNESS:
191 return PIPE_ENDIAN_NATIVE; /* unsure */
192
193 case PIPE_CAP_MAX_VIEWPORTS:
194 return screen->props.limits.maxViewports;
195
196 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
197 return 1;
198
199 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
200 return screen->props.limits.maxGeometryOutputVertices;
201 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
202 return screen->props.limits.maxGeometryOutputComponents;
203
204 #if 0 /* TODO: Enable me. Enables ARB_texture_gather */
205 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
206 return 4;
207 #endif
208
209 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
210 return screen->props.limits.minTexelGatherOffset;
211 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
212 return screen->props.limits.maxTexelGatherOffset;
213
214 case PIPE_CAP_VENDOR_ID:
215 return screen->props.vendorID;
216 case PIPE_CAP_DEVICE_ID:
217 return screen->props.deviceID;
218
219 case PIPE_CAP_ACCELERATED:
220 return 1;
221 case PIPE_CAP_VIDEO_MEMORY:
222 return get_video_mem(screen);
223 case PIPE_CAP_UMA:
224 return screen->props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
225
226 case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
227 return screen->props.limits.maxVertexInputBindingStride;
228
229 #if 0 /* TODO: Enable me */
230 case PIPE_CAP_SAMPLER_VIEW_TARGET:
231 return 1;
232 #endif
233
234 #if 0 /* TODO: Enable me */
235 case PIPE_CAP_CLIP_HALFZ:
236 return 1;
237 #endif
238
239 #if 0 /* TODO: Enable me */
240 case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
241 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
242 return 1;
243 #endif
244
245 case PIPE_CAP_SHAREABLE_SHADERS:
246 return 1;
247
248 #if 0 /* TODO: Enable me. Enables GL_ARB_shader_storage_buffer_object */
249 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
250 return screen->props.limits.minStorageBufferOffsetAlignment;
251 #endif
252
253 case PIPE_CAP_PCI_GROUP:
254 case PIPE_CAP_PCI_BUS:
255 case PIPE_CAP_PCI_DEVICE:
256 case PIPE_CAP_PCI_FUNCTION:
257 return 0; /* TODO: figure these out */
258
259 #if 0 /* TODO: Enable me */
260 case PIPE_CAP_CULL_DISTANCE:
261 return screen->feats.shaderCullDistance;
262 #endif
263
264 case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
265 return screen->props.limits.viewportSubPixelBits;
266
267 case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
268 return 0; /* not sure */
269
270 case PIPE_CAP_MAX_GS_INVOCATIONS:
271 return 0; /* not implemented */
272
273 case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
274 return screen->props.limits.maxDescriptorSetStorageBuffers;
275
276 case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
277 return screen->props.limits.maxStorageBufferRange; /* unsure */
278
279 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
280 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
281 return 1;
282
283 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
284 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
285 return 0;
286
287 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
288 return 0;
289
290 case PIPE_CAP_NIR_COMPACT_ARRAYS:
291 return 1;
292
293 case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
294 return 1;
295
296 case PIPE_CAP_FLATSHADE:
297 case PIPE_CAP_ALPHA_TEST:
298 case PIPE_CAP_CLIP_PLANES:
299 case PIPE_CAP_POINT_SIZE_FIXED:
300 case PIPE_CAP_TWO_SIDED_COLOR:
301 return 0;
302
303 case PIPE_CAP_DMABUF:
304 return screen->have_KHR_external_memory_fd;
305
306 default:
307 return u_pipe_screen_get_param_defaults(pscreen, param);
308 }
309 }
310
311 static float
312 zink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
313 {
314 struct zink_screen *screen = zink_screen(pscreen);
315
316 switch (param) {
317 case PIPE_CAPF_MAX_LINE_WIDTH:
318 case PIPE_CAPF_MAX_LINE_WIDTH_AA:
319 return screen->props.limits.lineWidthRange[1];
320
321 case PIPE_CAPF_MAX_POINT_WIDTH:
322 case PIPE_CAPF_MAX_POINT_WIDTH_AA:
323 return screen->props.limits.pointSizeRange[1];
324
325 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
326 return screen->props.limits.maxSamplerAnisotropy;
327
328 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
329 return screen->props.limits.maxSamplerLodBias;
330
331 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
332 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
333 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
334 return 0.0f; /* not implemented */
335 }
336
337 /* should only get here on unhandled cases */
338 return 0.0;
339 }
340
341 static int
342 zink_get_shader_param(struct pipe_screen *pscreen,
343 enum pipe_shader_type shader,
344 enum pipe_shader_cap param)
345 {
346 struct zink_screen *screen = zink_screen(pscreen);
347
348 switch (param) {
349 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
350 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
351 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
352 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
353 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
354 if (shader == PIPE_SHADER_VERTEX ||
355 shader == PIPE_SHADER_FRAGMENT)
356 return INT_MAX;
357 return 0;
358
359 case PIPE_SHADER_CAP_MAX_INPUTS:
360 switch (shader) {
361 case PIPE_SHADER_VERTEX:
362 return MIN2(screen->props.limits.maxVertexInputAttributes,
363 PIPE_MAX_SHADER_INPUTS);
364 case PIPE_SHADER_FRAGMENT:
365 return MIN2(screen->props.limits.maxFragmentInputComponents / 4,
366 PIPE_MAX_SHADER_INPUTS);
367 default:
368 return 0; /* unsupported stage */
369 }
370
371 case PIPE_SHADER_CAP_MAX_OUTPUTS:
372 switch (shader) {
373 case PIPE_SHADER_VERTEX:
374 return MIN2(screen->props.limits.maxVertexOutputComponents / 4,
375 PIPE_MAX_SHADER_OUTPUTS);
376 case PIPE_SHADER_FRAGMENT:
377 return MIN2(screen->props.limits.maxColorAttachments,
378 PIPE_MAX_SHADER_OUTPUTS);
379 default:
380 return 0; /* unsupported stage */
381 }
382
383 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
384 /* this might be a bit simplistic... */
385 return MIN2(screen->props.limits.maxPerStageDescriptorSamplers,
386 PIPE_MAX_SAMPLERS);
387
388 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
389 return MIN2(screen->props.limits.maxUniformBufferRange, INT_MAX);
390
391 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
392 return screen->props.limits.maxPerStageDescriptorUniformBuffers;
393
394 case PIPE_SHADER_CAP_MAX_TEMPS:
395 return INT_MAX;
396
397 case PIPE_SHADER_CAP_INTEGERS:
398 return 1;
399
400 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
401 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
402 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
403 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
404 case PIPE_SHADER_CAP_SUBROUTINES:
405 case PIPE_SHADER_CAP_INT64_ATOMICS:
406 case PIPE_SHADER_CAP_FP16:
407 return 0; /* not implemented */
408
409 case PIPE_SHADER_CAP_PREFERRED_IR:
410 return PIPE_SHADER_IR_NIR;
411
412 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
413 return 0; /* not implemented */
414
415 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
416 return MIN2(screen->props.limits.maxPerStageDescriptorSampledImages,
417 PIPE_MAX_SHADER_SAMPLER_VIEWS);
418
419 case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
420 case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
421 case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
422 return 0; /* not implemented */
423
424 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
425 return 0; /* no idea */
426
427 case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
428 return 32; /* arbitrary */
429
430 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
431 /* TODO: this limitation is dumb, and will need some fixes in mesa */
432 return MIN2(screen->props.limits.maxPerStageDescriptorStorageBuffers, 8);
433
434 case PIPE_SHADER_CAP_SUPPORTED_IRS:
435 return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
436
437 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
438 return MIN2(screen->props.limits.maxPerStageDescriptorStorageImages,
439 PIPE_MAX_SHADER_IMAGES);
440
441 case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
442 case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
443 return 0; /* unsure */
444
445 case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
446 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
447 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
448 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
449 return 0; /* not implemented */
450 }
451
452 /* should only get here on unhandled cases */
453 return 0;
454 }
455
456 static VkSampleCountFlagBits
457 vk_sample_count_flags(uint32_t sample_count)
458 {
459 switch (sample_count) {
460 case 1: return VK_SAMPLE_COUNT_1_BIT;
461 case 2: return VK_SAMPLE_COUNT_2_BIT;
462 case 4: return VK_SAMPLE_COUNT_4_BIT;
463 case 8: return VK_SAMPLE_COUNT_8_BIT;
464 case 16: return VK_SAMPLE_COUNT_16_BIT;
465 case 32: return VK_SAMPLE_COUNT_32_BIT;
466 case 64: return VK_SAMPLE_COUNT_64_BIT;
467 default:
468 return 0;
469 }
470 }
471
472 static bool
473 zink_is_format_supported(struct pipe_screen *pscreen,
474 enum pipe_format format,
475 enum pipe_texture_target target,
476 unsigned sample_count,
477 unsigned storage_sample_count,
478 unsigned bind)
479 {
480 struct zink_screen *screen = zink_screen(pscreen);
481
482 if (format == PIPE_FORMAT_NONE)
483 return screen->props.limits.framebufferNoAttachmentsSampleCounts &
484 vk_sample_count_flags(sample_count);
485
486 VkFormat vkformat = zink_get_format(screen, format);
487 if (vkformat == VK_FORMAT_UNDEFINED)
488 return false;
489
490 if (sample_count >= 1) {
491 VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
492 if (!sample_mask)
493 return false;
494 const struct util_format_description *desc = util_format_description(format);
495 if (util_format_is_depth_or_stencil(format)) {
496 if (util_format_has_depth(desc)) {
497 if (bind & PIPE_BIND_DEPTH_STENCIL &&
498 (screen->props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
499 return false;
500 if (bind & PIPE_BIND_SAMPLER_VIEW &&
501 (screen->props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
502 return false;
503 }
504 if (util_format_has_stencil(desc)) {
505 if (bind & PIPE_BIND_DEPTH_STENCIL &&
506 (screen->props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
507 return false;
508 if (bind & PIPE_BIND_SAMPLER_VIEW &&
509 (screen->props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
510 return false;
511 }
512 } else if (util_format_is_pure_integer(format)) {
513 if (bind & PIPE_BIND_RENDER_TARGET &&
514 !(screen->props.limits.framebufferColorSampleCounts & sample_mask))
515 return false;
516 if (bind & PIPE_BIND_SAMPLER_VIEW &&
517 !(screen->props.limits.sampledImageIntegerSampleCounts & sample_mask))
518 return false;
519 } else {
520 if (bind & PIPE_BIND_RENDER_TARGET &&
521 !(screen->props.limits.framebufferColorSampleCounts & sample_mask))
522 return false;
523 if (bind & PIPE_BIND_SAMPLER_VIEW &&
524 !(screen->props.limits.sampledImageColorSampleCounts & sample_mask))
525 return false;
526 }
527 }
528
529 VkFormatProperties props;
530 vkGetPhysicalDeviceFormatProperties(screen->pdev, vkformat, &props);
531
532 if (target == PIPE_BUFFER) {
533 if (bind & PIPE_BIND_VERTEX_BUFFER &&
534 !(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
535 return false;
536 } else {
537 /* all other targets are texture-targets */
538 if (bind & PIPE_BIND_RENDER_TARGET &&
539 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
540 return false;
541
542 if (bind & PIPE_BIND_BLENDABLE &&
543 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
544 return false;
545
546 if (bind & PIPE_BIND_SAMPLER_VIEW &&
547 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
548 return false;
549
550 if (bind & PIPE_BIND_DEPTH_STENCIL &&
551 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
552 return false;
553 }
554
555 if (util_format_is_compressed(format)) {
556 const struct util_format_description *desc = util_format_description(format);
557 if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC &&
558 !screen->feats.textureCompressionBC)
559 return false;
560 }
561
562 return true;
563 }
564
565 static void
566 zink_destroy_screen(struct pipe_screen *pscreen)
567 {
568 struct zink_screen *screen = zink_screen(pscreen);
569 slab_destroy_parent(&screen->transfer_pool);
570 FREE(screen);
571 }
572
573 static VkInstance
574 create_instance()
575 {
576 VkApplicationInfo ai = {};
577 ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
578
579 char proc_name[128];
580 if (os_get_process_name(proc_name, ARRAY_SIZE(proc_name)))
581 ai.pApplicationName = proc_name;
582 else
583 ai.pApplicationName = "unknown";
584
585 ai.pEngineName = "mesa zink";
586 ai.apiVersion = VK_API_VERSION_1_0;
587
588 const char *extensions[] = {
589 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
590 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
591 };
592
593 VkInstanceCreateInfo ici = {};
594 ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
595 ici.pApplicationInfo = &ai;
596 ici.ppEnabledExtensionNames = extensions;
597 ici.enabledExtensionCount = ARRAY_SIZE(extensions);
598
599 VkInstance instance = VK_NULL_HANDLE;
600 VkResult err = vkCreateInstance(&ici, NULL, &instance);
601 if (err != VK_SUCCESS)
602 return VK_NULL_HANDLE;
603
604 return instance;
605 }
606
607 static VkPhysicalDevice
608 choose_pdev(const VkInstance instance)
609 {
610 uint32_t i, pdev_count;
611 VkPhysicalDevice *pdevs, pdev;
612 vkEnumeratePhysicalDevices(instance, &pdev_count, NULL);
613 assert(pdev_count > 0);
614
615 pdevs = malloc(sizeof(*pdevs) * pdev_count);
616 vkEnumeratePhysicalDevices(instance, &pdev_count, pdevs);
617 assert(pdev_count > 0);
618
619 pdev = pdevs[0];
620 for (i = 0; i < pdev_count; ++i) {
621 VkPhysicalDeviceProperties props;
622 vkGetPhysicalDeviceProperties(pdevs[i], &props);
623 if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
624 pdev = pdevs[i];
625 break;
626 }
627 }
628 free(pdevs);
629 return pdev;
630 }
631
632 static uint32_t
633 find_gfx_queue(const VkPhysicalDevice pdev)
634 {
635 uint32_t num_queues;
636 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queues, NULL);
637 assert(num_queues > 0);
638
639 VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues);
640 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queues, props);
641
642 for (uint32_t i = 0; i < num_queues; i++) {
643 if (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
644 free(props);
645 return i;
646 }
647 }
648
649 return UINT32_MAX;
650 }
651
652 static void
653 zink_flush_frontbuffer(struct pipe_screen *pscreen,
654 struct pipe_resource *pres,
655 unsigned level, unsigned layer,
656 void *winsys_drawable_handle,
657 struct pipe_box *sub_box)
658 {
659 struct zink_screen *screen = zink_screen(pscreen);
660 struct sw_winsys *winsys = screen->winsys;
661 struct zink_resource *res = zink_resource(pres);
662
663 if (!winsys)
664 return;
665 void *map = winsys->displaytarget_map(winsys, res->dt, 0);
666
667 if (map) {
668 VkImageSubresource isr = {};
669 isr.aspectMask = res->aspect;
670 isr.mipLevel = level;
671 isr.arrayLayer = layer;
672 VkSubresourceLayout layout;
673 vkGetImageSubresourceLayout(screen->dev, res->image, &isr, &layout);
674
675 void *ptr;
676 VkResult result = vkMapMemory(screen->dev, res->mem, res->offset, res->size, 0, &ptr);
677 if (result != VK_SUCCESS) {
678 debug_printf("failed to map memory for display\n");
679 return;
680 }
681 for (int i = 0; i < pres->height0; ++i) {
682 uint8_t *src = (uint8_t *)ptr + i * layout.rowPitch;
683 uint8_t *dst = (uint8_t *)map + i * res->dt_stride;
684 memcpy(dst, src, res->dt_stride);
685 }
686 vkUnmapMemory(screen->dev, res->mem);
687 }
688
689 winsys->displaytarget_unmap(winsys, res->dt);
690
691 assert(res->dt);
692 if (res->dt)
693 winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
694 }
695
696 static struct pipe_screen *
697 zink_internal_create_screen(struct sw_winsys *winsys, int fd)
698 {
699 struct zink_screen *screen = CALLOC_STRUCT(zink_screen);
700 if (!screen)
701 return NULL;
702
703 zink_debug = debug_get_option_zink_debug();
704
705 screen->instance = create_instance();
706 screen->pdev = choose_pdev(screen->instance);
707 screen->gfx_queue = find_gfx_queue(screen->pdev);
708
709 vkGetPhysicalDeviceProperties(screen->pdev, &screen->props);
710 vkGetPhysicalDeviceFeatures(screen->pdev, &screen->feats);
711 vkGetPhysicalDeviceMemoryProperties(screen->pdev, &screen->mem_props);
712
713 screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
714 VK_FORMAT_X8_D24_UNORM_PACK32);
715 screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
716 VK_FORMAT_D24_UNORM_S8_UINT);
717
718 uint32_t num_extensions = 0;
719 if (vkEnumerateDeviceExtensionProperties(screen->pdev, NULL,
720 &num_extensions, NULL) == VK_SUCCESS && num_extensions > 0) {
721 VkExtensionProperties *extensions = MALLOC(sizeof(VkExtensionProperties) *
722 num_extensions);
723 if (extensions) {
724 vkEnumerateDeviceExtensionProperties(screen->pdev, NULL,
725 &num_extensions, extensions);
726
727 for (uint32_t i = 0; i < num_extensions; ++i) {
728 if (!strcmp(extensions[i].extensionName,
729 VK_KHR_MAINTENANCE1_EXTENSION_NAME))
730 screen->have_KHR_maintenance1 = true;
731 if (!strcmp(extensions[i].extensionName,
732 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME))
733 screen->have_KHR_external_memory_fd = true;
734 }
735 FREE(extensions);
736 }
737 }
738
739 if (!screen->have_KHR_maintenance1) {
740 debug_printf("ZINK: VK_KHR_maintenance1 required!\n");
741 goto fail;
742 }
743
744 VkDeviceQueueCreateInfo qci = {};
745 float dummy = 0.0f;
746 qci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
747 qci.queueFamilyIndex = screen->gfx_queue;
748 qci.queueCount = 1;
749 qci.pQueuePriorities = &dummy;
750
751 VkDeviceCreateInfo dci = {};
752 dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
753 dci.queueCreateInfoCount = 1;
754 dci.pQueueCreateInfos = &qci;
755 dci.pEnabledFeatures = &screen->feats;
756 const char *extensions[3] = {
757 VK_KHR_MAINTENANCE1_EXTENSION_NAME,
758 };
759 num_extensions = 1;
760
761 if (fd >= 0 && !screen->have_KHR_external_memory_fd) {
762 debug_printf("ZINK: KHR_external_memory_fd required!\n");
763 goto fail;
764 }
765
766 if (screen->have_KHR_external_memory_fd) {
767 extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME;
768 extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
769 }
770 assert(num_extensions <= ARRAY_SIZE(extensions));
771
772 dci.ppEnabledExtensionNames = extensions;
773 dci.enabledExtensionCount = num_extensions;
774 if (vkCreateDevice(screen->pdev, &dci, NULL, &screen->dev) != VK_SUCCESS)
775 goto fail;
776
777 screen->winsys = winsys;
778
779 screen->base.get_name = zink_get_name;
780 screen->base.get_vendor = zink_get_vendor;
781 screen->base.get_device_vendor = zink_get_device_vendor;
782 screen->base.get_param = zink_get_param;
783 screen->base.get_paramf = zink_get_paramf;
784 screen->base.get_shader_param = zink_get_shader_param;
785 screen->base.get_compiler_options = zink_get_compiler_options;
786 screen->base.is_format_supported = zink_is_format_supported;
787 screen->base.context_create = zink_context_create;
788 screen->base.flush_frontbuffer = zink_flush_frontbuffer;
789 screen->base.destroy = zink_destroy_screen;
790
791 zink_screen_resource_init(&screen->base);
792 zink_screen_fence_init(&screen->base);
793
794 slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16);
795
796 return &screen->base;
797
798 fail:
799 FREE(screen);
800 return NULL;
801 }
802
803 struct pipe_screen *
804 zink_create_screen(struct sw_winsys *winsys)
805 {
806 return zink_internal_create_screen(winsys, -1);
807 }
808
809 struct pipe_screen *
810 zink_drm_create_screen(int fd)
811 {
812 return zink_internal_create_screen(NULL, fd);
813 }