Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_device.c
4565 views
1
/*
2
* Copyright © 2019 Red Hat.
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
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "lvp_private.h"
25
26
#include "pipe-loader/pipe_loader.h"
27
#include "git_sha1.h"
28
#include "vk_util.h"
29
#include "pipe/p_state.h"
30
#include "pipe/p_context.h"
31
#include "frontend/drisw_api.h"
32
33
#include "util/u_inlines.h"
34
#include "util/os_memory.h"
35
#include "util/u_thread.h"
36
#include "util/u_atomic.h"
37
#include "util/timespec.h"
38
#include "os_time.h"
39
40
#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
41
defined(VK_USE_PLATFORM_WIN32_KHR) || \
42
defined(VK_USE_PLATFORM_XCB_KHR) || \
43
defined(VK_USE_PLATFORM_XLIB_KHR) || \
44
defined(VK_USE_PLATFORM_DISPLAY_KHR)
45
#define LVP_USE_WSI_PLATFORM
46
#endif
47
#define LVP_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
48
49
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceVersion(uint32_t* pApiVersion)
50
{
51
*pApiVersion = LVP_API_VERSION;
52
return VK_SUCCESS;
53
}
54
55
static const struct vk_instance_extension_table lvp_instance_extensions_supported = {
56
.KHR_device_group_creation = true,
57
.KHR_external_fence_capabilities = true,
58
.KHR_external_memory_capabilities = true,
59
.KHR_external_semaphore_capabilities = true,
60
.KHR_get_physical_device_properties2 = true,
61
.EXT_debug_report = true,
62
#ifdef LVP_USE_WSI_PLATFORM
63
.KHR_get_surface_capabilities2 = true,
64
.KHR_surface = true,
65
.KHR_surface_protected_capabilities = true,
66
#endif
67
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
68
.KHR_wayland_surface = true,
69
#endif
70
#ifdef VK_USE_PLATFORM_WIN32_KHR
71
.KHR_win32_surface = true,
72
#endif
73
#ifdef VK_USE_PLATFORM_XCB_KHR
74
.KHR_xcb_surface = true,
75
#endif
76
#ifdef VK_USE_PLATFORM_XLIB_KHR
77
.KHR_xlib_surface = true,
78
#endif
79
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
80
.EXT_acquire_xlib_display = true,
81
#endif
82
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
83
.KHR_display = true,
84
.KHR_get_display_properties2 = true,
85
.EXT_direct_mode_display = true,
86
.EXT_display_surface_counter = true,
87
#endif
88
};
89
90
static const struct vk_device_extension_table lvp_device_extensions_supported = {
91
.KHR_8bit_storage = true,
92
.KHR_16bit_storage = true,
93
.KHR_bind_memory2 = true,
94
.KHR_buffer_device_address = true,
95
.KHR_create_renderpass2 = true,
96
.KHR_copy_commands2 = true,
97
.KHR_dedicated_allocation = true,
98
.KHR_descriptor_update_template = true,
99
.KHR_device_group = true,
100
.KHR_draw_indirect_count = true,
101
.KHR_driver_properties = true,
102
.KHR_external_fence = true,
103
.KHR_external_memory = true,
104
.KHR_external_semaphore = true,
105
.KHR_get_memory_requirements2 = true,
106
#ifdef LVP_USE_WSI_PLATFORM
107
.KHR_incremental_present = true,
108
#endif
109
.KHR_image_format_list = true,
110
.KHR_imageless_framebuffer = true,
111
.KHR_maintenance1 = true,
112
.KHR_maintenance2 = true,
113
.KHR_maintenance3 = true,
114
.KHR_multiview = true,
115
.KHR_push_descriptor = true,
116
.KHR_relaxed_block_layout = true,
117
.KHR_sampler_mirror_clamp_to_edge = true,
118
.KHR_separate_depth_stencil_layouts = true,
119
.KHR_shader_atomic_int64 = true,
120
.KHR_shader_draw_parameters = true,
121
.KHR_storage_buffer_storage_class = true,
122
#ifdef LVP_USE_WSI_PLATFORM
123
.KHR_swapchain = true,
124
#endif
125
.KHR_uniform_buffer_standard_layout = true,
126
.KHR_variable_pointers = true,
127
.EXT_calibrated_timestamps = true,
128
.EXT_conditional_rendering = true,
129
.EXT_extended_dynamic_state = true,
130
.EXT_extended_dynamic_state2 = true,
131
.EXT_host_query_reset = true,
132
.EXT_index_type_uint8 = true,
133
.EXT_multi_draw = true,
134
.EXT_post_depth_coverage = true,
135
.EXT_private_data = true,
136
.EXT_sampler_filter_minmax = true,
137
.EXT_scalar_block_layout = true,
138
.EXT_separate_stencil_usage = true,
139
.EXT_shader_stencil_export = true,
140
.EXT_shader_viewport_index_layer = true,
141
.EXT_transform_feedback = true,
142
.EXT_vertex_attribute_divisor = true,
143
.EXT_vertex_input_dynamic_state = true,
144
.EXT_custom_border_color = true,
145
.EXT_provoking_vertex = true,
146
.EXT_line_rasterization = true,
147
.GOOGLE_decorate_string = true,
148
.GOOGLE_hlsl_functionality1 = true,
149
};
150
151
static VkResult VKAPI_CALL
152
lvp_physical_device_init(struct lvp_physical_device *device,
153
struct lvp_instance *instance,
154
struct pipe_loader_device *pld)
155
{
156
VkResult result;
157
158
struct vk_physical_device_dispatch_table dispatch_table;
159
vk_physical_device_dispatch_table_from_entrypoints(
160
&dispatch_table, &lvp_physical_device_entrypoints, true);
161
result = vk_physical_device_init(&device->vk, &instance->vk,
162
NULL, &dispatch_table);
163
if (result != VK_SUCCESS) {
164
vk_error(instance, result);
165
goto fail;
166
}
167
device->pld = pld;
168
169
device->pscreen = pipe_loader_create_screen_vk(device->pld, true);
170
if (!device->pscreen)
171
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
172
173
device->max_images = device->pscreen->get_shader_param(device->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_IMAGES);
174
device->vk.supported_extensions = lvp_device_extensions_supported;
175
result = lvp_init_wsi(device);
176
if (result != VK_SUCCESS) {
177
vk_physical_device_finish(&device->vk);
178
vk_error(instance, result);
179
goto fail;
180
}
181
182
return VK_SUCCESS;
183
fail:
184
return result;
185
}
186
187
static void VKAPI_CALL
188
lvp_physical_device_finish(struct lvp_physical_device *device)
189
{
190
lvp_finish_wsi(device);
191
device->pscreen->destroy(device->pscreen);
192
vk_physical_device_finish(&device->vk);
193
}
194
195
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateInstance(
196
const VkInstanceCreateInfo* pCreateInfo,
197
const VkAllocationCallbacks* pAllocator,
198
VkInstance* pInstance)
199
{
200
struct lvp_instance *instance;
201
VkResult result;
202
203
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
204
205
if (pAllocator == NULL)
206
pAllocator = vk_default_allocator();
207
208
instance = vk_zalloc(pAllocator, sizeof(*instance), 8,
209
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
210
if (!instance)
211
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
212
213
struct vk_instance_dispatch_table dispatch_table;
214
vk_instance_dispatch_table_from_entrypoints(
215
&dispatch_table, &lvp_instance_entrypoints, true);
216
217
result = vk_instance_init(&instance->vk,
218
&lvp_instance_extensions_supported,
219
&dispatch_table,
220
pCreateInfo,
221
pAllocator);
222
if (result != VK_SUCCESS) {
223
vk_free(pAllocator, instance);
224
return vk_error(instance, result);
225
}
226
227
instance->apiVersion = LVP_API_VERSION;
228
instance->physicalDeviceCount = -1;
229
230
// _mesa_locale_init();
231
// VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
232
233
*pInstance = lvp_instance_to_handle(instance);
234
235
return VK_SUCCESS;
236
}
237
238
VKAPI_ATTR void VKAPI_CALL lvp_DestroyInstance(
239
VkInstance _instance,
240
const VkAllocationCallbacks* pAllocator)
241
{
242
LVP_FROM_HANDLE(lvp_instance, instance, _instance);
243
244
if (!instance)
245
return;
246
if (instance->physicalDeviceCount > 0)
247
lvp_physical_device_finish(&instance->physicalDevice);
248
// _mesa_locale_fini();
249
250
pipe_loader_release(&instance->devs, instance->num_devices);
251
252
vk_instance_finish(&instance->vk);
253
vk_free(&instance->vk.alloc, instance);
254
}
255
256
#if defined(HAVE_PIPE_LOADER_DRI)
257
static void lvp_get_image(struct dri_drawable *dri_drawable,
258
int x, int y, unsigned width, unsigned height, unsigned stride,
259
void *data)
260
{
261
262
}
263
264
static void lvp_put_image(struct dri_drawable *dri_drawable,
265
void *data, unsigned width, unsigned height)
266
{
267
fprintf(stderr, "put image %dx%d\n", width, height);
268
}
269
270
static void lvp_put_image2(struct dri_drawable *dri_drawable,
271
void *data, int x, int y, unsigned width, unsigned height,
272
unsigned stride)
273
{
274
fprintf(stderr, "put image 2 %d,%d %dx%d\n", x, y, width, height);
275
}
276
277
static struct drisw_loader_funcs lvp_sw_lf = {
278
.get_image = lvp_get_image,
279
.put_image = lvp_put_image,
280
.put_image2 = lvp_put_image2,
281
};
282
#endif
283
284
static VkResult
285
lvp_enumerate_physical_devices(struct lvp_instance *instance)
286
{
287
VkResult result;
288
289
if (instance->physicalDeviceCount != -1)
290
return VK_SUCCESS;
291
292
/* sw only for now */
293
instance->num_devices = pipe_loader_sw_probe(NULL, 0);
294
295
assert(instance->num_devices == 1);
296
297
#if defined(HAVE_PIPE_LOADER_DRI)
298
pipe_loader_sw_probe_dri(&instance->devs, &lvp_sw_lf);
299
#else
300
pipe_loader_sw_probe_null(&instance->devs);
301
#endif
302
303
result = lvp_physical_device_init(&instance->physicalDevice,
304
instance, &instance->devs[0]);
305
if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
306
instance->physicalDeviceCount = 0;
307
} else if (result == VK_SUCCESS) {
308
instance->physicalDeviceCount = 1;
309
}
310
311
return result;
312
}
313
314
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDevices(
315
VkInstance _instance,
316
uint32_t* pPhysicalDeviceCount,
317
VkPhysicalDevice* pPhysicalDevices)
318
{
319
LVP_FROM_HANDLE(lvp_instance, instance, _instance);
320
VkResult result;
321
322
result = lvp_enumerate_physical_devices(instance);
323
if (result != VK_SUCCESS)
324
return result;
325
326
if (!pPhysicalDevices) {
327
*pPhysicalDeviceCount = instance->physicalDeviceCount;
328
} else if (*pPhysicalDeviceCount >= 1) {
329
pPhysicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);
330
*pPhysicalDeviceCount = 1;
331
} else {
332
*pPhysicalDeviceCount = 0;
333
}
334
335
return VK_SUCCESS;
336
}
337
338
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumeratePhysicalDeviceGroups(
339
VkInstance _instance,
340
uint32_t* pPhysicalDeviceGroupCount,
341
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
342
{
343
LVP_FROM_HANDLE(lvp_instance, instance, _instance);
344
VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,
345
pPhysicalDeviceGroupProperties,
346
pPhysicalDeviceGroupCount);
347
348
VkResult result = lvp_enumerate_physical_devices(instance);
349
if (result != VK_SUCCESS)
350
return result;
351
352
vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, p) {
353
p->physicalDeviceCount = 1;
354
memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
355
p->physicalDevices[0] = lvp_physical_device_to_handle(&instance->physicalDevice);
356
p->subsetAllocation = false;
357
}
358
359
return vk_outarray_status(&out);
360
}
361
362
static int
363
min_vertex_pipeline_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
364
{
365
int val = INT_MAX;
366
for (int i = 0; i < PIPE_SHADER_COMPUTE; ++i) {
367
if (i == PIPE_SHADER_FRAGMENT ||
368
!pscreen->get_shader_param(pscreen, i,
369
PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
370
continue;
371
372
val = MAX2(val, pscreen->get_shader_param(pscreen, i, param));
373
}
374
return val;
375
}
376
377
static int
378
min_shader_param(struct pipe_screen *pscreen, enum pipe_shader_cap param)
379
{
380
return MIN3(min_vertex_pipeline_param(pscreen, param),
381
pscreen->get_shader_param(pscreen, PIPE_SHADER_FRAGMENT, param),
382
pscreen->get_shader_param(pscreen, PIPE_SHADER_COMPUTE, param));
383
}
384
385
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures(
386
VkPhysicalDevice physicalDevice,
387
VkPhysicalDeviceFeatures* pFeatures)
388
{
389
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
390
bool indirect = false;//pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_GLSL_FEATURE_LEVEL) >= 400;
391
memset(pFeatures, 0, sizeof(*pFeatures));
392
*pFeatures = (VkPhysicalDeviceFeatures) {
393
.robustBufferAccess = true,
394
.fullDrawIndexUint32 = true,
395
.imageCubeArray = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CUBE_MAP_ARRAY) != 0),
396
.independentBlend = true,
397
.geometryShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
398
.tessellationShader = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_TESS_EVAL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) != 0),
399
.sampleRateShading = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SAMPLE_SHADING) != 0),
400
.dualSrcBlend = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS) != 0),
401
.logicOp = true,
402
.multiDrawIndirect = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MULTI_DRAW_INDIRECT) != 0),
403
.drawIndirectFirstInstance = true,
404
.depthClamp = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_CLIP_DISABLE) != 0),
405
.depthBiasClamp = true,
406
.fillModeNonSolid = true,
407
.depthBounds = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DEPTH_BOUNDS_TEST) != 0),
408
.wideLines = true,
409
.largePoints = true,
410
.alphaToOne = true,
411
.multiViewport = true,
412
.samplerAnisotropy = false, /* FINISHME */
413
.textureCompressionETC2 = false,
414
.textureCompressionASTC_LDR = false,
415
.textureCompressionBC = true,
416
.occlusionQueryPrecise = true,
417
.pipelineStatisticsQuery = true,
418
.vertexPipelineStoresAndAtomics = (min_vertex_pipeline_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
419
.fragmentStoresAndAtomics = (pdevice->pscreen->get_shader_param(pdevice->pscreen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS) != 0),
420
.shaderTessellationAndGeometryPointSize = true,
421
.shaderImageGatherExtended = true,
422
.shaderStorageImageExtendedFormats = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),
423
.shaderStorageImageMultisample = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE) != 0),
424
.shaderUniformBufferArrayDynamicIndexing = indirect,
425
.shaderSampledImageArrayDynamicIndexing = indirect,
426
.shaderStorageBufferArrayDynamicIndexing = indirect,
427
.shaderStorageImageArrayDynamicIndexing = indirect,
428
.shaderStorageImageReadWithoutFormat = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_IMAGE_LOAD_FORMATTED) != 0),
429
.shaderStorageImageWriteWithoutFormat = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES) != 0),
430
.shaderClipDistance = true,
431
.shaderCullDistance = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CULL_DISTANCE) == 1),
432
.shaderFloat64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
433
.shaderInt64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
434
.shaderInt16 = (min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_INT16) == 1),
435
.variableMultisampleRate = false,
436
.inheritedQueries = false,
437
};
438
}
439
440
static void
441
lvp_get_physical_device_features_1_1(struct lvp_physical_device *pdevice,
442
VkPhysicalDeviceVulkan11Features *f)
443
{
444
assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
445
446
f->storageBuffer16BitAccess = true;
447
f->uniformAndStorageBuffer16BitAccess = true;
448
f->storagePushConstant16 = true;
449
f->storageInputOutput16 = false;
450
f->multiview = true;
451
f->multiviewGeometryShader = true;
452
f->multiviewTessellationShader = true;
453
f->variablePointersStorageBuffer = true;
454
f->variablePointers = false;
455
f->protectedMemory = false;
456
f->samplerYcbcrConversion = false;
457
f->shaderDrawParameters = true;
458
}
459
460
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFeatures2(
461
VkPhysicalDevice physicalDevice,
462
VkPhysicalDeviceFeatures2 *pFeatures)
463
{
464
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
465
lvp_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
466
467
VkPhysicalDeviceVulkan11Features core_1_1 = {
468
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
469
};
470
lvp_get_physical_device_features_1_1(pdevice, &core_1_1);
471
472
#define CORE_FEATURE(major, minor, feature) \
473
features->feature = core_##major##_##minor.feature
474
475
vk_foreach_struct(ext, pFeatures->pNext) {
476
switch (ext->sType) {
477
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {
478
VkPhysicalDeviceVariablePointersFeatures *features = (void *)ext;
479
CORE_FEATURE(1, 1, variablePointersStorageBuffer);
480
CORE_FEATURE(1, 1, variablePointers);
481
break;
482
}
483
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
484
VkPhysicalDeviceShaderDrawParametersFeatures *features =
485
(VkPhysicalDeviceShaderDrawParametersFeatures*)ext;
486
CORE_FEATURE(1, 1, shaderDrawParameters);
487
break;
488
}
489
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
490
VkPhysicalDeviceProtectedMemoryFeatures *features =
491
(VkPhysicalDeviceProtectedMemoryFeatures*)ext;
492
CORE_FEATURE(1, 1, protectedMemory);
493
break;
494
}
495
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: {
496
VkPhysicalDevice8BitStorageFeaturesKHR *features =
497
(VkPhysicalDevice8BitStorageFeaturesKHR *)ext;
498
features->storageBuffer8BitAccess = true;
499
features->uniformAndStorageBuffer8BitAccess = true;
500
features->storagePushConstant8 = true;
501
break;
502
}
503
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
504
VkPhysicalDevice16BitStorageFeatures *features =
505
(VkPhysicalDevice16BitStorageFeatures*)ext;
506
CORE_FEATURE(1, 1, storageBuffer16BitAccess);
507
CORE_FEATURE(1, 1, uniformAndStorageBuffer16BitAccess);
508
CORE_FEATURE(1, 1, storagePushConstant16);
509
CORE_FEATURE(1, 1, storageInputOutput16);
510
break;
511
}
512
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
513
VkPhysicalDevicePrivateDataFeaturesEXT *features =
514
(VkPhysicalDevicePrivateDataFeaturesEXT *)ext;
515
features->privateData = true;
516
break;
517
}
518
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
519
VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
520
(VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
521
features->rectangularLines = true;
522
features->bresenhamLines = true;
523
features->smoothLines = true;
524
features->stippledRectangularLines = true;
525
features->stippledBresenhamLines = true;
526
features->stippledSmoothLines = true;
527
break;
528
}
529
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
530
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
531
(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
532
features->vertexAttributeInstanceRateZeroDivisor = false;
533
if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0) {
534
features->vertexAttributeInstanceRateDivisor = true;
535
} else {
536
features->vertexAttributeInstanceRateDivisor = false;
537
}
538
break;
539
}
540
541
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
542
VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
543
(VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
544
features->indexTypeUint8 = true;
545
break;
546
}
547
548
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT: {
549
VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *features =
550
(VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT *)ext;
551
features->vertexInputDynamicState = true;
552
break;
553
}
554
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
555
VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
556
(VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;
557
558
features->transformFeedback = true;
559
features->geometryStreams = true;
560
break;
561
}
562
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
563
VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
564
(VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;
565
features->conditionalRendering = true;
566
features->inheritedConditionalRendering = false;
567
break;
568
}
569
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
570
VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features =
571
(VkPhysicalDeviceExtendedDynamicStateFeaturesEXT*)ext;
572
features->extendedDynamicState = true;
573
break;
574
}
575
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
576
VkPhysicalDeviceMultiviewFeatures *features = (VkPhysicalDeviceMultiviewFeatures*)ext;
577
CORE_FEATURE(1, 1, multiview);
578
CORE_FEATURE(1, 1, multiviewGeometryShader);
579
CORE_FEATURE(1, 1, multiviewTessellationShader);
580
break;
581
}
582
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
583
lvp_get_physical_device_features_1_1(pdevice, (void *)ext);
584
break;
585
}
586
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
587
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
588
(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
589
features->uniformBufferStandardLayout = true;
590
break;
591
}
592
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
593
VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =
594
(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)ext;
595
features->scalarBlockLayout = true;
596
break;
597
}
598
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
599
VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
600
(VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;
601
CORE_FEATURE(1, 1, samplerYcbcrConversion);
602
break;
603
}
604
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
605
VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
606
(VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
607
features->hostQueryReset = true;
608
break;
609
}
610
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR: {
611
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR *features = (void *)ext;
612
features->bufferDeviceAddress = true;
613
features->bufferDeviceAddressCaptureReplay = false;
614
features->bufferDeviceAddressMultiDevice = false;
615
break;
616
}
617
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
618
VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features = (void *)ext;
619
features->shaderBufferInt64Atomics = true;
620
features->shaderSharedInt64Atomics = true;
621
break;
622
}
623
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
624
VkPhysicalDeviceImagelessFramebufferFeatures *features =
625
(VkPhysicalDeviceImagelessFramebufferFeatures*)ext;
626
features->imagelessFramebuffer = true;
627
break;
628
}
629
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
630
VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =
631
(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;
632
features->separateDepthStencilLayouts = true;
633
break;
634
}
635
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
636
VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =
637
(VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;
638
features->customBorderColors = true;
639
features->customBorderColorWithoutFormat = true;
640
break;
641
}
642
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {
643
VkPhysicalDeviceProvokingVertexFeaturesEXT *features =
644
(VkPhysicalDeviceProvokingVertexFeaturesEXT*)ext;
645
features->provokingVertexLast = true;
646
features->transformFeedbackPreservesProvokingVertex = true;
647
break;
648
}
649
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: {
650
VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext;
651
features->multiDraw = true;
652
break;
653
}
654
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {
655
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
656
features->extendedDynamicState2 = true;
657
features->extendedDynamicState2LogicOp = true;
658
features->extendedDynamicState2PatchControlPoints = true;
659
break;
660
}
661
default:
662
break;
663
}
664
}
665
}
666
667
void
668
lvp_device_get_cache_uuid(void *uuid)
669
{
670
memset(uuid, 0, VK_UUID_SIZE);
671
snprintf(uuid, VK_UUID_SIZE, "val-%s", MESA_GIT_SHA1 + 4);
672
}
673
674
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
675
VkPhysicalDeviceProperties *pProperties)
676
{
677
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
678
679
VkSampleCountFlags sample_counts = VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
680
681
uint64_t grid_size[3], block_size[3];
682
uint64_t max_threads_per_block, max_local_size;
683
684
pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,
685
PIPE_COMPUTE_CAP_MAX_GRID_SIZE, grid_size);
686
pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,
687
PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE, block_size);
688
pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,
689
PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK,
690
&max_threads_per_block);
691
pdevice->pscreen->get_compute_param(pdevice->pscreen, PIPE_SHADER_IR_NIR,
692
PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE,
693
&max_local_size);
694
695
VkPhysicalDeviceLimits limits = {
696
.maxImageDimension1D = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
697
.maxImageDimension2D = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
698
.maxImageDimension3D = (1 << pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS)),
699
.maxImageDimensionCube = (1 << pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS)),
700
.maxImageArrayLayers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
701
.maxTexelBufferElements = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE),
702
.maxUniformBufferRange = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE),
703
.maxStorageBufferRange = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_SHADER_BUFFER_SIZE),
704
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
705
.maxMemoryAllocationCount = UINT32_MAX,
706
.maxSamplerAllocationCount = 32 * 1024,
707
.bufferImageGranularity = 64, /* A cache line */
708
.sparseAddressSpaceSize = 0,
709
.maxBoundDescriptorSets = MAX_SETS,
710
.maxPerStageDescriptorSamplers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS),
711
.maxPerStageDescriptorUniformBuffers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_CONST_BUFFERS) - 1,
712
.maxPerStageDescriptorStorageBuffers = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_BUFFERS),
713
.maxPerStageDescriptorSampledImages = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS),
714
.maxPerStageDescriptorStorageImages = min_shader_param(pdevice->pscreen, PIPE_SHADER_CAP_MAX_SHADER_IMAGES),
715
.maxPerStageDescriptorInputAttachments = 8,
716
.maxPerStageResources = 128,
717
.maxDescriptorSetSamplers = 32 * 1024,
718
.maxDescriptorSetUniformBuffers = 256,
719
.maxDescriptorSetUniformBuffersDynamic = 256,
720
.maxDescriptorSetStorageBuffers = 256,
721
.maxDescriptorSetStorageBuffersDynamic = 256,
722
.maxDescriptorSetSampledImages = 256,
723
.maxDescriptorSetStorageImages = 256,
724
.maxDescriptorSetInputAttachments = 256,
725
.maxVertexInputAttributes = 32,
726
.maxVertexInputBindings = 32,
727
.maxVertexInputAttributeOffset = 2047,
728
.maxVertexInputBindingStride = 2048,
729
.maxVertexOutputComponents = 128,
730
.maxTessellationGenerationLevel = 64,
731
.maxTessellationPatchSize = 32,
732
.maxTessellationControlPerVertexInputComponents = 128,
733
.maxTessellationControlPerVertexOutputComponents = 128,
734
.maxTessellationControlPerPatchOutputComponents = 128,
735
.maxTessellationControlTotalOutputComponents = 4096,
736
.maxTessellationEvaluationInputComponents = 128,
737
.maxTessellationEvaluationOutputComponents = 128,
738
.maxGeometryShaderInvocations = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GS_INVOCATIONS),
739
.maxGeometryInputComponents = 64,
740
.maxGeometryOutputComponents = 128,
741
.maxGeometryOutputVertices = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES),
742
.maxGeometryTotalOutputComponents = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS),
743
.maxFragmentInputComponents = 128,
744
.maxFragmentOutputAttachments = 8,
745
.maxFragmentDualSrcAttachments = 2,
746
.maxFragmentCombinedOutputResources = 8,
747
.maxComputeSharedMemorySize = max_local_size,
748
.maxComputeWorkGroupCount = { grid_size[0], grid_size[1], grid_size[2] },
749
.maxComputeWorkGroupInvocations = max_threads_per_block,
750
.maxComputeWorkGroupSize = { block_size[0], block_size[1], block_size[2] },
751
.subPixelPrecisionBits = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_RASTERIZER_SUBPIXEL_BITS),
752
.subTexelPrecisionBits = 8,
753
.mipmapPrecisionBits = 8,
754
.maxDrawIndexedIndexValue = UINT32_MAX,
755
.maxDrawIndirectCount = UINT32_MAX,
756
.maxSamplerLodBias = 16,
757
.maxSamplerAnisotropy = 16,
758
.maxViewports = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VIEWPORTS),
759
.maxViewportDimensions = { (1 << 14), (1 << 14) },
760
.viewportBoundsRange = { -32768.0, 32768.0 },
761
.viewportSubPixelBits = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VIEWPORT_SUBPIXEL_BITS),
762
.minMemoryMapAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT),
763
.minTexelBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT),
764
.minUniformBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT),
765
.minStorageBufferOffsetAlignment = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT),
766
.minTexelOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_TEXEL_OFFSET),
767
.maxTexelOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXEL_OFFSET),
768
.minTexelGatherOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET),
769
.maxTexelGatherOffset = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET),
770
.minInterpolationOffset = -2, /* FIXME */
771
.maxInterpolationOffset = 2, /* FIXME */
772
.subPixelInterpolationOffsetBits = 8, /* FIXME */
773
.maxFramebufferWidth = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
774
.maxFramebufferHeight = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE),
775
.maxFramebufferLayers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS),
776
.framebufferColorSampleCounts = sample_counts,
777
.framebufferDepthSampleCounts = sample_counts,
778
.framebufferStencilSampleCounts = sample_counts,
779
.framebufferNoAttachmentsSampleCounts = sample_counts,
780
.maxColorAttachments = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_RENDER_TARGETS),
781
.sampledImageColorSampleCounts = sample_counts,
782
.sampledImageIntegerSampleCounts = sample_counts,
783
.sampledImageDepthSampleCounts = sample_counts,
784
.sampledImageStencilSampleCounts = sample_counts,
785
.storageImageSampleCounts = sample_counts,
786
.maxSampleMaskWords = 1,
787
.timestampComputeAndGraphics = true,
788
.timestampPeriod = 1,
789
.maxClipDistances = 8,
790
.maxCullDistances = 8,
791
.maxCombinedClipAndCullDistances = 8,
792
.discreteQueuePriorities = 2,
793
.pointSizeRange = { 0.0, pdevice->pscreen->get_paramf(pdevice->pscreen, PIPE_CAPF_MAX_POINT_WIDTH) },
794
.lineWidthRange = { 1.0, pdevice->pscreen->get_paramf(pdevice->pscreen, PIPE_CAPF_MAX_LINE_WIDTH) },
795
.pointSizeGranularity = (1.0 / 8.0),
796
.lineWidthGranularity = 1.0 / 128.0,
797
.strictLines = true,
798
.standardSampleLocations = true,
799
.optimalBufferCopyOffsetAlignment = 128,
800
.optimalBufferCopyRowPitchAlignment = 128,
801
.nonCoherentAtomSize = 64,
802
};
803
804
*pProperties = (VkPhysicalDeviceProperties) {
805
.apiVersion = LVP_API_VERSION,
806
.driverVersion = 1,
807
.vendorID = VK_VENDOR_ID_MESA,
808
.deviceID = 0,
809
.deviceType = VK_PHYSICAL_DEVICE_TYPE_CPU,
810
.limits = limits,
811
.sparseProperties = {0},
812
};
813
814
strcpy(pProperties->deviceName, pdevice->pscreen->get_name(pdevice->pscreen));
815
lvp_device_get_cache_uuid(pProperties->pipelineCacheUUID);
816
817
}
818
819
extern unsigned lp_native_vector_width;
820
static void
821
lvp_get_physical_device_properties_1_1(struct lvp_physical_device *pdevice,
822
VkPhysicalDeviceVulkan11Properties *p)
823
{
824
assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);
825
826
memset(p->deviceUUID, 0, VK_UUID_SIZE);
827
memset(p->driverUUID, 0, VK_UUID_SIZE);
828
memset(p->deviceLUID, 0, VK_LUID_SIZE);
829
/* The LUID is for Windows. */
830
p->deviceLUIDValid = false;
831
p->deviceNodeMask = 0;
832
833
p->subgroupSize = lp_native_vector_width / 32;
834
p->subgroupSupportedStages = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
835
p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | VK_SUBGROUP_FEATURE_VOTE_BIT | VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | VK_SUBGROUP_FEATURE_BALLOT_BIT;
836
p->subgroupQuadOperationsInAllStages = false;
837
838
p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
839
p->maxMultiviewViewCount = 6;
840
p->maxMultiviewInstanceIndex = INT_MAX;
841
p->protectedNoFault = false;
842
p->maxPerSetDescriptors = 1024;
843
p->maxMemoryAllocationSize = (1u << 31);
844
}
845
846
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(
847
VkPhysicalDevice physicalDevice,
848
VkPhysicalDeviceProperties2 *pProperties)
849
{
850
LVP_FROM_HANDLE(lvp_physical_device, pdevice, physicalDevice);
851
lvp_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
852
853
VkPhysicalDeviceVulkan11Properties core_1_1 = {
854
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
855
};
856
lvp_get_physical_device_properties_1_1(pdevice, &core_1_1);
857
858
#define CORE_RENAMED_PROPERTY(major, minor, ext_property, core_property) \
859
memcpy(&properties->ext_property, &core_##major##_##minor.core_property, \
860
sizeof(core_##major##_##minor.core_property))
861
862
#define CORE_PROPERTY(major, minor, property) \
863
CORE_RENAMED_PROPERTY(major, minor, property, property)
864
865
vk_foreach_struct(ext, pProperties->pNext) {
866
switch (ext->sType) {
867
868
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
869
VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
870
(VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
871
properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
872
break;
873
}
874
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
875
VkPhysicalDeviceMaintenance3Properties *properties =
876
(VkPhysicalDeviceMaintenance3Properties*)ext;
877
CORE_PROPERTY(1, 1, maxPerSetDescriptors);
878
CORE_PROPERTY(1, 1, maxMemoryAllocationSize);
879
break;
880
}
881
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {
882
VkPhysicalDeviceDriverPropertiesKHR *driver_props =
883
(VkPhysicalDeviceDriverPropertiesKHR *) ext;
884
driver_props->driverID = VK_DRIVER_ID_MESA_LLVMPIPE;
885
snprintf(driver_props->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR, "llvmpipe");
886
snprintf(driver_props->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,
887
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1
888
#ifdef MESA_LLVM_VERSION_STRING
889
" (LLVM " MESA_LLVM_VERSION_STRING ")"
890
#endif
891
);
892
driver_props->conformanceVersion.major = 1;
893
driver_props->conformanceVersion.minor = 0;
894
driver_props->conformanceVersion.subminor = 0;
895
driver_props->conformanceVersion.patch = 0;;
896
break;
897
}
898
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
899
VkPhysicalDevicePointClippingProperties *properties =
900
(VkPhysicalDevicePointClippingProperties*)ext;
901
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
902
break;
903
}
904
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
905
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
906
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
907
if (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR) != 0)
908
props->maxVertexAttribDivisor = UINT32_MAX;
909
else
910
props->maxVertexAttribDivisor = 1;
911
break;
912
}
913
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
914
VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
915
(VkPhysicalDeviceTransformFeedbackPropertiesEXT*)ext;
916
properties->maxTransformFeedbackStreams = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_VERTEX_STREAMS);
917
properties->maxTransformFeedbackBuffers = pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS);
918
properties->maxTransformFeedbackBufferSize = UINT32_MAX;
919
properties->maxTransformFeedbackStreamDataSize = 512;
920
properties->maxTransformFeedbackBufferDataSize = 512;
921
properties->maxTransformFeedbackBufferDataStride = 512;
922
properties->transformFeedbackQueries = true;
923
properties->transformFeedbackStreamsLinesTriangles = false;
924
properties->transformFeedbackRasterizationStreamSelect = false;
925
properties->transformFeedbackDraw = true;
926
break;
927
}
928
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
929
VkPhysicalDeviceMultiviewProperties *properties =
930
(VkPhysicalDeviceMultiviewProperties *)ext;
931
CORE_PROPERTY(1, 1, maxMultiviewViewCount);
932
CORE_PROPERTY(1, 1, maxMultiviewInstanceIndex);
933
break;
934
}
935
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
936
VkPhysicalDeviceIDProperties *properties =
937
(VkPhysicalDeviceIDProperties *)ext;
938
CORE_PROPERTY(1, 1, deviceUUID);
939
CORE_PROPERTY(1, 1, driverUUID);
940
CORE_PROPERTY(1, 1, deviceLUID);
941
CORE_PROPERTY(1, 1, deviceLUIDValid);
942
break;
943
}
944
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
945
VkPhysicalDeviceProtectedMemoryProperties *properties =
946
(VkPhysicalDeviceProtectedMemoryProperties *)ext;
947
CORE_PROPERTY(1, 1, protectedNoFault);
948
break;
949
}
950
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {
951
VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =
952
(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;
953
properties->filterMinmaxImageComponentMapping = true;
954
properties->filterMinmaxSingleComponentFormats = true;
955
break;
956
}
957
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
958
VkPhysicalDeviceLineRasterizationPropertiesEXT *properties =
959
(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
960
properties->lineSubPixelPrecisionBits = 4;
961
break;
962
}
963
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
964
VkPhysicalDeviceSubgroupProperties *properties =
965
(VkPhysicalDeviceSubgroupProperties*)ext;
966
CORE_PROPERTY(1, 1, subgroupSize);
967
CORE_RENAMED_PROPERTY(1, 1, supportedStages,
968
subgroupSupportedStages);
969
CORE_RENAMED_PROPERTY(1, 1, supportedOperations,
970
subgroupSupportedOperations);
971
CORE_RENAMED_PROPERTY(1, 1, quadOperationsInAllStages,
972
subgroupQuadOperationsInAllStages);
973
break;
974
}
975
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
976
lvp_get_physical_device_properties_1_1(pdevice, (void *)ext);
977
break;
978
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
979
VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties =
980
(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
981
properties->maxCustomBorderColorSamplers = 32 * 1024;
982
break;
983
}
984
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
985
VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =
986
(VkPhysicalDeviceProvokingVertexPropertiesEXT*)ext;
987
properties->provokingVertexModePerPipeline = true;
988
properties->transformFeedbackPreservesTriangleFanProvokingVertex = true;
989
break;
990
}
991
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
992
VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
993
props->maxMultiDrawCount = 2048;
994
break;
995
}
996
default:
997
break;
998
}
999
}
1000
}
1001
1002
static void lvp_get_physical_device_queue_family_properties(
1003
VkQueueFamilyProperties* pQueueFamilyProperties)
1004
{
1005
*pQueueFamilyProperties = (VkQueueFamilyProperties) {
1006
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
1007
VK_QUEUE_COMPUTE_BIT |
1008
VK_QUEUE_TRANSFER_BIT,
1009
.queueCount = 1,
1010
.timestampValidBits = 64,
1011
.minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
1012
};
1013
}
1014
1015
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties(
1016
VkPhysicalDevice physicalDevice,
1017
uint32_t* pCount,
1018
VkQueueFamilyProperties* pQueueFamilyProperties)
1019
{
1020
if (pQueueFamilyProperties == NULL) {
1021
*pCount = 1;
1022
return;
1023
}
1024
1025
assert(*pCount >= 1);
1026
lvp_get_physical_device_queue_family_properties(pQueueFamilyProperties);
1027
}
1028
1029
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceQueueFamilyProperties2(
1030
VkPhysicalDevice physicalDevice,
1031
uint32_t* pCount,
1032
VkQueueFamilyProperties2 *pQueueFamilyProperties)
1033
{
1034
if (pQueueFamilyProperties == NULL) {
1035
*pCount = 1;
1036
return;
1037
}
1038
1039
assert(*pCount >= 1);
1040
lvp_get_physical_device_queue_family_properties(&pQueueFamilyProperties->queueFamilyProperties);
1041
}
1042
1043
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties(
1044
VkPhysicalDevice physicalDevice,
1045
VkPhysicalDeviceMemoryProperties* pMemoryProperties)
1046
{
1047
pMemoryProperties->memoryTypeCount = 1;
1048
pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
1049
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1050
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1051
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
1052
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1053
.heapIndex = 0,
1054
};
1055
1056
pMemoryProperties->memoryHeapCount = 1;
1057
pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
1058
.size = 2ULL*1024*1024*1024,
1059
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
1060
};
1061
}
1062
1063
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceMemoryProperties2(
1064
VkPhysicalDevice physicalDevice,
1065
VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
1066
{
1067
lvp_GetPhysicalDeviceMemoryProperties(physicalDevice,
1068
&pMemoryProperties->memoryProperties);
1069
}
1070
1071
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL lvp_GetInstanceProcAddr(
1072
VkInstance _instance,
1073
const char* pName)
1074
{
1075
LVP_FROM_HANDLE(lvp_instance, instance, _instance);
1076
return vk_instance_get_proc_addr(&instance->vk,
1077
&lvp_instance_entrypoints,
1078
pName);
1079
}
1080
1081
/* Windows will use a dll definition file to avoid build errors. */
1082
#ifdef _WIN32
1083
#undef PUBLIC
1084
#define PUBLIC
1085
#endif
1086
1087
/* The loader wants us to expose a second GetInstanceProcAddr function
1088
* to work around certain LD_PRELOAD issues seen in apps.
1089
*/
1090
PUBLIC
1091
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
1092
VkInstance instance,
1093
const char* pName);
1094
1095
PUBLIC
1096
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
1097
VkInstance instance,
1098
const char* pName)
1099
{
1100
return lvp_GetInstanceProcAddr(instance, pName);
1101
}
1102
1103
PUBLIC
1104
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
1105
VkInstance _instance,
1106
const char* pName);
1107
1108
PUBLIC
1109
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
1110
VkInstance _instance,
1111
const char* pName)
1112
{
1113
LVP_FROM_HANDLE(lvp_instance, instance, _instance);
1114
return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);
1115
}
1116
1117
static int queue_thread(void *data)
1118
{
1119
struct lvp_queue *queue = data;
1120
1121
mtx_lock(&queue->m);
1122
while (!queue->shutdown) {
1123
struct lvp_queue_work *task;
1124
while (list_is_empty(&queue->workqueue) && !queue->shutdown)
1125
cnd_wait(&queue->new_work, &queue->m);
1126
1127
if (queue->shutdown)
1128
break;
1129
1130
task = list_first_entry(&queue->workqueue, struct lvp_queue_work,
1131
list);
1132
1133
mtx_unlock(&queue->m);
1134
//execute
1135
for (unsigned i = 0; i < task->cmd_buffer_count; i++) {
1136
lvp_execute_cmds(queue->device, queue, task->cmd_buffers[i]);
1137
}
1138
1139
if (task->cmd_buffer_count) {
1140
struct pipe_fence_handle *handle = NULL;
1141
queue->ctx->flush(queue->ctx, task->fence ? &handle : NULL, 0);
1142
if (task->fence) {
1143
mtx_lock(&queue->device->fence_lock);
1144
task->fence->handle = handle;
1145
mtx_unlock(&queue->device->fence_lock);
1146
}
1147
} else if (task->fence)
1148
task->fence->signaled = true;
1149
p_atomic_dec(&queue->count);
1150
mtx_lock(&queue->m);
1151
list_del(&task->list);
1152
free(task);
1153
}
1154
mtx_unlock(&queue->m);
1155
return 0;
1156
}
1157
1158
static VkResult
1159
lvp_queue_init(struct lvp_device *device, struct lvp_queue *queue)
1160
{
1161
queue->device = device;
1162
1163
queue->flags = 0;
1164
queue->ctx = device->pscreen->context_create(device->pscreen, NULL, PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);
1165
queue->cso = cso_create_context(queue->ctx, CSO_NO_VBUF);
1166
list_inithead(&queue->workqueue);
1167
p_atomic_set(&queue->count, 0);
1168
mtx_init(&queue->m, mtx_plain);
1169
queue->exec_thread = u_thread_create(queue_thread, queue);
1170
1171
vk_object_base_init(&device->vk, &queue->base, VK_OBJECT_TYPE_QUEUE);
1172
return VK_SUCCESS;
1173
}
1174
1175
static void
1176
lvp_queue_finish(struct lvp_queue *queue)
1177
{
1178
mtx_lock(&queue->m);
1179
queue->shutdown = true;
1180
cnd_broadcast(&queue->new_work);
1181
mtx_unlock(&queue->m);
1182
1183
thrd_join(queue->exec_thread, NULL);
1184
1185
cnd_destroy(&queue->new_work);
1186
mtx_destroy(&queue->m);
1187
cso_destroy_context(queue->cso);
1188
queue->ctx->destroy(queue->ctx);
1189
}
1190
1191
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDevice(
1192
VkPhysicalDevice physicalDevice,
1193
const VkDeviceCreateInfo* pCreateInfo,
1194
const VkAllocationCallbacks* pAllocator,
1195
VkDevice* pDevice)
1196
{
1197
fprintf(stderr, "WARNING: lavapipe is not a conformant vulkan implementation, testing use only.\n");
1198
1199
LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
1200
struct lvp_device *device;
1201
struct lvp_instance *instance = (struct lvp_instance *)physical_device->vk.instance;
1202
1203
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
1204
1205
/* Check enabled features */
1206
if (pCreateInfo->pEnabledFeatures) {
1207
VkPhysicalDeviceFeatures supported_features;
1208
lvp_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
1209
VkBool32 *supported_feature = (VkBool32 *)&supported_features;
1210
VkBool32 *enabled_feature = (VkBool32 *)pCreateInfo->pEnabledFeatures;
1211
unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
1212
for (uint32_t i = 0; i < num_features; i++) {
1213
if (enabled_feature[i] && !supported_feature[i])
1214
return vk_error(instance, VK_ERROR_FEATURE_NOT_PRESENT);
1215
}
1216
}
1217
1218
device = vk_zalloc2(&physical_device->vk.instance->alloc, pAllocator,
1219
sizeof(*device), 8,
1220
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1221
if (!device)
1222
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1223
1224
struct vk_device_dispatch_table dispatch_table;
1225
vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1226
&lvp_device_entrypoints, true);
1227
VkResult result = vk_device_init(&device->vk,
1228
&physical_device->vk,
1229
&dispatch_table, pCreateInfo,
1230
pAllocator);
1231
if (result != VK_SUCCESS) {
1232
vk_free(&device->vk.alloc, device);
1233
return vk_error(instance, result);
1234
}
1235
1236
device->instance = (struct lvp_instance *)physical_device->vk.instance;
1237
device->physical_device = physical_device;
1238
1239
mtx_init(&device->fence_lock, mtx_plain);
1240
device->pscreen = physical_device->pscreen;
1241
1242
lvp_queue_init(device, &device->queue);
1243
1244
*pDevice = lvp_device_to_handle(device);
1245
1246
return VK_SUCCESS;
1247
1248
}
1249
1250
VKAPI_ATTR void VKAPI_CALL lvp_DestroyDevice(
1251
VkDevice _device,
1252
const VkAllocationCallbacks* pAllocator)
1253
{
1254
LVP_FROM_HANDLE(lvp_device, device, _device);
1255
1256
lvp_queue_finish(&device->queue);
1257
vk_device_finish(&device->vk);
1258
vk_free(&device->vk.alloc, device);
1259
}
1260
1261
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceExtensionProperties(
1262
const char* pLayerName,
1263
uint32_t* pPropertyCount,
1264
VkExtensionProperties* pProperties)
1265
{
1266
if (pLayerName)
1267
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1268
1269
return vk_enumerate_instance_extension_properties(
1270
&lvp_instance_extensions_supported, pPropertyCount, pProperties);
1271
}
1272
1273
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateInstanceLayerProperties(
1274
uint32_t* pPropertyCount,
1275
VkLayerProperties* pProperties)
1276
{
1277
if (pProperties == NULL) {
1278
*pPropertyCount = 0;
1279
return VK_SUCCESS;
1280
}
1281
1282
/* None supported at this time */
1283
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1284
}
1285
1286
VKAPI_ATTR VkResult VKAPI_CALL lvp_EnumerateDeviceLayerProperties(
1287
VkPhysicalDevice physicalDevice,
1288
uint32_t* pPropertyCount,
1289
VkLayerProperties* pProperties)
1290
{
1291
if (pProperties == NULL) {
1292
*pPropertyCount = 0;
1293
return VK_SUCCESS;
1294
}
1295
1296
/* None supported at this time */
1297
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
1298
}
1299
1300
VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceQueue2(
1301
VkDevice _device,
1302
const VkDeviceQueueInfo2* pQueueInfo,
1303
VkQueue* pQueue)
1304
{
1305
LVP_FROM_HANDLE(lvp_device, device, _device);
1306
struct lvp_queue *queue;
1307
1308
queue = &device->queue;
1309
if (pQueueInfo->flags != queue->flags) {
1310
/* From the Vulkan 1.1.70 spec:
1311
*
1312
* "The queue returned by vkGetDeviceQueue2 must have the same
1313
* flags value from this structure as that used at device
1314
* creation time in a VkDeviceQueueCreateInfo instance. If no
1315
* matching flags were specified at device creation time then
1316
* pQueue will return VK_NULL_HANDLE."
1317
*/
1318
*pQueue = VK_NULL_HANDLE;
1319
return;
1320
}
1321
1322
*pQueue = lvp_queue_to_handle(queue);
1323
}
1324
1325
1326
VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceQueue(
1327
VkDevice _device,
1328
uint32_t queueFamilyIndex,
1329
uint32_t queueIndex,
1330
VkQueue* pQueue)
1331
{
1332
const VkDeviceQueueInfo2 info = (VkDeviceQueueInfo2) {
1333
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
1334
.queueFamilyIndex = queueFamilyIndex,
1335
.queueIndex = queueIndex
1336
};
1337
1338
lvp_GetDeviceQueue2(_device, &info, pQueue);
1339
}
1340
1341
1342
VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueSubmit(
1343
VkQueue _queue,
1344
uint32_t submitCount,
1345
const VkSubmitInfo* pSubmits,
1346
VkFence _fence)
1347
{
1348
LVP_FROM_HANDLE(lvp_queue, queue, _queue);
1349
LVP_FROM_HANDLE(lvp_fence, fence, _fence);
1350
1351
if (submitCount == 0)
1352
goto just_signal_fence;
1353
for (uint32_t i = 0; i < submitCount; i++) {
1354
uint32_t task_size = sizeof(struct lvp_queue_work) + pSubmits[i].commandBufferCount * sizeof(struct lvp_cmd_buffer *);
1355
struct lvp_queue_work *task = malloc(task_size);
1356
1357
task->cmd_buffer_count = pSubmits[i].commandBufferCount;
1358
task->fence = fence;
1359
task->cmd_buffers = (struct lvp_cmd_buffer **)(task + 1);
1360
for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {
1361
task->cmd_buffers[j] = lvp_cmd_buffer_from_handle(pSubmits[i].pCommandBuffers[j]);
1362
}
1363
1364
mtx_lock(&queue->m);
1365
p_atomic_inc(&queue->count);
1366
list_addtail(&task->list, &queue->workqueue);
1367
cnd_signal(&queue->new_work);
1368
mtx_unlock(&queue->m);
1369
}
1370
return VK_SUCCESS;
1371
just_signal_fence:
1372
fence->signaled = true;
1373
return VK_SUCCESS;
1374
}
1375
1376
static VkResult queue_wait_idle(struct lvp_queue *queue, uint64_t timeout)
1377
{
1378
if (timeout == 0)
1379
return p_atomic_read(&queue->count) == 0 ? VK_SUCCESS : VK_TIMEOUT;
1380
if (timeout == UINT64_MAX)
1381
while (p_atomic_read(&queue->count))
1382
os_time_sleep(100);
1383
else {
1384
int64_t atime = os_time_get_absolute_timeout(timeout);
1385
if (!os_wait_until_zero_abs_timeout(&queue->count, atime))
1386
return VK_TIMEOUT;
1387
}
1388
return VK_SUCCESS;
1389
}
1390
1391
VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueWaitIdle(
1392
VkQueue _queue)
1393
{
1394
LVP_FROM_HANDLE(lvp_queue, queue, _queue);
1395
1396
return queue_wait_idle(queue, UINT64_MAX);
1397
}
1398
1399
VKAPI_ATTR VkResult VKAPI_CALL lvp_DeviceWaitIdle(
1400
VkDevice _device)
1401
{
1402
LVP_FROM_HANDLE(lvp_device, device, _device);
1403
1404
return queue_wait_idle(&device->queue, UINT64_MAX);
1405
}
1406
1407
VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateMemory(
1408
VkDevice _device,
1409
const VkMemoryAllocateInfo* pAllocateInfo,
1410
const VkAllocationCallbacks* pAllocator,
1411
VkDeviceMemory* pMem)
1412
{
1413
LVP_FROM_HANDLE(lvp_device, device, _device);
1414
struct lvp_device_memory *mem;
1415
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1416
1417
if (pAllocateInfo->allocationSize == 0) {
1418
/* Apparently, this is allowed */
1419
*pMem = VK_NULL_HANDLE;
1420
return VK_SUCCESS;
1421
}
1422
1423
mem = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
1424
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1425
if (mem == NULL)
1426
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1427
1428
vk_object_base_init(&device->vk, &mem->base,
1429
VK_OBJECT_TYPE_DEVICE_MEMORY);
1430
mem->pmem = device->pscreen->allocate_memory(device->pscreen, pAllocateInfo->allocationSize);
1431
if (!mem->pmem) {
1432
vk_free2(&device->vk.alloc, pAllocator, mem);
1433
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1434
}
1435
1436
mem->type_index = pAllocateInfo->memoryTypeIndex;
1437
1438
*pMem = lvp_device_memory_to_handle(mem);
1439
1440
return VK_SUCCESS;
1441
}
1442
1443
VKAPI_ATTR void VKAPI_CALL lvp_FreeMemory(
1444
VkDevice _device,
1445
VkDeviceMemory _mem,
1446
const VkAllocationCallbacks* pAllocator)
1447
{
1448
LVP_FROM_HANDLE(lvp_device, device, _device);
1449
LVP_FROM_HANDLE(lvp_device_memory, mem, _mem);
1450
1451
if (mem == NULL)
1452
return;
1453
1454
device->pscreen->free_memory(device->pscreen, mem->pmem);
1455
vk_object_base_finish(&mem->base);
1456
vk_free2(&device->vk.alloc, pAllocator, mem);
1457
1458
}
1459
1460
VKAPI_ATTR VkResult VKAPI_CALL lvp_MapMemory(
1461
VkDevice _device,
1462
VkDeviceMemory _memory,
1463
VkDeviceSize offset,
1464
VkDeviceSize size,
1465
VkMemoryMapFlags flags,
1466
void** ppData)
1467
{
1468
LVP_FROM_HANDLE(lvp_device, device, _device);
1469
LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);
1470
void *map;
1471
if (mem == NULL) {
1472
*ppData = NULL;
1473
return VK_SUCCESS;
1474
}
1475
1476
map = device->pscreen->map_memory(device->pscreen, mem->pmem);
1477
1478
*ppData = (char *)map + offset;
1479
return VK_SUCCESS;
1480
}
1481
1482
VKAPI_ATTR void VKAPI_CALL lvp_UnmapMemory(
1483
VkDevice _device,
1484
VkDeviceMemory _memory)
1485
{
1486
LVP_FROM_HANDLE(lvp_device, device, _device);
1487
LVP_FROM_HANDLE(lvp_device_memory, mem, _memory);
1488
1489
if (mem == NULL)
1490
return;
1491
1492
device->pscreen->unmap_memory(device->pscreen, mem->pmem);
1493
}
1494
1495
VKAPI_ATTR VkResult VKAPI_CALL lvp_FlushMappedMemoryRanges(
1496
VkDevice _device,
1497
uint32_t memoryRangeCount,
1498
const VkMappedMemoryRange* pMemoryRanges)
1499
{
1500
return VK_SUCCESS;
1501
}
1502
1503
VKAPI_ATTR VkResult VKAPI_CALL lvp_InvalidateMappedMemoryRanges(
1504
VkDevice _device,
1505
uint32_t memoryRangeCount,
1506
const VkMappedMemoryRange* pMemoryRanges)
1507
{
1508
return VK_SUCCESS;
1509
}
1510
1511
VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements(
1512
VkDevice device,
1513
VkBuffer _buffer,
1514
VkMemoryRequirements* pMemoryRequirements)
1515
{
1516
LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer);
1517
1518
/* The Vulkan spec (git aaed022) says:
1519
*
1520
* memoryTypeBits is a bitfield and contains one bit set for every
1521
* supported memory type for the resource. The bit `1<<i` is set if and
1522
* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1523
* structure for the physical device is supported.
1524
*
1525
* We support exactly one memory type.
1526
*/
1527
pMemoryRequirements->memoryTypeBits = 1;
1528
1529
pMemoryRequirements->size = buffer->total_size;
1530
pMemoryRequirements->alignment = 64;
1531
}
1532
1533
VKAPI_ATTR void VKAPI_CALL lvp_GetBufferMemoryRequirements2(
1534
VkDevice device,
1535
const VkBufferMemoryRequirementsInfo2 *pInfo,
1536
VkMemoryRequirements2 *pMemoryRequirements)
1537
{
1538
lvp_GetBufferMemoryRequirements(device, pInfo->buffer,
1539
&pMemoryRequirements->memoryRequirements);
1540
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
1541
switch (ext->sType) {
1542
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
1543
VkMemoryDedicatedRequirements *req =
1544
(VkMemoryDedicatedRequirements *) ext;
1545
req->requiresDedicatedAllocation = false;
1546
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
1547
break;
1548
}
1549
default:
1550
break;
1551
}
1552
}
1553
}
1554
1555
VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements(
1556
VkDevice device,
1557
VkImage _image,
1558
VkMemoryRequirements* pMemoryRequirements)
1559
{
1560
LVP_FROM_HANDLE(lvp_image, image, _image);
1561
pMemoryRequirements->memoryTypeBits = 1;
1562
1563
pMemoryRequirements->size = image->size;
1564
pMemoryRequirements->alignment = image->alignment;
1565
}
1566
1567
VKAPI_ATTR void VKAPI_CALL lvp_GetImageMemoryRequirements2(
1568
VkDevice device,
1569
const VkImageMemoryRequirementsInfo2 *pInfo,
1570
VkMemoryRequirements2 *pMemoryRequirements)
1571
{
1572
lvp_GetImageMemoryRequirements(device, pInfo->image,
1573
&pMemoryRequirements->memoryRequirements);
1574
1575
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
1576
switch (ext->sType) {
1577
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
1578
VkMemoryDedicatedRequirements *req =
1579
(VkMemoryDedicatedRequirements *) ext;
1580
req->requiresDedicatedAllocation = false;
1581
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
1582
break;
1583
}
1584
default:
1585
break;
1586
}
1587
}
1588
}
1589
1590
VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements(
1591
VkDevice device,
1592
VkImage image,
1593
uint32_t* pSparseMemoryRequirementCount,
1594
VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
1595
{
1596
stub();
1597
}
1598
1599
VKAPI_ATTR void VKAPI_CALL lvp_GetImageSparseMemoryRequirements2(
1600
VkDevice device,
1601
const VkImageSparseMemoryRequirementsInfo2* pInfo,
1602
uint32_t* pSparseMemoryRequirementCount,
1603
VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
1604
{
1605
stub();
1606
}
1607
1608
VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceMemoryCommitment(
1609
VkDevice device,
1610
VkDeviceMemory memory,
1611
VkDeviceSize* pCommittedMemoryInBytes)
1612
{
1613
*pCommittedMemoryInBytes = 0;
1614
}
1615
1616
VKAPI_ATTR VkResult VKAPI_CALL lvp_BindBufferMemory2(VkDevice _device,
1617
uint32_t bindInfoCount,
1618
const VkBindBufferMemoryInfo *pBindInfos)
1619
{
1620
LVP_FROM_HANDLE(lvp_device, device, _device);
1621
for (uint32_t i = 0; i < bindInfoCount; ++i) {
1622
LVP_FROM_HANDLE(lvp_device_memory, mem, pBindInfos[i].memory);
1623
LVP_FROM_HANDLE(lvp_buffer, buffer, pBindInfos[i].buffer);
1624
1625
buffer->pmem = mem->pmem;
1626
device->pscreen->resource_bind_backing(device->pscreen,
1627
buffer->bo,
1628
mem->pmem,
1629
pBindInfos[i].memoryOffset);
1630
}
1631
return VK_SUCCESS;
1632
}
1633
1634
VKAPI_ATTR VkResult VKAPI_CALL lvp_BindImageMemory2(VkDevice _device,
1635
uint32_t bindInfoCount,
1636
const VkBindImageMemoryInfo *pBindInfos)
1637
{
1638
LVP_FROM_HANDLE(lvp_device, device, _device);
1639
for (uint32_t i = 0; i < bindInfoCount; ++i) {
1640
const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
1641
LVP_FROM_HANDLE(lvp_device_memory, mem, bind_info->memory);
1642
LVP_FROM_HANDLE(lvp_image, image, bind_info->image);
1643
bool did_bind = false;
1644
1645
vk_foreach_struct_const(s, bind_info->pNext) {
1646
switch (s->sType) {
1647
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
1648
const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
1649
(const VkBindImageMemorySwapchainInfoKHR *) s;
1650
struct lvp_image *swapchain_image =
1651
lvp_swapchain_get_image(swapchain_info->swapchain,
1652
swapchain_info->imageIndex);
1653
1654
image->pmem = swapchain_image->pmem;
1655
image->memory_offset = swapchain_image->memory_offset;
1656
device->pscreen->resource_bind_backing(device->pscreen,
1657
image->bo,
1658
image->pmem,
1659
image->memory_offset);
1660
did_bind = true;
1661
}
1662
default:
1663
break;
1664
}
1665
}
1666
1667
if (!did_bind) {
1668
if (!device->pscreen->resource_bind_backing(device->pscreen,
1669
image->bo,
1670
mem->pmem,
1671
bind_info->memoryOffset)) {
1672
/* This is probably caused by the texture being too large, so let's
1673
* report this as the *closest* allowed error-code. It's not ideal,
1674
* but it's unlikely that anyone will care too much.
1675
*/
1676
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
1677
}
1678
image->pmem = mem->pmem;
1679
image->memory_offset = bind_info->memoryOffset;
1680
}
1681
}
1682
return VK_SUCCESS;
1683
}
1684
1685
VKAPI_ATTR VkResult VKAPI_CALL lvp_QueueBindSparse(
1686
VkQueue queue,
1687
uint32_t bindInfoCount,
1688
const VkBindSparseInfo* pBindInfo,
1689
VkFence fence)
1690
{
1691
stub_return(VK_ERROR_INCOMPATIBLE_DRIVER);
1692
}
1693
1694
1695
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateFence(
1696
VkDevice _device,
1697
const VkFenceCreateInfo* pCreateInfo,
1698
const VkAllocationCallbacks* pAllocator,
1699
VkFence* pFence)
1700
{
1701
LVP_FROM_HANDLE(lvp_device, device, _device);
1702
struct lvp_fence *fence;
1703
1704
fence = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*fence), 8,
1705
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1706
if (fence == NULL)
1707
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1708
1709
vk_object_base_init(&device->vk, &fence->base, VK_OBJECT_TYPE_FENCE);
1710
fence->signaled = pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT;
1711
1712
fence->handle = NULL;
1713
*pFence = lvp_fence_to_handle(fence);
1714
1715
return VK_SUCCESS;
1716
}
1717
1718
VKAPI_ATTR void VKAPI_CALL lvp_DestroyFence(
1719
VkDevice _device,
1720
VkFence _fence,
1721
const VkAllocationCallbacks* pAllocator)
1722
{
1723
LVP_FROM_HANDLE(lvp_device, device, _device);
1724
LVP_FROM_HANDLE(lvp_fence, fence, _fence);
1725
1726
if (!_fence)
1727
return;
1728
if (fence->handle)
1729
device->pscreen->fence_reference(device->pscreen, &fence->handle, NULL);
1730
1731
vk_object_base_finish(&fence->base);
1732
vk_free2(&device->vk.alloc, pAllocator, fence);
1733
}
1734
1735
VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetFences(
1736
VkDevice _device,
1737
uint32_t fenceCount,
1738
const VkFence* pFences)
1739
{
1740
LVP_FROM_HANDLE(lvp_device, device, _device);
1741
for (unsigned i = 0; i < fenceCount; i++) {
1742
struct lvp_fence *fence = lvp_fence_from_handle(pFences[i]);
1743
1744
fence->signaled = false;
1745
1746
mtx_lock(&device->fence_lock);
1747
if (fence->handle)
1748
device->pscreen->fence_reference(device->pscreen, &fence->handle, NULL);
1749
mtx_unlock(&device->fence_lock);
1750
}
1751
return VK_SUCCESS;
1752
}
1753
1754
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetFenceStatus(
1755
VkDevice _device,
1756
VkFence _fence)
1757
{
1758
LVP_FROM_HANDLE(lvp_device, device, _device);
1759
LVP_FROM_HANDLE(lvp_fence, fence, _fence);
1760
1761
if (fence->signaled)
1762
return VK_SUCCESS;
1763
1764
mtx_lock(&device->fence_lock);
1765
1766
if (!fence->handle) {
1767
mtx_unlock(&device->fence_lock);
1768
return VK_NOT_READY;
1769
}
1770
1771
bool signalled = device->pscreen->fence_finish(device->pscreen,
1772
NULL,
1773
fence->handle,
1774
0);
1775
mtx_unlock(&device->fence_lock);
1776
if (signalled)
1777
return VK_SUCCESS;
1778
else
1779
return VK_NOT_READY;
1780
}
1781
1782
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateFramebuffer(
1783
VkDevice _device,
1784
const VkFramebufferCreateInfo* pCreateInfo,
1785
const VkAllocationCallbacks* pAllocator,
1786
VkFramebuffer* pFramebuffer)
1787
{
1788
LVP_FROM_HANDLE(lvp_device, device, _device);
1789
struct lvp_framebuffer *framebuffer;
1790
const VkFramebufferAttachmentsCreateInfo *imageless_create_info =
1791
vk_find_struct_const(pCreateInfo->pNext,
1792
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
1793
1794
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
1795
1796
size_t size = sizeof(*framebuffer);
1797
1798
if (!imageless_create_info)
1799
size += sizeof(struct lvp_image_view *) * pCreateInfo->attachmentCount;
1800
framebuffer = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
1801
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1802
if (framebuffer == NULL)
1803
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1804
1805
vk_object_base_init(&device->vk, &framebuffer->base,
1806
VK_OBJECT_TYPE_FRAMEBUFFER);
1807
1808
if (!imageless_create_info) {
1809
framebuffer->attachment_count = pCreateInfo->attachmentCount;
1810
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
1811
VkImageView _iview = pCreateInfo->pAttachments[i];
1812
framebuffer->attachments[i] = lvp_image_view_from_handle(_iview);
1813
}
1814
}
1815
1816
framebuffer->width = pCreateInfo->width;
1817
framebuffer->height = pCreateInfo->height;
1818
framebuffer->layers = pCreateInfo->layers;
1819
framebuffer->imageless = !!imageless_create_info;
1820
1821
*pFramebuffer = lvp_framebuffer_to_handle(framebuffer);
1822
1823
return VK_SUCCESS;
1824
}
1825
1826
VKAPI_ATTR void VKAPI_CALL lvp_DestroyFramebuffer(
1827
VkDevice _device,
1828
VkFramebuffer _fb,
1829
const VkAllocationCallbacks* pAllocator)
1830
{
1831
LVP_FROM_HANDLE(lvp_device, device, _device);
1832
LVP_FROM_HANDLE(lvp_framebuffer, fb, _fb);
1833
1834
if (!fb)
1835
return;
1836
vk_object_base_finish(&fb->base);
1837
vk_free2(&device->vk.alloc, pAllocator, fb);
1838
}
1839
1840
VKAPI_ATTR VkResult VKAPI_CALL lvp_WaitForFences(
1841
VkDevice _device,
1842
uint32_t fenceCount,
1843
const VkFence* pFences,
1844
VkBool32 waitAll,
1845
uint64_t timeout)
1846
{
1847
LVP_FROM_HANDLE(lvp_device, device, _device);
1848
1849
VkResult qret = queue_wait_idle(&device->queue, timeout);
1850
bool timeout_status = false;
1851
if (qret == VK_TIMEOUT)
1852
return VK_TIMEOUT;
1853
1854
mtx_lock(&device->fence_lock);
1855
for (unsigned i = 0; i < fenceCount; i++) {
1856
struct lvp_fence *fence = lvp_fence_from_handle(pFences[i]);
1857
1858
if (fence->signaled)
1859
continue;
1860
if (!fence->handle) {
1861
timeout_status |= true;
1862
continue;
1863
}
1864
bool ret = device->pscreen->fence_finish(device->pscreen,
1865
NULL,
1866
fence->handle,
1867
timeout);
1868
if (ret && !waitAll) {
1869
timeout_status = false;
1870
break;
1871
}
1872
1873
if (!ret)
1874
timeout_status |= true;
1875
}
1876
mtx_unlock(&device->fence_lock);
1877
return timeout_status ? VK_TIMEOUT : VK_SUCCESS;
1878
}
1879
1880
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSemaphore(
1881
VkDevice _device,
1882
const VkSemaphoreCreateInfo* pCreateInfo,
1883
const VkAllocationCallbacks* pAllocator,
1884
VkSemaphore* pSemaphore)
1885
{
1886
LVP_FROM_HANDLE(lvp_device, device, _device);
1887
1888
struct lvp_semaphore *sema = vk_alloc2(&device->vk.alloc, pAllocator,
1889
sizeof(*sema), 8,
1890
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1891
1892
if (!sema)
1893
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1894
vk_object_base_init(&device->vk, &sema->base,
1895
VK_OBJECT_TYPE_SEMAPHORE);
1896
*pSemaphore = lvp_semaphore_to_handle(sema);
1897
1898
return VK_SUCCESS;
1899
}
1900
1901
VKAPI_ATTR void VKAPI_CALL lvp_DestroySemaphore(
1902
VkDevice _device,
1903
VkSemaphore _semaphore,
1904
const VkAllocationCallbacks* pAllocator)
1905
{
1906
LVP_FROM_HANDLE(lvp_device, device, _device);
1907
LVP_FROM_HANDLE(lvp_semaphore, semaphore, _semaphore);
1908
1909
if (!_semaphore)
1910
return;
1911
vk_object_base_finish(&semaphore->base);
1912
vk_free2(&device->vk.alloc, pAllocator, semaphore);
1913
}
1914
1915
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateEvent(
1916
VkDevice _device,
1917
const VkEventCreateInfo* pCreateInfo,
1918
const VkAllocationCallbacks* pAllocator,
1919
VkEvent* pEvent)
1920
{
1921
LVP_FROM_HANDLE(lvp_device, device, _device);
1922
struct lvp_event *event = vk_alloc2(&device->vk.alloc, pAllocator,
1923
sizeof(*event), 8,
1924
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1925
1926
if (!event)
1927
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1928
1929
vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);
1930
*pEvent = lvp_event_to_handle(event);
1931
event->event_storage = 0;
1932
1933
return VK_SUCCESS;
1934
}
1935
1936
VKAPI_ATTR void VKAPI_CALL lvp_DestroyEvent(
1937
VkDevice _device,
1938
VkEvent _event,
1939
const VkAllocationCallbacks* pAllocator)
1940
{
1941
LVP_FROM_HANDLE(lvp_device, device, _device);
1942
LVP_FROM_HANDLE(lvp_event, event, _event);
1943
1944
if (!event)
1945
return;
1946
1947
vk_object_base_finish(&event->base);
1948
vk_free2(&device->vk.alloc, pAllocator, event);
1949
}
1950
1951
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetEventStatus(
1952
VkDevice _device,
1953
VkEvent _event)
1954
{
1955
LVP_FROM_HANDLE(lvp_event, event, _event);
1956
if (event->event_storage == 1)
1957
return VK_EVENT_SET;
1958
return VK_EVENT_RESET;
1959
}
1960
1961
VKAPI_ATTR VkResult VKAPI_CALL lvp_SetEvent(
1962
VkDevice _device,
1963
VkEvent _event)
1964
{
1965
LVP_FROM_HANDLE(lvp_event, event, _event);
1966
event->event_storage = 1;
1967
1968
return VK_SUCCESS;
1969
}
1970
1971
VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetEvent(
1972
VkDevice _device,
1973
VkEvent _event)
1974
{
1975
LVP_FROM_HANDLE(lvp_event, event, _event);
1976
event->event_storage = 0;
1977
1978
return VK_SUCCESS;
1979
}
1980
1981
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSampler(
1982
VkDevice _device,
1983
const VkSamplerCreateInfo* pCreateInfo,
1984
const VkAllocationCallbacks* pAllocator,
1985
VkSampler* pSampler)
1986
{
1987
LVP_FROM_HANDLE(lvp_device, device, _device);
1988
struct lvp_sampler *sampler;
1989
const VkSamplerReductionModeCreateInfo *reduction_mode_create_info =
1990
vk_find_struct_const(pCreateInfo->pNext,
1991
SAMPLER_REDUCTION_MODE_CREATE_INFO);
1992
const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color_create_info =
1993
vk_find_struct_const(pCreateInfo->pNext,
1994
SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
1995
1996
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1997
1998
sampler = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*sampler), 8,
1999
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2000
if (!sampler)
2001
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
2002
2003
vk_object_base_init(&device->vk, &sampler->base,
2004
VK_OBJECT_TYPE_SAMPLER);
2005
sampler->create_info = *pCreateInfo;
2006
2007
switch (pCreateInfo->borderColor) {
2008
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
2009
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
2010
default:
2011
memset(&sampler->border_color, 0, sizeof(union pipe_color_union));
2012
break;
2013
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
2014
sampler->border_color.f[0] = sampler->border_color.f[1] =
2015
sampler->border_color.f[2] = 0.0f;
2016
sampler->border_color.f[3] = 1.0f;
2017
break;
2018
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
2019
sampler->border_color.i[0] = sampler->border_color.i[1] =
2020
sampler->border_color.i[2] = 0;
2021
sampler->border_color.i[3] = 1;
2022
break;
2023
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
2024
sampler->border_color.f[0] = sampler->border_color.f[1] =
2025
sampler->border_color.f[2] = 1.0f;
2026
sampler->border_color.f[3] = 1.0f;
2027
break;
2028
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
2029
sampler->border_color.i[0] = sampler->border_color.i[1] =
2030
sampler->border_color.i[2] = 1;
2031
sampler->border_color.i[3] = 1;
2032
break;
2033
case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
2034
case VK_BORDER_COLOR_INT_CUSTOM_EXT:
2035
assert(custom_border_color_create_info != NULL);
2036
memcpy(&sampler->border_color,
2037
&custom_border_color_create_info->customBorderColor,
2038
sizeof(union pipe_color_union));
2039
break;
2040
}
2041
2042
sampler->reduction_mode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
2043
if (reduction_mode_create_info)
2044
sampler->reduction_mode = reduction_mode_create_info->reductionMode;
2045
2046
*pSampler = lvp_sampler_to_handle(sampler);
2047
2048
return VK_SUCCESS;
2049
}
2050
2051
VKAPI_ATTR void VKAPI_CALL lvp_DestroySampler(
2052
VkDevice _device,
2053
VkSampler _sampler,
2054
const VkAllocationCallbacks* pAllocator)
2055
{
2056
LVP_FROM_HANDLE(lvp_device, device, _device);
2057
LVP_FROM_HANDLE(lvp_sampler, sampler, _sampler);
2058
2059
if (!_sampler)
2060
return;
2061
vk_object_base_finish(&sampler->base);
2062
vk_free2(&device->vk.alloc, pAllocator, sampler);
2063
}
2064
2065
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateSamplerYcbcrConversionKHR(
2066
VkDevice device,
2067
const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
2068
const VkAllocationCallbacks* pAllocator,
2069
VkSamplerYcbcrConversion* pYcbcrConversion)
2070
{
2071
return VK_ERROR_OUT_OF_HOST_MEMORY;
2072
}
2073
2074
VKAPI_ATTR void VKAPI_CALL lvp_DestroySamplerYcbcrConversionKHR(
2075
VkDevice device,
2076
VkSamplerYcbcrConversion ycbcrConversion,
2077
const VkAllocationCallbacks* pAllocator)
2078
{
2079
}
2080
2081
/* vk_icd.h does not declare this function, so we declare it here to
2082
* suppress Wmissing-prototypes.
2083
*/
2084
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2085
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
2086
2087
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
2088
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
2089
{
2090
/* For the full details on loader interface versioning, see
2091
* <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
2092
* What follows is a condensed summary, to help you navigate the large and
2093
* confusing official doc.
2094
*
2095
* - Loader interface v0 is incompatible with later versions. We don't
2096
* support it.
2097
*
2098
* - In loader interface v1:
2099
* - The first ICD entrypoint called by the loader is
2100
* vk_icdGetInstanceProcAddr(). The ICD must statically expose this
2101
* entrypoint.
2102
* - The ICD must statically expose no other Vulkan symbol unless it is
2103
* linked with -Bsymbolic.
2104
* - Each dispatchable Vulkan handle created by the ICD must be
2105
* a pointer to a struct whose first member is VK_LOADER_DATA. The
2106
* ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.
2107
* - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
2108
* vkDestroySurfaceKHR(). The ICD must be capable of working with
2109
* such loader-managed surfaces.
2110
*
2111
* - Loader interface v2 differs from v1 in:
2112
* - The first ICD entrypoint called by the loader is
2113
* vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
2114
* statically expose this entrypoint.
2115
*
2116
* - Loader interface v3 differs from v2 in:
2117
* - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
2118
* vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
2119
* because the loader no longer does so.
2120
*
2121
* - Loader interface v4 differs from v3 in:
2122
* - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().
2123
*/
2124
*pSupportedVersion = MIN2(*pSupportedVersion, 4u);
2125
return VK_SUCCESS;
2126
}
2127
2128
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePrivateDataSlotEXT(
2129
VkDevice _device,
2130
const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
2131
const VkAllocationCallbacks* pAllocator,
2132
VkPrivateDataSlotEXT* pPrivateDataSlot)
2133
{
2134
LVP_FROM_HANDLE(lvp_device, device, _device);
2135
return vk_private_data_slot_create(&device->vk, pCreateInfo, pAllocator,
2136
pPrivateDataSlot);
2137
}
2138
2139
VKAPI_ATTR void VKAPI_CALL lvp_DestroyPrivateDataSlotEXT(
2140
VkDevice _device,
2141
VkPrivateDataSlotEXT privateDataSlot,
2142
const VkAllocationCallbacks* pAllocator)
2143
{
2144
LVP_FROM_HANDLE(lvp_device, device, _device);
2145
vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);
2146
}
2147
2148
VKAPI_ATTR VkResult VKAPI_CALL lvp_SetPrivateDataEXT(
2149
VkDevice _device,
2150
VkObjectType objectType,
2151
uint64_t objectHandle,
2152
VkPrivateDataSlotEXT privateDataSlot,
2153
uint64_t data)
2154
{
2155
LVP_FROM_HANDLE(lvp_device, device, _device);
2156
return vk_object_base_set_private_data(&device->vk, objectType,
2157
objectHandle, privateDataSlot,
2158
data);
2159
}
2160
2161
VKAPI_ATTR void VKAPI_CALL lvp_GetPrivateDataEXT(
2162
VkDevice _device,
2163
VkObjectType objectType,
2164
uint64_t objectHandle,
2165
VkPrivateDataSlotEXT privateDataSlot,
2166
uint64_t* pData)
2167
{
2168
LVP_FROM_HANDLE(lvp_device, device, _device);
2169
vk_object_base_get_private_data(&device->vk, objectType, objectHandle,
2170
privateDataSlot, pData);
2171
}
2172
2173
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalFenceProperties(
2174
VkPhysicalDevice physicalDevice,
2175
const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
2176
VkExternalFenceProperties *pExternalFenceProperties)
2177
{
2178
pExternalFenceProperties->exportFromImportedHandleTypes = 0;
2179
pExternalFenceProperties->compatibleHandleTypes = 0;
2180
pExternalFenceProperties->externalFenceFeatures = 0;
2181
}
2182
2183
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalSemaphoreProperties(
2184
VkPhysicalDevice physicalDevice,
2185
const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
2186
VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
2187
{
2188
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
2189
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
2190
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
2191
}
2192
2193
static const VkTimeDomainEXT lvp_time_domains[] = {
2194
VK_TIME_DOMAIN_DEVICE_EXT,
2195
VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
2196
};
2197
2198
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
2199
VkPhysicalDevice physicalDevice,
2200
uint32_t *pTimeDomainCount,
2201
VkTimeDomainEXT *pTimeDomains)
2202
{
2203
int d;
2204
VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains,
2205
pTimeDomainCount);
2206
2207
for (d = 0; d < ARRAY_SIZE(lvp_time_domains); d++) {
2208
vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {
2209
*i = lvp_time_domains[d];
2210
}
2211
}
2212
2213
return vk_outarray_status(&out);
2214
}
2215
2216
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetCalibratedTimestampsEXT(
2217
VkDevice device,
2218
uint32_t timestampCount,
2219
const VkCalibratedTimestampInfoEXT *pTimestampInfos,
2220
uint64_t *pTimestamps,
2221
uint64_t *pMaxDeviation)
2222
{
2223
*pMaxDeviation = 1;
2224
2225
uint64_t now = os_time_get_nano();
2226
for (unsigned i = 0; i < timestampCount; i++) {
2227
pTimestamps[i] = now;
2228
}
2229
return VK_SUCCESS;
2230
}
2231
2232
VKAPI_ATTR void VKAPI_CALL lvp_GetDeviceGroupPeerMemoryFeaturesKHR(
2233
VkDevice device,
2234
uint32_t heapIndex,
2235
uint32_t localDeviceIndex,
2236
uint32_t remoteDeviceIndex,
2237
VkPeerMemoryFeatureFlags *pPeerMemoryFeatures)
2238
{
2239
*pPeerMemoryFeatures = 0;
2240
}
2241
2242