zink_screen.c 61.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * Copyright 2018 Collabora Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "zink_screen.h"

#include "zink_compiler.h"
#include "zink_context.h"
28
#include "zink_device_info.h"
29
#include "zink_descriptors.h"
30
#include "zink_fence.h"
31
#include "zink_format.h"
32
#include "zink_framebuffer.h"
33
#include "zink_instance.h"
34
35
36
37
38
#include "zink_public.h"
#include "zink_resource.h"

#include "os/os_process.h"
#include "util/u_debug.h"
39
#include "util/format/u_format.h"
40
#include "util/hash_table.h"
41
42
43
44
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_screen.h"
#include "util/u_string.h"
Erik Faye-Lund's avatar
Erik Faye-Lund committed
45
#include "util/u_transfer_helper.h"
46
#include "util/xmlconfig.h"
47

48
49
#include "util/u_cpu_detect.h"

50
#include "frontend/sw_winsys.h"
51
52

static const struct debug_named_value
53
zink_debug_options[] = {
54
55
56
   { "nir", ZINK_DEBUG_NIR, "Dump NIR during program compile" },
   { "spirv", ZINK_DEBUG_SPIRV, "Dump SPIR-V during program compile" },
   { "tgsi", ZINK_DEBUG_TGSI, "Dump TGSI during program compile" },
57
   { "validation", ZINK_DEBUG_VALIDATION, "Dump Validation layer output" },
58
59
60
   DEBUG_NAMED_VALUE_END
};

61
DEBUG_GET_ONCE_FLAGS_OPTION(zink_debug, "ZINK_DEBUG", zink_debug_options, 0)
62
63
64
65

uint32_t
zink_debug;

66
67
68
69
70
71
72
73
74
75
76

static const struct debug_named_value
zink_descriptor_options[] = {
   { "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" },
   { "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" },
   { "notemplates", ZINK_DESCRIPTOR_MODE_NOTEMPLATES, "Cache, but disable templated updates" },
   DEBUG_NAMED_VALUE_END
};

DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)

77
78
79
80
81
82
83
84
85
86
87
static const char *
zink_get_vendor(struct pipe_screen *pscreen)
{
   return "Collabora Ltd";
}

static const char *
zink_get_device_vendor(struct pipe_screen *pscreen)
{
   struct zink_screen *screen = zink_screen(pscreen);
   static char buf[1000];
88
   snprintf(buf, sizeof(buf), "Unknown (vendor-id: 0x%04x)", screen->info.props.vendorID);
89
90
91
92
93
94
95
96
   return buf;
}

static const char *
zink_get_name(struct pipe_screen *pscreen)
{
   struct zink_screen *screen = zink_screen(pscreen);
   static char buf[1000];
97
   snprintf(buf, sizeof(buf), "zink (%s)", screen->info.props.deviceName);
98
99
100
   return buf;
}

101
102
103
104
105
106
static bool
equals_ivci(const void *a, const void *b)
{
   return memcmp(a, b, sizeof(VkImageViewCreateInfo)) == 0;
}

Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
107
108
109
110
111
112
static bool
equals_bvci(const void *a, const void *b)
{
   return memcmp(a, b, sizeof(VkBufferViewCreateInfo)) == 0;
}

113
114
115
116
117
118
119
120
121
122
123
124
125
126
static uint32_t
hash_framebuffer_state(const void *key)
{
   struct zink_framebuffer_state* s = (struct zink_framebuffer_state*)key;
   return _mesa_hash_data(key, offsetof(struct zink_framebuffer_state, attachments) + sizeof(s->attachments[0]) * s->num_attachments);
}

static bool
equals_framebuffer_state(const void *a, const void *b)
{
   struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)a;
   return memcmp(a, b, offsetof(struct zink_framebuffer_state, attachments) + sizeof(s->attachments[0]) * s->num_attachments) == 0;
}

127
static VkDeviceSize
128
129
130
get_video_mem(struct zink_screen *screen)
{
   VkDeviceSize size = 0;
131
132
   for (uint32_t i = 0; i < screen->info.mem_props.memoryHeapCount; ++i) {
      if (screen->info.mem_props.memoryHeaps[i].flags &
133
          VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
134
         size += screen->info.mem_props.memoryHeaps[i].size;
135
   }
136
   return size;
137
138
}

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
static void
disk_cache_init(struct zink_screen *screen)
{
#ifdef ENABLE_SHADER_CACHE
   static char buf[1000];
   snprintf(buf, sizeof(buf), "zink_%x04x", screen->info.props.vendorID);

   screen->disk_cache = disk_cache_create(buf, screen->info.props.deviceName, 0);
   if (screen->disk_cache)
      disk_cache_compute_key(screen->disk_cache, buf, strlen(buf), screen->disk_cache_key);
#endif
}

void
zink_screen_update_pipeline_cache(struct zink_screen *screen)
{
   size_t size = 0;

   if (!screen->disk_cache)
      return;
   if (vkGetPipelineCacheData(screen->dev, screen->pipeline_cache, &size, NULL) != VK_SUCCESS)
      return;
   if (screen->pipeline_cache_size == size)
      return;
   void *data = malloc(size);
   if (!data)
      return;
   if (vkGetPipelineCacheData(screen->dev, screen->pipeline_cache, &size, data) == VK_SUCCESS) {
      screen->pipeline_cache_size = size;
      disk_cache_put(screen->disk_cache, screen->disk_cache_key, data, size, NULL);
   }
   free(data);
}

173
174
175
176
177
178
179
180
181
182
183
184
185
static int
zink_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
                       enum pipe_compute_cap param, void *ret)
{
   struct zink_screen *screen = zink_screen(pscreen);
#define RET(x) do {                  \
   if (ret)                          \
      memcpy(ret, x, sizeof(x));     \
   return sizeof(x);                 \
} while (0)

   switch (param) {
   case PIPE_COMPUTE_CAP_ADDRESS_BITS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
186
      RET((uint32_t []){ 64 });
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

   case PIPE_COMPUTE_CAP_IR_TARGET:
      if (ret)
         strcpy(ret, "nir");
      return 4;

   case PIPE_COMPUTE_CAP_GRID_DIMENSION:
      RET((uint64_t []) { 3 });

   case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
      RET(((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupCount[0],
                           screen->info.props.limits.maxComputeWorkGroupCount[1],
                           screen->info.props.limits.maxComputeWorkGroupCount[2] }));

   case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
      /* MaxComputeWorkGroupSize[0..2] */
      RET(((uint64_t []) {screen->info.props.limits.maxComputeWorkGroupSize[0],
                          screen->info.props.limits.maxComputeWorkGroupSize[1],
                          screen->info.props.limits.maxComputeWorkGroupSize[2]}));

   case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
   case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
      RET((uint64_t []) { screen->info.props.limits.maxComputeWorkGroupInvocations });

Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
211
   case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
212
213
214
215
216
217
218
219
220
221
   case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
      RET((uint64_t []) { screen->info.props.limits.maxComputeSharedMemorySize });

   case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
      RET((uint32_t []) { 1 });

   case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
      RET((uint32_t []) { screen->info.props11.subgroupSize });

   case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
222
223
224
   case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
      RET((uint64_t []) { 1 << 30 }); /* does vulkan even expose this? */

225
   case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
226
227
      RET((uint32_t []) { 400 }); /* does vulkan even expose this? */

228
   case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
229
      RET((uint32_t []) { 8 }); /* does vulkan even expose this? */
230
   case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
231
      RET((uint64_t []) { 1024 }); /* does vulkan even expose this? */
232
233
234
235
236
237

   default:
      unreachable("unknown compute param");
   }
}

238
239
240
241
242
243
static int
zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
   struct zink_screen *screen = zink_screen(pscreen);

   switch (param) {
244
245
246
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return screen->info.feats.features.samplerAnisotropy;

247
   case PIPE_CAP_NPOT_TEXTURES:
248
   case PIPE_CAP_TGSI_TEXCOORD:
249
   case PIPE_CAP_DRAW_INDIRECT:
250
   case PIPE_CAP_TEXTURE_QUERY_LOD:
251
   case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
252
   case PIPE_CAP_CLEAR_TEXTURE:
253
   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
254
   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
255
   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
256
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
257
   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
258
   case PIPE_CAP_QUERY_BUFFER_OBJECT:
259
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
260
   case PIPE_CAP_CLIP_HALFZ:
261
   case PIPE_CAP_TGSI_TXQS:
262
   case PIPE_CAP_TEXTURE_BARRIER:
263
   case PIPE_CAP_TGSI_VOTE:
264
   case PIPE_CAP_DRAW_PARAMETERS:
265
   case PIPE_CAP_QUERY_SO_OVERFLOW:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
266
   case PIPE_CAP_GL_SPIRV:
267
   case PIPE_CAP_CLEAR_SCISSORED:
268
   case PIPE_CAP_INVALIDATE_BUFFER:
269
   case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0:
270
271
      return 1;

272
273
274
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
      return screen->info.have_KHR_sampler_mirror_clamp_to_edge;

275
276
277
   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
      return screen->info.feats.features.depthBiasClamp;

278
279
280
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE:
      return screen->info.feats.features.pipelineStatisticsQuery;

281
282
283
   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
      return screen->info.feats.features.robustBufferAccess;

284
   case PIPE_CAP_MULTI_DRAW_INDIRECT:
285
286
      return screen->info.feats.features.multiDrawIndirect;

287
   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
288
      return screen->info.have_KHR_draw_indirect_count;
289

290
   case PIPE_CAP_START_INSTANCE:
291
292
      return (screen->info.have_vulkan12 && screen->info.feats11.shaderDrawParameters) ||
              screen->info.have_KHR_shader_draw_parameters;
293

294
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
295
      return screen->info.have_EXT_vertex_attribute_divisor;
296

297
298
299
   case PIPE_CAP_BLEND_EQUATION_ADVANCED:
      return screen->info.have_EXT_blend_operation_advanced;

300
301
302
   case PIPE_CAP_MAX_VERTEX_STREAMS:
      return screen->info.tf_props.maxTransformFeedbackStreams;

303
304
305
306
307
   case PIPE_CAP_INT64:
   case PIPE_CAP_INT64_DIVMOD:
   case PIPE_CAP_DOUBLES:
      return 1;

308
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
309
      if (!screen->info.feats.features.dualSrcBlend)
310
         return 0;
311
      return screen->info.props.limits.maxFragmentDualSrcAttachments;
312
313

   case PIPE_CAP_MAX_RENDER_TARGETS:
314
      return screen->info.props.limits.maxColorAttachments;
315

Dave Airlie's avatar
Dave Airlie committed
316
   case PIPE_CAP_OCCLUSION_QUERY:
317
318
      return 1;

319
320
321
   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
      return screen->info.have_EXT_sample_locations && screen->info.have_EXT_extended_dynamic_state;

Dave Airlie's avatar
Dave Airlie committed
322
   case PIPE_CAP_QUERY_TIME_ELAPSED:
323
      return screen->timestamp_valid_bits > 0;
Dave Airlie's avatar
Dave Airlie committed
324

325
326
327
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
      return 1;

328
329
330
   case PIPE_CAP_FRAGMENT_SHADER_INTERLOCK:
      return screen->info.have_EXT_fragment_shader_interlock;

331
332
333
   case PIPE_CAP_TGSI_CLOCK:
      return screen->info.have_KHR_shader_clock;

Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
334
335
336
   case PIPE_CAP_POINT_SPRITE:
      return 1;

337
338
339
   case PIPE_CAP_SAMPLE_SHADING:
      return screen->info.feats.features.sampleRateShading;

340
341
342
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;

Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
343
344
345
   case PIPE_CAP_GL_CLAMP:
      return 0;

346
347
348
349
350
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR ||
             screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR ?
             0 : PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;

351
   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
352
      return screen->info.props.limits.maxImageDimension2D;
353
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
354
      return 1 + util_logbase2(screen->info.props.limits.maxImageDimension3D);
355
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
356
      return 1 + util_logbase2(screen->info.props.limits.maxImageDimensionCube);
357
358
359
360
361
362

   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
   case PIPE_CAP_VERTEX_SHADER_SATURATE:
      return 1;

363
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
364
365
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
366
      return screen->info.feats.features.independentBlend;
367

368
369
370
   case PIPE_CAP_NO_DITHERING:
      return 1;

371
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
372
      return screen->info.have_EXT_transform_feedback ? screen->info.tf_props.maxTransformFeedbackBuffers : 0;
373
374
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
375
      return screen->info.have_EXT_transform_feedback;
376

377
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
378
      return screen->info.props.limits.maxImageArrayLayers;
379
380

   case PIPE_CAP_DEPTH_CLIP_DISABLE:
381
      return screen->info.feats.features.depthClamp;
382

383
384
385
386
387
388
389
390
391
392
393
   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
      return screen->info.have_EXT_conservative_rasterization ? 8 : 0;

   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
      return screen->info.have_EXT_conservative_rasterization &&
             screen->info.cons_raster_props.conservativePointAndLineRasterization;

   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
      return screen->info.have_EXT_conservative_rasterization &&
             screen->info.cons_raster_props.conservativeRasterizationPostDepthCoverage;

394
395
396
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
      return screen->info.have_EXT_shader_stencil_export;

397
   case PIPE_CAP_TGSI_INSTANCEID:
398
399
400
401
402
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
      return 1;

   case PIPE_CAP_MIN_TEXEL_OFFSET:
403
      return screen->info.props.limits.minTexelOffset;
404
   case PIPE_CAP_MAX_TEXEL_OFFSET:
405
      return screen->info.props.limits.maxTexelOffset;
406
407
408
409

   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1;

410
   case PIPE_CAP_CONDITIONAL_RENDER:
411
     return screen->info.have_EXT_conditional_rendering;
412

413
   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
414
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
415
      return 460;
416
417
418
419
420

   case PIPE_CAP_COMPUTE:
      return 1;

   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
421
      return screen->info.props.limits.minUniformBufferOffsetAlignment;
422

Dave Airlie's avatar
Dave Airlie committed
423
   case PIPE_CAP_QUERY_TIMESTAMP:
424
425
      return screen->info.have_EXT_calibrated_timestamps &&
             screen->timestamp_valid_bits > 0;
Dave Airlie's avatar
Dave Airlie committed
426

427
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
428
      return screen->info.props.limits.minMemoryMapAlignment;
429
430

   case PIPE_CAP_CUBE_MAP_ARRAY:
431
      return screen->info.feats.features.imageCubeArray;
432

433
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
434
   case PIPE_CAP_PRIMITIVE_RESTART:
435
436
437
      return 1;

   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
438
      return screen->info.props.limits.minTexelBufferOffsetAlignment;
439

440
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
441
      return 1;
442
443

   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
444
      return screen->info.props.limits.maxTexelBufferElements;
445
446
447
448
449

   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_NATIVE; /* unsure */

   case PIPE_CAP_MAX_VIEWPORTS:
450
      return screen->info.props.limits.maxViewports;
451

452
   case PIPE_CAP_IMAGE_LOAD_FORMATTED:
453
454
455
      return screen->info.feats.features.shaderStorageImageExtendedFormats &&
             screen->info.feats.features.shaderStorageImageReadWithoutFormat &&
             screen->info.feats.features.shaderStorageImageWriteWithoutFormat;
456

457
458
459
460
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
      return 1;

   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
461
      return screen->info.props.limits.maxGeometryOutputVertices;
462
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
463
      return screen->info.props.limits.maxGeometryTotalOutputComponents;
464
465
466
467
468

   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
      return 4;

   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
469
      return screen->info.props.limits.minTexelGatherOffset;
470
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
471
      return screen->info.props.limits.maxTexelGatherOffset;
472

473
474
475
476
   case PIPE_CAP_SAMPLER_REDUCTION_MINMAX:
      return screen->vk_version >= VK_MAKE_VERSION(1,2,0) || screen->info.have_EXT_sampler_filter_minmax ?
         PIPE_SAMPLER_REDUCTION_MINMAX_ARB : 0;

477
478
479
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
      return 1;

480
   case PIPE_CAP_VENDOR_ID:
481
      return screen->info.props.vendorID;
482
   case PIPE_CAP_DEVICE_ID:
483
      return screen->info.props.deviceID;
484
485
486
487

   case PIPE_CAP_ACCELERATED:
      return 1;
   case PIPE_CAP_VIDEO_MEMORY:
488
      return get_video_mem(screen) >> 20;
489
   case PIPE_CAP_UMA:
490
      return screen->info.props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
491
492

   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
493
      return screen->info.props.limits.maxVertexInputBindingStride;
494
495

   case PIPE_CAP_SAMPLER_VIEW_TARGET:
496
   case PIPE_CAP_EMULATE_ARGB:
497
498
      return 1;

499
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
500
   case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
501
502
503
      return screen->info.have_EXT_shader_viewport_index_layer ||
             (screen->info.feats12.shaderOutputLayer &&
              screen->info.feats12.shaderOutputViewportIndex);
504

505
506
507
508
509
   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
      return 1;

   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
510
      return screen->info.props.limits.minStorageBufferOffsetAlignment;
511
512
513
514
515
516
517
518

   case PIPE_CAP_PCI_GROUP:
   case PIPE_CAP_PCI_BUS:
   case PIPE_CAP_PCI_DEVICE:
   case PIPE_CAP_PCI_FUNCTION:
      return 0; /* TODO: figure these out */

   case PIPE_CAP_CULL_DISTANCE:
519
      return screen->info.feats.features.shaderCullDistance;
520

521
522
523
524
   case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
      /* this is the spec minimum */
      return screen->info.feats.features.sparseBinding ? 64 * 1024 : 0;

525
   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
526
      return screen->info.props.limits.viewportSubPixelBits;
527
528
529
530
531

   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
      return 0; /* not sure */

   case PIPE_CAP_MAX_GS_INVOCATIONS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
532
      return screen->info.props.limits.maxGeometryShaderInvocations;
533
534

   case PIPE_CAP_MAX_COMBINED_SHADER_BUFFERS:
535
536
      /* gallium handles this automatically */
      return 0;
537
538

   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
539
      /* 1<<27 is required by VK spec */
540
541
542
      assert(screen->info.props.limits.maxStorageBufferRange >= 1 << 27);
      /* but Gallium can't handle values that are too big, so clamp to VK spec minimum */
      return 1 << 27;
543
544
545
546
547
548
549
550
551

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return 1;

   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return 0;

Erik Faye-Lund's avatar
Erik Faye-Lund committed
552
553
554
   case PIPE_CAP_NIR_COMPACT_ARRAYS:
      return 1;

555
556
557
   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
      return 1;

558
559
560
   case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
      return 1;

Dave Airlie's avatar
Dave Airlie committed
561
   case PIPE_CAP_FLATSHADE:
562
   case PIPE_CAP_ALPHA_TEST:
Erik Faye-Lund's avatar
Erik Faye-Lund committed
563
   case PIPE_CAP_CLIP_PLANES:
Erik Faye-Lund's avatar
Erik Faye-Lund committed
564
   case PIPE_CAP_POINT_SIZE_FIXED:
565
   case PIPE_CAP_TWO_SIDED_COLOR:
Dave Airlie's avatar
Dave Airlie committed
566
567
      return 0;

568
569
570
571
572
573
   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
      return screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
   case PIPE_CAP_MAX_VARYINGS:
      /* need to reserve up to 60 of our varying components and 16 slots for streamout */
      return MIN2(screen->info.props.limits.maxVertexOutputComponents / 4 / 2, 16);

574
   case PIPE_CAP_DMABUF:
575
      return screen->info.have_KHR_external_memory_fd;
576

577
578
579
   case PIPE_CAP_DEPTH_BOUNDS_TEST:
      return screen->info.feats.features.depthBounds;

580
581
582
   case PIPE_CAP_POST_DEPTH_COVERAGE:
      return screen->info.have_EXT_post_depth_coverage;

583
584
585
586
587
588
589
590
591
592
593
594
595
   default:
      return u_pipe_screen_get_param_defaults(pscreen, param);
   }
}

static float
zink_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
{
   struct zink_screen *screen = zink_screen(pscreen);

   switch (param) {
   case PIPE_CAPF_MAX_LINE_WIDTH:
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
596
597
      if (!screen->info.feats.features.wideLines)
         return 1.0f;
598
      return screen->info.props.limits.lineWidthRange[1];
599
600
601

   case PIPE_CAPF_MAX_POINT_WIDTH:
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
602
603
      if (!screen->info.feats.features.largePoints)
         return 1.0f;
604
      return screen->info.props.limits.pointSizeRange[1];
605
606

   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
607
608
      if (!screen->info.feats.features.samplerAnisotropy)
         return 1.0f;
609
      return screen->info.props.limits.maxSamplerAnisotropy;
610
611

   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
612
      return screen->info.props.limits.maxSamplerLodBias;
613
614
615
616
617
618
619
620

   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
      return 0.0f; /* not implemented */
   }

   /* should only get here on unhandled cases */
621
   return 0.0f;
622
623
624
625
626
627
628
629
630
631
632
}

static int
zink_get_shader_param(struct pipe_screen *pscreen,
                       enum pipe_shader_type shader,
                       enum pipe_shader_cap param)
{
   struct zink_screen *screen = zink_screen(pscreen);

   switch (param) {
   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
633
634
635
636
      switch (shader) {
      case PIPE_SHADER_FRAGMENT:
      case PIPE_SHADER_VERTEX:
         return INT_MAX;
637
638
      case PIPE_SHADER_TESS_CTRL:
      case PIPE_SHADER_TESS_EVAL:
639
         if (screen->info.feats.features.tessellationShader &&
640
             screen->info.have_KHR_maintenance2)
641
642
            return INT_MAX;
         break;
643
644
645
646
647
648

      case PIPE_SHADER_GEOMETRY:
         if (screen->info.feats.features.geometryShader)
            return INT_MAX;
         break;

649
650
      case PIPE_SHADER_COMPUTE:
         return INT_MAX;
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
651
652
653
654
      default:
         break;
      }
      return 0;
655
656
657
658
659
660
661
662
663
   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
      if (shader == PIPE_SHADER_VERTEX ||
          shader == PIPE_SHADER_FRAGMENT)
         return INT_MAX;
      return 0;

664
665
   case PIPE_SHADER_CAP_MAX_INPUTS: {
      uint32_t max = 0;
666
667
      switch (shader) {
      case PIPE_SHADER_VERTEX:
668
669
         max = MIN2(screen->info.props.limits.maxVertexInputAttributes, PIPE_MAX_ATTRIBS);
         break;
670
      case PIPE_SHADER_TESS_CTRL:
671
672
         max = screen->info.props.limits.maxTessellationControlPerVertexInputComponents / 4;
         break;
673
      case PIPE_SHADER_TESS_EVAL:
674
675
         max = screen->info.props.limits.maxTessellationEvaluationInputComponents / 4;
         break;
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
676
      case PIPE_SHADER_GEOMETRY:
677
678
         max = screen->info.props.limits.maxGeometryInputComponents;
         break;
679
      case PIPE_SHADER_FRAGMENT:
680
681
682
683
684
685
         /* intel drivers report fewer components, but it's a value that's compatible
          * with what we need for GL, so we can still force a conformant value here
          */
         if (screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR ||
             screen->info.driver_props.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR)
            return 32;
686
687
         max = screen->info.props.limits.maxFragmentInputComponents / 4;
         break;
688
689
690
      default:
         return 0; /* unsupported stage */
      }
691
692
      return MIN2(max, 64); // prevent overflowing struct shader_info::inputs_read
   }
693

694
695
   case PIPE_SHADER_CAP_MAX_OUTPUTS: {
      uint32_t max = 0;
696
697
      switch (shader) {
      case PIPE_SHADER_VERTEX:
698
699
         max = screen->info.props.limits.maxVertexOutputComponents / 4;
         break;
700
      case PIPE_SHADER_TESS_CTRL:
701
702
         max = screen->info.props.limits.maxTessellationControlPerVertexOutputComponents / 4;
         break;
703
      case PIPE_SHADER_TESS_EVAL:
704
705
         max = screen->info.props.limits.maxTessellationEvaluationOutputComponents / 4;
         break;
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
706
      case PIPE_SHADER_GEOMETRY:
707
708
         max = screen->info.props.limits.maxGeometryOutputComponents / 4;
         break;
709
      case PIPE_SHADER_FRAGMENT:
710
711
         max = screen->info.props.limits.maxColorAttachments;
         break;
712
713
714
      default:
         return 0; /* unsupported stage */
      }
715
716
      return MIN2(max, 64); // prevent overflowing struct shader_info::outputs_read/written
   }
717
718

   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
719
      /* At least 16384 is guaranteed by VK spec */
720
721
722
      assert(screen->info.props.limits.maxUniformBufferRange >= 16384);
      /* but Gallium can't handle values that are too big */
      return MIN2(screen->info.props.limits.maxUniformBufferRange, 1 << 31);
723
724

   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
725
726
      return  MIN2(screen->info.props.limits.maxPerStageDescriptorUniformBuffers,
                   PIPE_MAX_CONSTANT_BUFFERS);
727
728
729
730

   case PIPE_SHADER_CAP_MAX_TEMPS:
      return INT_MAX;

731
732
733
   case PIPE_SHADER_CAP_INTEGERS:
      return 1;

734
735
736
   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
      return 1;

737
738
739
740
741
742
   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
   case PIPE_SHADER_CAP_SUBROUTINES:
   case PIPE_SHADER_CAP_INT64_ATOMICS:
   case PIPE_SHADER_CAP_FP16:
743
744
   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
   case PIPE_SHADER_CAP_INT16:
745
   case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
746
747
748
749
750
751
752
753
      return 0; /* not implemented */

   case PIPE_SHADER_CAP_PREFERRED_IR:
      return PIPE_SHADER_IR_NIR;

   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
      return 0; /* not implemented */

754
   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
755
   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
756
757
758
      return MIN2(MIN2(screen->info.props.limits.maxPerStageDescriptorSamplers,
                       screen->info.props.limits.maxPerStageDescriptorSampledImages),
                  PIPE_MAX_SAMPLERS);
759
760
761
762
763
764
765
766
767
768
769
770
771

   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
      return 0; /* not implemented */

   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
      return 0; /* no idea */

   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
      return 32; /* arbitrary */

   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
      switch (shader) {
      case PIPE_SHADER_VERTEX:
      case PIPE_SHADER_TESS_CTRL:
      case PIPE_SHADER_TESS_EVAL:
      case PIPE_SHADER_GEOMETRY:
         if (!screen->info.feats.features.vertexPipelineStoresAndAtomics)
            return 0;
         break;

      case PIPE_SHADER_FRAGMENT:
         if (!screen->info.feats.features.fragmentStoresAndAtomics)
            return 0;
         break;

      default:
         break;
      }

790
791
      /* TODO: this limitation is dumb, and will need some fixes in mesa */
      return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageBuffers, PIPE_MAX_SHADER_BUFFERS);
792
793

   case PIPE_SHADER_CAP_SUPPORTED_IRS:
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
794
      return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED);
795
796

   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
797
      if ((screen->info.have_KHR_vulkan_memory_model || !screen->needs_vk_mem_model) &&
798
799
800
801
802
          (screen->info.feats.features.shaderStorageImageExtendedFormats ||
          (screen->info.feats.features.shaderStorageImageWriteWithoutFormat &&
           screen->info.feats.features.shaderStorageImageReadWithoutFormat)))
         return MIN2(screen->info.props.limits.maxPerStageDescriptorStorageImages,
                     PIPE_MAX_SHADER_IMAGES);
803
      return 0;
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819

   case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
   case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
      return 0; /* unsure */

   case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
      return 0; /* not implemented */
   }

   /* should only get here on unhandled cases */
   return 0;
}

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
static VkSampleCountFlagBits
vk_sample_count_flags(uint32_t sample_count)
{
   switch (sample_count) {
   case 1: return VK_SAMPLE_COUNT_1_BIT;
   case 2: return VK_SAMPLE_COUNT_2_BIT;
   case 4: return VK_SAMPLE_COUNT_4_BIT;
   case 8: return VK_SAMPLE_COUNT_8_BIT;
   case 16: return VK_SAMPLE_COUNT_16_BIT;
   case 32: return VK_SAMPLE_COUNT_32_BIT;
   case 64: return VK_SAMPLE_COUNT_64_BIT;
   default:
      return 0;
   }
}

836
837
838
839
840
841
842
843
844
845
static bool
zink_is_format_supported(struct pipe_screen *pscreen,
                         enum pipe_format format,
                         enum pipe_texture_target target,
                         unsigned sample_count,
                         unsigned storage_sample_count,
                         unsigned bind)
{
   struct zink_screen *screen = zink_screen(pscreen);

846
   if (format == PIPE_FORMAT_NONE)
847
      return screen->info.props.limits.framebufferNoAttachmentsSampleCounts &
848
             vk_sample_count_flags(sample_count);
849

850
   VkFormat vkformat = zink_get_format(screen, format);
851
   if (vkformat == VK_FORMAT_UNDEFINED)
852
      return false;
853

854
855
   if (sample_count >= 1) {
      VkSampleCountFlagBits sample_mask = vk_sample_count_flags(sample_count);
856
857
      if (!sample_mask)
         return false;
858
      const struct util_format_description *desc = util_format_description(format);
859
860
861
      if (util_format_is_depth_or_stencil(format)) {
         if (util_format_has_depth(desc)) {
            if (bind & PIPE_BIND_DEPTH_STENCIL &&
862
                (screen->info.props.limits.framebufferDepthSampleCounts & sample_mask) != sample_mask)
863
               return false;
864
            if (bind & PIPE_BIND_SAMPLER_VIEW &&
865
                (screen->info.props.limits.sampledImageDepthSampleCounts & sample_mask) != sample_mask)
866
               return false;
867
868
869
         }
         if (util_format_has_stencil(desc)) {
            if (bind & PIPE_BIND_DEPTH_STENCIL &&
870
                (screen->info.props.limits.framebufferStencilSampleCounts & sample_mask) != sample_mask)
871
               return false;
872
            if (bind & PIPE_BIND_SAMPLER_VIEW &&
873
                (screen->info.props.limits.sampledImageStencilSampleCounts & sample_mask) != sample_mask)
874
               return false;
875
876
877
         }
      } else if (util_format_is_pure_integer(format)) {
         if (bind & PIPE_BIND_RENDER_TARGET &&
878
             !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
879
            return false;
880
         if (bind & PIPE_BIND_SAMPLER_VIEW &&
881
             !(screen->info.props.limits.sampledImageIntegerSampleCounts & sample_mask))
882
            return false;
883
884
      } else {
         if (bind & PIPE_BIND_RENDER_TARGET &&
885
             !(screen->info.props.limits.framebufferColorSampleCounts & sample_mask))
886
            return false;
887
         if (bind & PIPE_BIND_SAMPLER_VIEW &&
888
             !(screen->info.props.limits.sampledImageColorSampleCounts & sample_mask))
889
            return false;
890
      }
891
      if (bind & PIPE_BIND_SHADER_IMAGE) {
892
          if (!(screen->info.props.limits.storageImageSampleCounts & sample_mask))
893
894
             return false;
      }
895
896
   }

897
   VkFormatProperties props = screen->format_props[format];
898
899
900
901

   if (target == PIPE_BUFFER) {
      if (bind & PIPE_BIND_VERTEX_BUFFER &&
          !(props.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT))
902
         return false;
903

904
905
906
907
      if (bind & PIPE_BIND_SAMPLER_VIEW) {
         if (!(props.bufferFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT))
            return false;
         /* we can't swizzle these, so we can't sample from them either */
908
909
         if (util_format_is_argb(format) || util_format_is_abgr(format) ||
             util_format_is_xrgb(format) || util_format_is_xbgr(format))
910
            return false;
911
      }
912
913
914
915

      if (bind & PIPE_BIND_SHADER_IMAGE &&
          !(props.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT))
         return false;
916
917
918
919
   } else {
      /* all other targets are texture-targets */
      if (bind & PIPE_BIND_RENDER_TARGET &&
          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
920
         return false;
921
922
923

      if (bind & PIPE_BIND_BLENDABLE &&
         !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT))
924
        return false;
925
926

      if (bind & PIPE_BIND_SAMPLER_VIEW &&
927
928
929
         !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
            return false;

930
931
932
      if (bind & PIPE_BIND_SAMPLER_REDUCTION_MINMAX)
         return props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;

933
934
935
936
937
938
939
      if ((bind & PIPE_BIND_SAMPLER_VIEW) || (bind & PIPE_BIND_RENDER_TARGET)) {
         /* if this is a 3-component texture, force gallium to give us 4 components by rejecting this one */
         const struct util_format_description *desc = util_format_description(format);
         if (desc->nr_channels == 3 &&
             (desc->block.bits == 24 || desc->block.bits == 48 || desc->block.bits == 96))
            return false;
      }
940
941
942

      if (bind & PIPE_BIND_DEPTH_STENCIL &&
          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
943
         return false;
944
945
946
947

      if (bind & PIPE_BIND_SHADER_IMAGE &&
          !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
         return false;
948
949
   }

950
951
952
   if (util_format_is_compressed(format)) {
      const struct util_format_description *desc = util_format_description(format);
      if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC &&
953
          !screen->info.feats.features.textureCompressionBC)
954
         return false;
955
   }
956

957
   return true;
958
959
}

960
961
962
963
static void
resource_cache_entry_destroy(struct zink_screen *screen, struct hash_entry *he)
{
   struct util_dynarray *array = (void*)he->data;
964
965
966
   util_dynarray_foreach(array, struct mem_cache_entry, mc) {
      vkFreeMemory(screen->dev, mc->mem, NULL);
   }
967
968
969
   util_dynarray_fini(array);
}

970
971
972
973
static void
zink_destroy_screen(struct pipe_screen *pscreen)
{
   struct zink_screen *screen = zink_screen(pscreen);
974
975
976
977
978

   if (VK_NULL_HANDLE != screen->debugUtilsCallbackHandle) {
      screen->vk_DestroyDebugUtilsMessengerEXT(screen->instance, screen->debugUtilsCallbackHandle, NULL);
   }

979
980
   hash_table_foreach(&screen->surface_cache, entry) {
      struct pipe_surface *psurf = (struct pipe_surface*)entry->data;
981
982
      /* context is already destroyed, so this has to be destroyed directly */
      zink_destroy_surface(screen, psurf);
983
984
   }

Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
985
986
987
988
989
   hash_table_foreach(&screen->bufferview_cache, entry) {
      struct zink_buffer_view *bv = (struct zink_buffer_view*)entry->data;
      zink_buffer_view_reference(screen, &bv, NULL);
   }

990
991
992
993
994
   hash_table_foreach(&screen->framebuffer_cache, entry) {
      struct zink_framebuffer* fb = (struct zink_framebuffer*)entry->data;
      zink_destroy_framebuffer(screen, fb);
   }

995
   simple_mtx_destroy(&screen->surface_mtx);
Mike Blumenkrantz's avatar
Mike Blumenkrantz committed
996
   simple_mtx_destroy(&screen->bufferview_mtx);
997
   simple_mtx_destroy(&screen->framebuffer_mtx);
998

Erik Faye-Lund's avatar
Erik Faye-Lund committed
999
   u_transfer_helper_destroy(pscreen->transfer_helper);
1000
   zink_screen_update_pipeline_cache(screen);
For faster browsing, not all history is shown. View entire blame