radeonsi: rename si_shader_create -> si_create_shader_variant for clarity
[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_MIXED_COLORBUFFER_FORMATS:
143 return 1;
144
145 case PIPE_CAP_SEAMLESS_CUBE_MAP:
146 return 1;
147
148 case PIPE_CAP_MIN_TEXEL_OFFSET:
149 return screen->props.limits.minTexelOffset;
150 case PIPE_CAP_MAX_TEXEL_OFFSET:
151 return screen->props.limits.maxTexelOffset;
152
153 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
154 return 1;
155
156 case PIPE_CAP_GLSL_FEATURE_LEVEL:
157 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
158 return 120;
159
160 #if 0 /* TODO: Enable me */
161 case PIPE_CAP_COMPUTE:
162 return 1;
163 #endif
164
165 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
166 return screen->props.limits.minUniformBufferOffsetAlignment;
167
168 #if 0 /* TODO: Enable me */
169 case PIPE_CAP_QUERY_TIMESTAMP:
170 return 1;
171 #endif
172
173 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
174 return screen->props.limits.minMemoryMapAlignment;
175
176 case PIPE_CAP_CUBE_MAP_ARRAY:
177 return screen->feats.imageCubeArray;
178
179 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
180 return 0; /* unsure */
181
182 case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
183 return screen->props.limits.maxTexelBufferElements;
184
185 case PIPE_CAP_ENDIANNESS:
186 return PIPE_ENDIAN_NATIVE; /* unsure */
187
188 case PIPE_CAP_MAX_VIEWPORTS:
189 return screen->props.limits.maxViewports;
190
191 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
192 return 1;
193
194 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
195 return screen->props.limits.maxGeometryOutputVertices;
196 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
197 return screen->props.limits.maxGeometryOutputComponents;
198
199 #if 0 /* TODO: Enable me. Enables ARB_texture_gather */
200 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
201 return 4;
202 #endif
203
204 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
205 return screen->props.limits.minTexelGatherOffset;
206 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
207 return screen->props.limits.maxTexelGatherOffset;
208
209 case PIPE_CAP_VENDOR_ID:
210 return screen->props.vendorID;
211 case PIPE_CAP_DEVICE_ID:
212 return screen->props.deviceID;
213
214 case PIPE_CAP_ACCELERATED:
215 return 1;
216 case PIPE_CAP_VIDEO_MEMORY:
217 return get_video_mem(screen);
218 case PIPE_CAP_UMA:
219 return screen->props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
220
221 case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
222 return screen->props.limits.maxVertexInputBindingStride;
223
224 #if 0 /* TODO: Enable me */
225 case PIPE_CAP_SAMPLER_VIEW_TARGET:
226 return 1;
227 #endif
228
229 #if 0 /* TODO: Enable me */
230 case PIPE_CAP_CLIP_HALFZ:
231 return 1;
232 #endif
233
234 #if 0 /* TODO: Enable me */
235 case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
236 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
237 return 1;
238 #endif
239
240 case PIPE_CAP_SHAREABLE_SHADERS:
241 return 1;
242
243 #if 0 /* TODO: Enable me. Enables GL_ARB_shader_storage_buffer_object */
244 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
245 return screen->props.limits.minStorageBufferOffsetAlignment;
246 #endif
247
248 case PIPE_CAP_PCI_GROUP:
249 case PIPE_CAP_PCI_BUS:
250 case PIPE_CAP_PCI_DEVICE:
251 case PIPE_CAP_PCI_FUNCTION:
252 return 0; /* TODO: figure these out */
253
254 #if 0 /* TODO: Enable me */
255 case PIPE_CAP_CULL_DISTANCE:
256 return screen->feats.shaderCullDistance;
257 #endif
258
259 case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
260 return screen->props.limits.viewportSubPixelBits;
261
262 case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
263 return 0; /* not sure */
264
265 case PIPE_CAP_MAX_GS_INVOCATIONS:
266 return 0; /* not implemented */
267
268 case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
269 return screen->props.limits.maxDescriptorSetStorageBuffers;
270
271 case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
272 return screen->props.limits.maxStorageBufferRange; /* unsure */
273
274 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
275 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
276 return 1;
277
278 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
279 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
280 return 0;
281
282 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
283 return 0;
284
285 case PIPE_CAP_NIR_COMPACT_ARRAYS:
286 return 1;
287
288 case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
289 return 1;
290
291 case PIPE_CAP_FLATSHADE:
292 case PIPE_CAP_ALPHA_TEST:
293 case PIPE_CAP_CLIP_PLANES:
294 case PIPE_CAP_POINT_SIZE_FIXED:
295 case PIPE_CAP_TWO_SIDED_COLOR:
296 return 0;
297
298 case PIPE_CAP_DMABUF:
299 return screen->have_KHR_external_memory_fd;
300
301 default:
302 return u_pipe_screen_get_param_defaults(pscreen, param);
303 }
304 }
305
306 static float
307 zink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
308 {
309 struct zink_screen *screen = zink_screen(pscreen);
310
311 switch (param) {
312 case PIPE_CAPF_MAX_LINE_WIDTH:
313 case PIPE_CAPF_MAX_LINE_WIDTH_AA:
314 return screen->props.limits.lineWidthRange[1];
315
316 case PIPE_CAPF_MAX_POINT_WIDTH:
317 case PIPE_CAPF_MAX_POINT_WIDTH_AA:
318 return screen->props.limits.pointSizeRange[1];
319
320 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
321 return screen->props.limits.maxSamplerAnisotropy;
322
323 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
324 return screen->props.limits.maxSamplerLodBias;
325
326 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
327 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
328 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
329 return 0.0f; /* not implemented */
330 }
331
332 /* should only get here on unhandled cases */
333 return 0.0;
334 }
335
336 static int
337 zink_get_shader_param(struct pipe_screen *pscreen,
338 enum pipe_shader_type shader,
339 enum pipe_shader_cap param)
340 {
341 struct zink_screen *screen = zink_screen(pscreen);
342
343 switch (param) {
344 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
345 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
346 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
347 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
348 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
349 if (shader == PIPE_SHADER_VERTEX ||
350 shader == PIPE_SHADER_FRAGMENT)
351 return INT_MAX;
352 return 0;
353
354 case PIPE_SHADER_CAP_MAX_INPUTS:
355 switch (shader) {
356 case PIPE_SHADER_VERTEX:
357 return MIN2(screen->props.limits.maxVertexInputAttributes,
358 PIPE_MAX_SHADER_INPUTS);
359 case PIPE_SHADER_FRAGMENT:
360 return MIN2(screen->props.limits.maxFragmentInputComponents / 4,
361 PIPE_MAX_SHADER_INPUTS);
362 default:
363 return 0; /* unsupported stage */
364 }
365
366 case PIPE_SHADER_CAP_MAX_OUTPUTS:
367 switch (shader) {
368 case PIPE_SHADER_VERTEX:
369 return MIN2(screen->props.limits.maxVertexOutputComponents / 4,
370 PIPE_MAX_SHADER_OUTPUTS);
371 case PIPE_SHADER_FRAGMENT:
372 return MIN2(screen->props.limits.maxColorAttachments,
373 PIPE_MAX_SHADER_OUTPUTS);
374 default:
375 return 0; /* unsupported stage */
376 }
377
378 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
379 /* this might be a bit simplistic... */
380 return MIN2(screen->props.limits.maxPerStageDescriptorSamplers,
381 PIPE_MAX_SAMPLERS);
382
383 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
384 return MIN2(screen->props.limits.maxUniformBufferRange, INT_MAX);
385
386 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
387 return screen->props.limits.maxPerStageDescriptorUniformBuffers;
388
389 case PIPE_SHADER_CAP_MAX_TEMPS:
390 return INT_MAX;
391
392 case PIPE_SHADER_CAP_INTEGERS:
393 return 1;
394
395 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
396 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
397 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
398 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
399 case PIPE_SHADER_CAP_SUBROUTINES:
400 case PIPE_SHADER_CAP_INT64_ATOMICS:
401 case PIPE_SHADER_CAP_FP16:
402 return 0; /* not implemented */
403
404 case PIPE_SHADER_CAP_PREFERRED_IR:
405 return PIPE_SHADER_IR_NIR;
406
407 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
408 return 0; /* not implemented */
409
410 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
411 return MIN2(screen->props.limits.maxPerStageDescriptorSampledImages,
412 PIPE_MAX_SHADER_SAMPLER_VIEWS);
413
414 case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
415 case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
416 case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
417 return 0; /* not implemented */
418
419 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
420 return 0; /* no idea */
421
422 case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
423 return 32; /* arbitrary */
424
425 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
426 /* TODO: this limitation is dumb, and will need some fixes in mesa */
427 return MIN2(screen->props.limits.maxPerStageDescriptorStorageBuffers, 8);
428
429 case PIPE_SHADER_CAP_SUPPORTED_IRS:
430 return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
431
432 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
433 return MIN2(screen->props.limits.maxPerStageDescriptorStorageImages,
434 PIPE_MAX_SHADER_IMAGES);
435
436 case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
437 case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
438 return 0; /* unsure */
439
440 case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
441 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
442 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
443 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
444 return 0; /* not implemented */
445 }
446
447 /* should only get here on unhandled cases */
448 return 0;
449 }
450
451 static VkSampleCountFlagBits
452 vk_sample_count_flags(uint32_t sample_count)
453 {
454 switch (sample_count) {
455 case 1: return VK_SAMPLE_COUNT_1_BIT;
456 case 2: return VK_SAMPLE_COUNT_2_BIT;
457 case 4: return VK_SAMPLE_COUNT_4_BIT;
458 case 8: return VK_SAMPLE_COUNT_8_BIT;
459 case 16: return VK_SAMPLE_COUNT_16_BIT;
460 case 32: return VK_SAMPLE_COUNT_32_BIT;
461 case 64: return VK_SAMPLE_COUNT_64_BIT;
462 default:
463 return 0;
464 }
465 }
466
467 static bool
468 zink_is_format_supported(struct pipe_screen *pscreen,
469 enum pipe_format format,
470 enum pipe_texture_target target,
471 unsigned sample_count,
472 unsigned storage_sample_count,
473 unsigned bind)
474 {
475 struct zink_screen *screen = zink_screen(pscreen);
476
477 if (format == PIPE_FORMAT_NONE)
478 return screen->props.limits.framebufferNoAttachmentsSampleCounts &
479 vk_sample_count_flags(sample_count);
480
481 VkFormat vkformat = zink_get_format(screen, format);
482 if (vkformat == VK_FORMAT_UNDEFINED)
483 return false;
484
485 if (sample_count >= 1) {
486 VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
487 if (!sample_mask)
488 return false;
489 const struct util_format_description *desc = util_format_description(format);
490 if (util_format_is_depth_or_stencil(format)) {
491 if (util_format_has_depth(desc)) {
492 if (bind & PIPE_BIND_DEPTH_STENCIL &&
493 (screen->props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
494 return false;
495 if (bind & PIPE_BIND_SAMPLER_VIEW &&
496 (screen->props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
497 return false;
498 }
499 if (util_format_has_stencil(desc)) {
500 if (bind & PIPE_BIND_DEPTH_STENCIL &&
501 (screen->props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
502 return false;
503 if (bind & PIPE_BIND_SAMPLER_VIEW &&
504 (screen->props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
505 return false;
506 }
507 } else if (util_format_is_pure_integer(format)) {
508 if (bind & PIPE_BIND_RENDER_TARGET &&
509 !(screen->props.limits.framebufferColorSampleCounts & sample_mask))
510 return false;
511 if (bind & PIPE_BIND_SAMPLER_VIEW &&
512 !(screen->props.limits.sampledImageIntegerSampleCounts & sample_mask))
513 return false;
514 } else {
515 if (bind & PIPE_BIND_RENDER_TARGET &&
516 !(screen->props.limits.framebufferColorSampleCounts & sample_mask))
517 return false;
518 if (bind & PIPE_BIND_SAMPLER_VIEW &&
519 !(screen->props.limits.sampledImageColorSampleCounts & sample_mask))
520 return false;
521 }
522 }
523
524 VkFormatProperties props;
525 vkGetPhysicalDeviceFormatProperties(screen->pdev, vkformat, &props);
526
527 if (target == PIPE_BUFFER) {
528 if (bind & PIPE_BIND_VERTEX_BUFFER &&
529 !(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
530 return false;
531 } else {
532 /* all other targets are texture-targets */
533 if (bind & PIPE_BIND_RENDER_TARGET &&
534 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
535 return false;
536
537 if (bind & PIPE_BIND_BLENDABLE &&
538 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
539 return false;
540
541 if (bind & PIPE_BIND_SAMPLER_VIEW &&
542 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
543 return false;
544
545 if (bind & PIPE_BIND_DEPTH_STENCIL &&
546 !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
547 return false;
548 }
549
550 if (util_format_is_compressed(format)) {
551 const struct util_format_description *desc = util_format_description(format);
552 if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC &&
553 !screen->feats.textureCompressionBC)
554 return false;
555 }
556
557 return true;
558 }
559
560 static void
561 zink_destroy_screen(struct pipe_screen *pscreen)
562 {
563 struct zink_screen *screen = zink_screen(pscreen);
564 slab_destroy_parent(&screen->transfer_pool);
565 FREE(screen);
566 }
567
568 static VkInstance
569 create_instance()
570 {
571 VkApplicationInfo ai = {};
572 ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
573
574 char proc_name[128];
575 if (os_get_process_name(proc_name, ARRAY_SIZE(proc_name)))
576 ai.pApplicationName = proc_name;
577 else
578 ai.pApplicationName = "unknown";
579
580 ai.pEngineName = "mesa zink";
581 ai.apiVersion = VK_API_VERSION_1_0;
582
583 const char *extensions[] = {
584 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
585 VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
586 };
587
588 VkInstanceCreateInfo ici = {};
589 ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
590 ici.pApplicationInfo = &ai;
591 ici.ppEnabledExtensionNames = extensions;
592 ici.enabledExtensionCount = ARRAY_SIZE(extensions);
593
594 VkInstance instance = VK_NULL_HANDLE;
595 VkResult err = vkCreateInstance(&ici, NULL, &instance);
596 if (err != VK_SUCCESS)
597 return VK_NULL_HANDLE;
598
599 return instance;
600 }
601
602 static VkPhysicalDevice
603 choose_pdev(const VkInstance instance)
604 {
605 uint32_t i, pdev_count;
606 VkPhysicalDevice *pdevs, pdev;
607 vkEnumeratePhysicalDevices(instance, &pdev_count, NULL);
608 assert(pdev_count > 0);
609
610 pdevs = malloc(sizeof(*pdevs) * pdev_count);
611 vkEnumeratePhysicalDevices(instance, &pdev_count, pdevs);
612 assert(pdev_count > 0);
613
614 pdev = pdevs[0];
615 for (i = 0; i < pdev_count; ++i) {
616 VkPhysicalDeviceProperties props;
617 vkGetPhysicalDeviceProperties(pdevs[i], &props);
618 if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
619 pdev = pdevs[i];
620 break;
621 }
622 }
623 free(pdevs);
624 return pdev;
625 }
626
627 static uint32_t
628 find_gfx_queue(const VkPhysicalDevice pdev)
629 {
630 uint32_t num_queues;
631 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queues, NULL);
632 assert(num_queues > 0);
633
634 VkQueueFamilyProperties *props = malloc(sizeof(*props) * num_queues);
635 vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_queues, props);
636
637 for (uint32_t i = 0; i < num_queues; i++) {
638 if (props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
639 free(props);
640 return i;
641 }
642 }
643
644 return UINT32_MAX;
645 }
646
647 static void
648 zink_flush_frontbuffer(struct pipe_screen *pscreen,
649 struct pipe_resource *pres,
650 unsigned level, unsigned layer,
651 void *winsys_drawable_handle,
652 struct pipe_box *sub_box)
653 {
654 struct zink_screen *screen = zink_screen(pscreen);
655 struct sw_winsys *winsys = screen->winsys;
656 struct zink_resource *res = zink_resource(pres);
657
658 if (!winsys)
659 return;
660 void *map = winsys->displaytarget_map(winsys, res->dt, 0);
661
662 if (map) {
663 VkImageSubresource isr = {};
664 isr.aspectMask = res->aspect;
665 isr.mipLevel = level;
666 isr.arrayLayer = layer;
667 VkSubresourceLayout layout;
668 vkGetImageSubresourceLayout(screen->dev, res->image, &isr, &layout);
669
670 void *ptr;
671 VkResult result = vkMapMemory(screen->dev, res->mem, res->offset, res->size, 0, &ptr);
672 if (result != VK_SUCCESS) {
673 debug_printf("failed to map memory for display\n");
674 return;
675 }
676 for (int i = 0; i < pres->height0; ++i) {
677 uint8_t *src = (uint8_t *)ptr + i * layout.rowPitch;
678 uint8_t *dst = (uint8_t *)map + i * res->dt_stride;
679 memcpy(dst, src, res->dt_stride);
680 }
681 vkUnmapMemory(screen->dev, res->mem);
682 }
683
684 winsys->displaytarget_unmap(winsys, res->dt);
685
686 assert(res->dt);
687 if (res->dt)
688 winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
689 }
690
691 static struct pipe_screen *
692 zink_internal_create_screen(struct sw_winsys *winsys, int fd)
693 {
694 struct zink_screen *screen = CALLOC_STRUCT(zink_screen);
695 if (!screen)
696 return NULL;
697
698 zink_debug = debug_get_option_zink_debug();
699
700 screen->instance = create_instance();
701 screen->pdev = choose_pdev(screen->instance);
702 screen->gfx_queue = find_gfx_queue(screen->pdev);
703
704 vkGetPhysicalDeviceProperties(screen->pdev, &screen->props);
705 vkGetPhysicalDeviceFeatures(screen->pdev, &screen->feats);
706 vkGetPhysicalDeviceMemoryProperties(screen->pdev, &screen->mem_props);
707
708 screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
709 VK_FORMAT_X8_D24_UNORM_PACK32);
710 screen->have_D24_UNORM_S8_UINT = zink_is_depth_format_supported(screen,
711 VK_FORMAT_D24_UNORM_S8_UINT);
712
713 uint32_t num_extensions = 0;
714 if (vkEnumerateDeviceExtensionProperties(screen->pdev, NULL,
715 &num_extensions, NULL) == VK_SUCCESS && num_extensions > 0) {
716 VkExtensionProperties *extensions = MALLOC(sizeof(VkExtensionProperties) *
717 num_extensions);
718 if (extensions) {
719 vkEnumerateDeviceExtensionProperties(screen->pdev, NULL,
720 &num_extensions, extensions);
721
722 for (uint32_t i = 0; i < num_extensions; ++i) {
723 if (!strcmp(extensions[i].extensionName,
724 VK_KHR_MAINTENANCE1_EXTENSION_NAME))
725 screen->have_KHR_maintenance1 = true;
726 if (!strcmp(extensions[i].extensionName,
727 VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME))
728 screen->have_KHR_external_memory_fd = true;
729 }
730 FREE(extensions);
731 }
732 }
733
734 if (!screen->have_KHR_maintenance1) {
735 debug_printf("ZINK: VK_KHR_maintenance1 required!\n");
736 goto fail;
737 }
738
739 VkDeviceQueueCreateInfo qci = {};
740 float dummy = 0.0f;
741 qci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
742 qci.queueFamilyIndex = screen->gfx_queue;
743 qci.queueCount = 1;
744 qci.pQueuePriorities = &dummy;
745
746 VkDeviceCreateInfo dci = {};
747 dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
748 dci.queueCreateInfoCount = 1;
749 dci.pQueueCreateInfos = &qci;
750 dci.pEnabledFeatures = &screen->feats;
751 const char *extensions[3] = {
752 VK_KHR_MAINTENANCE1_EXTENSION_NAME,
753 };
754 num_extensions = 1;
755
756 if (fd >= 0 && !screen->have_KHR_external_memory_fd) {
757 debug_printf("ZINK: KHR_external_memory_fd required!\n");
758 goto fail;
759 }
760
761 if (screen->have_KHR_external_memory_fd) {
762 extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME;
763 extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
764 }
765 assert(num_extensions <= ARRAY_SIZE(extensions));
766
767 dci.ppEnabledExtensionNames = extensions;
768 dci.enabledExtensionCount = num_extensions;
769 if (vkCreateDevice(screen->pdev, &dci, NULL, &screen->dev) != VK_SUCCESS)
770 goto fail;
771
772 screen->winsys = winsys;
773
774 screen->base.get_name = zink_get_name;
775 screen->base.get_vendor = zink_get_vendor;
776 screen->base.get_device_vendor = zink_get_device_vendor;
777 screen->base.get_param = zink_get_param;
778 screen->base.get_paramf = zink_get_paramf;
779 screen->base.get_shader_param = zink_get_shader_param;
780 screen->base.get_compiler_options = zink_get_compiler_options;
781 screen->base.is_format_supported = zink_is_format_supported;
782 screen->base.context_create = zink_context_create;
783 screen->base.flush_frontbuffer = zink_flush_frontbuffer;
784 screen->base.destroy = zink_destroy_screen;
785
786 zink_screen_resource_init(&screen->base);
787 zink_screen_fence_init(&screen->base);
788
789 slab_create_parent(&screen->transfer_pool, sizeof(struct zink_transfer), 16);
790
791 return &screen->base;
792
793 fail:
794 FREE(screen);
795 return NULL;
796 }
797
798 struct pipe_screen *
799 zink_create_screen(struct sw_winsys *winsys)
800 {
801 return zink_internal_create_screen(winsys, -1);
802 }
803
804 struct pipe_screen *
805 zink_drm_create_screen(int fd)
806 {
807 return zink_internal_create_screen(NULL, fd);
808 }