1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "dzn_private.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "vk_alloc.h" 27bf215546Sopenharmony_ci#include "vk_common_entrypoints.h" 28bf215546Sopenharmony_ci#include "vk_cmd_enqueue_entrypoints.h" 29bf215546Sopenharmony_ci#include "vk_debug_report.h" 30bf215546Sopenharmony_ci#include "vk_format.h" 31bf215546Sopenharmony_ci#include "vk_sync_dummy.h" 32bf215546Sopenharmony_ci#include "vk_util.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "git_sha1.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "util/debug.h" 37bf215546Sopenharmony_ci#include "util/disk_cache.h" 38bf215546Sopenharmony_ci#include "util/macros.h" 39bf215546Sopenharmony_ci#include "util/mesa-sha1.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include "glsl_types.h" 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "dxil_validator.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "git_sha1.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci#include <string.h> 48bf215546Sopenharmony_ci#include <stdio.h> 49bf215546Sopenharmony_ci#include <stdlib.h> 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci#ifdef _WIN32 52bf215546Sopenharmony_ci#include <windows.h> 53bf215546Sopenharmony_ci#include <shlobj.h> 54bf215546Sopenharmony_ci#include "dzn_dxgi.h" 55bf215546Sopenharmony_ci#endif 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci#include <directx/d3d12sdklayers.h> 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci#if defined(VK_USE_PLATFORM_WIN32_KHR) || \ 60bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_WAYLAND_KHR) || \ 61bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_XCB_KHR) || \ 62bf215546Sopenharmony_ci defined(VK_USE_PLATFORM_XLIB_KHR) 63bf215546Sopenharmony_ci#define DZN_USE_WSI_PLATFORM 64bf215546Sopenharmony_ci#endif 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci#define DZN_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION) 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci#define MAX_TIER2_MEMORY_TYPES 3 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic const struct vk_instance_extension_table instance_extensions = { 71bf215546Sopenharmony_ci .KHR_get_physical_device_properties2 = true, 72bf215546Sopenharmony_ci#ifdef DZN_USE_WSI_PLATFORM 73bf215546Sopenharmony_ci .KHR_surface = true, 74bf215546Sopenharmony_ci#endif 75bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WIN32_KHR 76bf215546Sopenharmony_ci .KHR_win32_surface = true, 77bf215546Sopenharmony_ci#endif 78bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XCB_KHR 79bf215546Sopenharmony_ci .KHR_xcb_surface = true, 80bf215546Sopenharmony_ci#endif 81bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_WAYLAND_KHR 82bf215546Sopenharmony_ci .KHR_wayland_surface = true, 83bf215546Sopenharmony_ci#endif 84bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_XLIB_KHR 85bf215546Sopenharmony_ci .KHR_xlib_surface = true, 86bf215546Sopenharmony_ci#endif 87bf215546Sopenharmony_ci .EXT_debug_report = true, 88bf215546Sopenharmony_ci .EXT_debug_utils = true, 89bf215546Sopenharmony_ci}; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_cistatic void 92bf215546Sopenharmony_cidzn_physical_device_get_extensions(struct dzn_physical_device *pdev) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci pdev->vk.supported_extensions = (struct vk_device_extension_table) { 95bf215546Sopenharmony_ci .KHR_create_renderpass2 = true, 96bf215546Sopenharmony_ci .KHR_depth_stencil_resolve = true, 97bf215546Sopenharmony_ci .KHR_descriptor_update_template = true, 98bf215546Sopenharmony_ci .KHR_draw_indirect_count = true, 99bf215546Sopenharmony_ci .KHR_driver_properties = true, 100bf215546Sopenharmony_ci .KHR_dynamic_rendering = true, 101bf215546Sopenharmony_ci .KHR_shader_draw_parameters = true, 102bf215546Sopenharmony_ci#ifdef DZN_USE_WSI_PLATFORM 103bf215546Sopenharmony_ci .KHR_swapchain = true, 104bf215546Sopenharmony_ci#endif 105bf215546Sopenharmony_ci .EXT_vertex_attribute_divisor = true, 106bf215546Sopenharmony_ci }; 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 110bf215546Sopenharmony_cidzn_EnumerateInstanceExtensionProperties(const char *pLayerName, 111bf215546Sopenharmony_ci uint32_t *pPropertyCount, 112bf215546Sopenharmony_ci VkExtensionProperties *pProperties) 113bf215546Sopenharmony_ci{ 114bf215546Sopenharmony_ci /* We don't support any layers */ 115bf215546Sopenharmony_ci if (pLayerName) 116bf215546Sopenharmony_ci return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci return vk_enumerate_instance_extension_properties( 119bf215546Sopenharmony_ci &instance_extensions, pPropertyCount, pProperties); 120bf215546Sopenharmony_ci} 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_cistatic const struct debug_control dzn_debug_options[] = { 123bf215546Sopenharmony_ci { "sync", DZN_DEBUG_SYNC }, 124bf215546Sopenharmony_ci { "nir", DZN_DEBUG_NIR }, 125bf215546Sopenharmony_ci { "dxil", DZN_DEBUG_DXIL }, 126bf215546Sopenharmony_ci { "warp", DZN_DEBUG_WARP }, 127bf215546Sopenharmony_ci { "internal", DZN_DEBUG_INTERNAL }, 128bf215546Sopenharmony_ci { "signature", DZN_DEBUG_SIG }, 129bf215546Sopenharmony_ci { "gbv", DZN_DEBUG_GBV }, 130bf215546Sopenharmony_ci { "d3d12", DZN_DEBUG_D3D12 }, 131bf215546Sopenharmony_ci { "debugger", DZN_DEBUG_DEBUGGER }, 132bf215546Sopenharmony_ci { "redirects", DZN_DEBUG_REDIRECTS }, 133bf215546Sopenharmony_ci { NULL, 0 } 134bf215546Sopenharmony_ci}; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_cistatic void 137bf215546Sopenharmony_cidzn_physical_device_destroy(struct dzn_physical_device *pdev) 138bf215546Sopenharmony_ci{ 139bf215546Sopenharmony_ci struct dzn_instance *instance = container_of(pdev->vk.instance, struct dzn_instance, vk); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci list_del(&pdev->link); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci if (pdev->dev) 144bf215546Sopenharmony_ci ID3D12Device1_Release(pdev->dev); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci if (pdev->adapter) 147bf215546Sopenharmony_ci IUnknown_Release(pdev->adapter); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci dzn_wsi_finish(pdev); 150bf215546Sopenharmony_ci vk_physical_device_finish(&pdev->vk); 151bf215546Sopenharmony_ci vk_free(&instance->vk.alloc, pdev); 152bf215546Sopenharmony_ci} 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_cistatic void 155bf215546Sopenharmony_cidzn_instance_destroy(struct dzn_instance *instance, const VkAllocationCallbacks *alloc) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci if (!instance) 158bf215546Sopenharmony_ci return; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci#ifdef _WIN32 161bf215546Sopenharmony_ci if (instance->dxil_validator) 162bf215546Sopenharmony_ci dxil_destroy_validator(instance->dxil_validator); 163bf215546Sopenharmony_ci#endif 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci list_for_each_entry_safe(struct dzn_physical_device, pdev, 166bf215546Sopenharmony_ci &instance->physical_devices, link) { 167bf215546Sopenharmony_ci dzn_physical_device_destroy(pdev); 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci vk_instance_finish(&instance->vk); 171bf215546Sopenharmony_ci vk_free2(vk_default_allocator(), alloc, instance); 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_cistatic VkResult 175bf215546Sopenharmony_cidzn_instance_create(const VkInstanceCreateInfo *pCreateInfo, 176bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 177bf215546Sopenharmony_ci VkInstance *out) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci struct dzn_instance *instance = 180bf215546Sopenharmony_ci vk_zalloc2(vk_default_allocator(), pAllocator, sizeof(*instance), 8, 181bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 182bf215546Sopenharmony_ci if (!instance) 183bf215546Sopenharmony_ci return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci struct vk_instance_dispatch_table dispatch_table; 186bf215546Sopenharmony_ci vk_instance_dispatch_table_from_entrypoints(&dispatch_table, 187bf215546Sopenharmony_ci &dzn_instance_entrypoints, 188bf215546Sopenharmony_ci true); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci VkResult result = 191bf215546Sopenharmony_ci vk_instance_init(&instance->vk, &instance_extensions, 192bf215546Sopenharmony_ci &dispatch_table, pCreateInfo, 193bf215546Sopenharmony_ci pAllocator ? pAllocator : vk_default_allocator()); 194bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 195bf215546Sopenharmony_ci vk_free2(vk_default_allocator(), pAllocator, instance); 196bf215546Sopenharmony_ci return result; 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci list_inithead(&instance->physical_devices); 200bf215546Sopenharmony_ci instance->physical_devices_enumerated = false; 201bf215546Sopenharmony_ci instance->debug_flags = 202bf215546Sopenharmony_ci parse_debug_string(getenv("DZN_DEBUG"), dzn_debug_options); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci#ifdef _WIN32 205bf215546Sopenharmony_ci if (instance->debug_flags & DZN_DEBUG_DEBUGGER) { 206bf215546Sopenharmony_ci /* wait for debugger to attach... */ 207bf215546Sopenharmony_ci while (!IsDebuggerPresent()) { 208bf215546Sopenharmony_ci Sleep(100); 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci if (instance->debug_flags & DZN_DEBUG_REDIRECTS) { 213bf215546Sopenharmony_ci char home[MAX_PATH], path[MAX_PATH]; 214bf215546Sopenharmony_ci if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, home))) { 215bf215546Sopenharmony_ci snprintf(path, sizeof(path), "%s\\stderr.txt", home); 216bf215546Sopenharmony_ci freopen(path, "w", stderr); 217bf215546Sopenharmony_ci snprintf(path, sizeof(path), "%s\\stdout.txt", home); 218bf215546Sopenharmony_ci freopen(path, "w", stdout); 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci#endif 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci bool missing_validator = false; 224bf215546Sopenharmony_ci#ifdef _WIN32 225bf215546Sopenharmony_ci instance->dxil_validator = dxil_create_validator(NULL); 226bf215546Sopenharmony_ci missing_validator = !instance->dxil_validator; 227bf215546Sopenharmony_ci#endif 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci instance->d3d12.serialize_root_sig = d3d12_get_serialize_root_sig(); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (missing_validator || 232bf215546Sopenharmony_ci !instance->d3d12.serialize_root_sig) { 233bf215546Sopenharmony_ci dzn_instance_destroy(instance, pAllocator); 234bf215546Sopenharmony_ci return vk_error(NULL, VK_ERROR_INITIALIZATION_FAILED); 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci if (instance->debug_flags & DZN_DEBUG_D3D12) 238bf215546Sopenharmony_ci d3d12_enable_debug_layer(); 239bf215546Sopenharmony_ci if (instance->debug_flags & DZN_DEBUG_GBV) 240bf215546Sopenharmony_ci d3d12_enable_gpu_validation(); 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci instance->sync_binary_type = vk_sync_binary_get_type(&dzn_sync_type); 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci *out = dzn_instance_to_handle(instance); 245bf215546Sopenharmony_ci return VK_SUCCESS; 246bf215546Sopenharmony_ci} 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 249bf215546Sopenharmony_cidzn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, 250bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 251bf215546Sopenharmony_ci VkInstance *pInstance) 252bf215546Sopenharmony_ci{ 253bf215546Sopenharmony_ci return dzn_instance_create(pCreateInfo, pAllocator, pInstance); 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 257bf215546Sopenharmony_cidzn_DestroyInstance(VkInstance instance, 258bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 259bf215546Sopenharmony_ci{ 260bf215546Sopenharmony_ci dzn_instance_destroy(dzn_instance_from_handle(instance), pAllocator); 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_cistatic void 264bf215546Sopenharmony_cidzn_physical_device_init_uuids(struct dzn_physical_device *pdev) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci struct mesa_sha1 sha1_ctx; 269bf215546Sopenharmony_ci uint8_t sha1[SHA1_DIGEST_LENGTH]; 270bf215546Sopenharmony_ci STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1)); 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci /* The pipeline cache UUID is used for determining when a pipeline cache is 273bf215546Sopenharmony_ci * invalid. Our cache is device-agnostic, but it does depend on the features 274bf215546Sopenharmony_ci * provided by the D3D12 driver, so let's hash the build ID plus some 275bf215546Sopenharmony_ci * caps that might impact our NIR lowering passes. 276bf215546Sopenharmony_ci */ 277bf215546Sopenharmony_ci _mesa_sha1_init(&sha1_ctx); 278bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, mesa_version, strlen(mesa_version)); 279bf215546Sopenharmony_ci disk_cache_get_function_identifier(dzn_physical_device_init_uuids, &sha1_ctx); 280bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->options, sizeof(pdev->options)); 281bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->options2, sizeof(pdev->options2)); 282bf215546Sopenharmony_ci _mesa_sha1_final(&sha1_ctx, sha1); 283bf215546Sopenharmony_ci memcpy(pdev->pipeline_cache_uuid, sha1, VK_UUID_SIZE); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci /* The driver UUID is used for determining sharability of images and memory 286bf215546Sopenharmony_ci * between two Vulkan instances in separate processes. People who want to 287bf215546Sopenharmony_ci * share memory need to also check the device UUID (below) so all this 288bf215546Sopenharmony_ci * needs to be is the build-id. 289bf215546Sopenharmony_ci */ 290bf215546Sopenharmony_ci _mesa_sha1_compute(mesa_version, strlen(mesa_version), sha1); 291bf215546Sopenharmony_ci memcpy(pdev->driver_uuid, sha1, VK_UUID_SIZE); 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci /* The device UUID uniquely identifies the given device within the machine. */ 294bf215546Sopenharmony_ci _mesa_sha1_init(&sha1_ctx); 295bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->desc.vendor_id, sizeof(pdev->desc.vendor_id)); 296bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->desc.device_id, sizeof(pdev->desc.device_id)); 297bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->desc.subsys_id, sizeof(pdev->desc.subsys_id)); 298bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, &pdev->desc.revision, sizeof(pdev->desc.revision)); 299bf215546Sopenharmony_ci _mesa_sha1_final(&sha1_ctx, sha1); 300bf215546Sopenharmony_ci memcpy(pdev->device_uuid, sha1, VK_UUID_SIZE); 301bf215546Sopenharmony_ci} 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ciconst struct vk_pipeline_cache_object_ops *const dzn_pipeline_cache_import_ops[] = { 304bf215546Sopenharmony_ci &dzn_cached_blob_ops, 305bf215546Sopenharmony_ci NULL, 306bf215546Sopenharmony_ci}; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_cistatic VkResult 309bf215546Sopenharmony_cidzn_physical_device_create(struct dzn_instance *instance, 310bf215546Sopenharmony_ci IUnknown *adapter, 311bf215546Sopenharmony_ci const struct dzn_physical_device_desc *desc) 312bf215546Sopenharmony_ci{ 313bf215546Sopenharmony_ci struct dzn_physical_device *pdev = 314bf215546Sopenharmony_ci vk_zalloc(&instance->vk.alloc, sizeof(*pdev), 8, 315bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci if (!pdev) 318bf215546Sopenharmony_ci return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci struct vk_physical_device_dispatch_table dispatch_table; 321bf215546Sopenharmony_ci vk_physical_device_dispatch_table_from_entrypoints(&dispatch_table, 322bf215546Sopenharmony_ci &dzn_physical_device_entrypoints, 323bf215546Sopenharmony_ci true); 324bf215546Sopenharmony_ci vk_physical_device_dispatch_table_from_entrypoints(&dispatch_table, 325bf215546Sopenharmony_ci &wsi_physical_device_entrypoints, 326bf215546Sopenharmony_ci false); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci VkResult result = 329bf215546Sopenharmony_ci vk_physical_device_init(&pdev->vk, &instance->vk, 330bf215546Sopenharmony_ci NULL, /* We set up extensions later */ 331bf215546Sopenharmony_ci &dispatch_table); 332bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 333bf215546Sopenharmony_ci vk_free(&instance->vk.alloc, pdev); 334bf215546Sopenharmony_ci return result; 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci mtx_init(&pdev->dev_lock, mtx_plain); 338bf215546Sopenharmony_ci pdev->desc = *desc; 339bf215546Sopenharmony_ci pdev->adapter = adapter; 340bf215546Sopenharmony_ci IUnknown_AddRef(adapter); 341bf215546Sopenharmony_ci list_addtail(&pdev->link, &instance->physical_devices); 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci vk_warn_non_conformant_implementation("dzn"); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci uint32_t num_sync_types = 0; 346bf215546Sopenharmony_ci pdev->sync_types[num_sync_types++] = &dzn_sync_type; 347bf215546Sopenharmony_ci pdev->sync_types[num_sync_types++] = &instance->sync_binary_type.sync; 348bf215546Sopenharmony_ci pdev->sync_types[num_sync_types++] = &vk_sync_dummy_type; 349bf215546Sopenharmony_ci pdev->sync_types[num_sync_types] = NULL; 350bf215546Sopenharmony_ci assert(num_sync_types <= MAX_SYNC_TYPES); 351bf215546Sopenharmony_ci pdev->vk.supported_sync_types = pdev->sync_types; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci pdev->vk.pipeline_cache_import_ops = dzn_pipeline_cache_import_ops; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci /* TODO: something something queue families */ 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci result = dzn_wsi_init(pdev); 358bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 359bf215546Sopenharmony_ci dzn_physical_device_destroy(pdev); 360bf215546Sopenharmony_ci return result; 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci dzn_physical_device_get_extensions(pdev); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci return VK_SUCCESS; 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_cistatic void 369bf215546Sopenharmony_cidzn_physical_device_cache_caps(struct dzn_physical_device *pdev) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci D3D_FEATURE_LEVEL checklist[] = { 372bf215546Sopenharmony_ci D3D_FEATURE_LEVEL_11_0, 373bf215546Sopenharmony_ci D3D_FEATURE_LEVEL_11_1, 374bf215546Sopenharmony_ci D3D_FEATURE_LEVEL_12_0, 375bf215546Sopenharmony_ci D3D_FEATURE_LEVEL_12_1, 376bf215546Sopenharmony_ci D3D_FEATURE_LEVEL_12_2, 377bf215546Sopenharmony_ci }; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FEATURE_LEVELS levels = { 380bf215546Sopenharmony_ci .NumFeatureLevels = ARRAY_SIZE(checklist), 381bf215546Sopenharmony_ci .pFeatureLevelsRequested = checklist, 382bf215546Sopenharmony_ci }; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_FEATURE_LEVELS, &levels, sizeof(levels)); 385bf215546Sopenharmony_ci pdev->feature_level = levels.MaxSupportedFeatureLevel; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_ARCHITECTURE1, &pdev->architecture, sizeof(pdev->architecture)); 388bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS, &pdev->options, sizeof(pdev->options)); 389bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS2, &pdev->options2, sizeof(pdev->options2)); 390bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(pdev->dev, D3D12_FEATURE_D3D12_OPTIONS3, &pdev->options3, sizeof(pdev->options3)); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci pdev->queue_families[pdev->queue_family_count++] = (struct dzn_queue_family) { 393bf215546Sopenharmony_ci .props = { 394bf215546Sopenharmony_ci .queueFlags = VK_QUEUE_GRAPHICS_BIT | 395bf215546Sopenharmony_ci VK_QUEUE_COMPUTE_BIT | 396bf215546Sopenharmony_ci VK_QUEUE_TRANSFER_BIT, 397bf215546Sopenharmony_ci .queueCount = 1, 398bf215546Sopenharmony_ci .timestampValidBits = 64, 399bf215546Sopenharmony_ci .minImageTransferGranularity = { 0, 0, 0 }, 400bf215546Sopenharmony_ci }, 401bf215546Sopenharmony_ci .desc = { 402bf215546Sopenharmony_ci .Type = D3D12_COMMAND_LIST_TYPE_DIRECT, 403bf215546Sopenharmony_ci }, 404bf215546Sopenharmony_ci }; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci pdev->queue_families[pdev->queue_family_count++] = (struct dzn_queue_family) { 407bf215546Sopenharmony_ci .props = { 408bf215546Sopenharmony_ci .queueFlags = VK_QUEUE_COMPUTE_BIT | 409bf215546Sopenharmony_ci VK_QUEUE_TRANSFER_BIT, 410bf215546Sopenharmony_ci .queueCount = 8, 411bf215546Sopenharmony_ci .timestampValidBits = 64, 412bf215546Sopenharmony_ci .minImageTransferGranularity = { 0, 0, 0 }, 413bf215546Sopenharmony_ci }, 414bf215546Sopenharmony_ci .desc = { 415bf215546Sopenharmony_ci .Type = D3D12_COMMAND_LIST_TYPE_COMPUTE, 416bf215546Sopenharmony_ci }, 417bf215546Sopenharmony_ci }; 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_ci pdev->queue_families[pdev->queue_family_count++] = (struct dzn_queue_family) { 420bf215546Sopenharmony_ci .props = { 421bf215546Sopenharmony_ci .queueFlags = VK_QUEUE_TRANSFER_BIT, 422bf215546Sopenharmony_ci .queueCount = 1, 423bf215546Sopenharmony_ci .timestampValidBits = 0, 424bf215546Sopenharmony_ci .minImageTransferGranularity = { 0, 0, 0 }, 425bf215546Sopenharmony_ci }, 426bf215546Sopenharmony_ci .desc = { 427bf215546Sopenharmony_ci .Type = D3D12_COMMAND_LIST_TYPE_COPY, 428bf215546Sopenharmony_ci }, 429bf215546Sopenharmony_ci }; 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci assert(pdev->queue_family_count <= ARRAY_SIZE(pdev->queue_families)); 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci D3D12_COMMAND_QUEUE_DESC queue_desc = { 434bf215546Sopenharmony_ci .Type = D3D12_COMMAND_LIST_TYPE_DIRECT, 435bf215546Sopenharmony_ci .Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, 436bf215546Sopenharmony_ci .Flags = D3D12_COMMAND_QUEUE_FLAG_NONE, 437bf215546Sopenharmony_ci .NodeMask = 0, 438bf215546Sopenharmony_ci }; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci ID3D12CommandQueue *cmdqueue; 441bf215546Sopenharmony_ci ID3D12Device1_CreateCommandQueue(pdev->dev, &queue_desc, 442bf215546Sopenharmony_ci &IID_ID3D12CommandQueue, 443bf215546Sopenharmony_ci (void **)&cmdqueue); 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci uint64_t ts_freq; 446bf215546Sopenharmony_ci ID3D12CommandQueue_GetTimestampFrequency(cmdqueue, &ts_freq); 447bf215546Sopenharmony_ci pdev->timestamp_period = 1000000000.0f / ts_freq; 448bf215546Sopenharmony_ci ID3D12CommandQueue_Release(cmdqueue); 449bf215546Sopenharmony_ci} 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_cistatic void 452bf215546Sopenharmony_cidzn_physical_device_init_memory(struct dzn_physical_device *pdev) 453bf215546Sopenharmony_ci{ 454bf215546Sopenharmony_ci VkPhysicalDeviceMemoryProperties *mem = &pdev->memory; 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci mem->memoryHeapCount = 1; 457bf215546Sopenharmony_ci mem->memoryHeaps[0] = (VkMemoryHeap) { 458bf215546Sopenharmony_ci .size = pdev->desc.shared_system_memory, 459bf215546Sopenharmony_ci .flags = 0, 460bf215546Sopenharmony_ci }; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci mem->memoryTypes[mem->memoryTypeCount++] = (VkMemoryType) { 463bf215546Sopenharmony_ci .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 464bf215546Sopenharmony_ci VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 465bf215546Sopenharmony_ci .heapIndex = 0, 466bf215546Sopenharmony_ci }; 467bf215546Sopenharmony_ci mem->memoryTypes[mem->memoryTypeCount++] = (VkMemoryType) { 468bf215546Sopenharmony_ci .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 469bf215546Sopenharmony_ci VK_MEMORY_PROPERTY_HOST_CACHED_BIT | 470bf215546Sopenharmony_ci VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 471bf215546Sopenharmony_ci .heapIndex = 0, 472bf215546Sopenharmony_ci }; 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci if (!pdev->architecture.UMA) { 475bf215546Sopenharmony_ci mem->memoryHeaps[mem->memoryHeapCount++] = (VkMemoryHeap) { 476bf215546Sopenharmony_ci .size = pdev->desc.dedicated_video_memory, 477bf215546Sopenharmony_ci .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, 478bf215546Sopenharmony_ci }; 479bf215546Sopenharmony_ci mem->memoryTypes[mem->memoryTypeCount++] = (VkMemoryType) { 480bf215546Sopenharmony_ci .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 481bf215546Sopenharmony_ci .heapIndex = mem->memoryHeapCount - 1, 482bf215546Sopenharmony_ci }; 483bf215546Sopenharmony_ci } else { 484bf215546Sopenharmony_ci mem->memoryHeaps[0].flags |= VK_MEMORY_HEAP_DEVICE_LOCAL_BIT; 485bf215546Sopenharmony_ci mem->memoryTypes[0].propertyFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 486bf215546Sopenharmony_ci mem->memoryTypes[1].propertyFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; 487bf215546Sopenharmony_ci } 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci assert(mem->memoryTypeCount <= MAX_TIER2_MEMORY_TYPES); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci if (pdev->options.ResourceHeapTier == D3D12_RESOURCE_HEAP_TIER_1) { 492bf215546Sopenharmony_ci unsigned oldMemoryTypeCount = mem->memoryTypeCount; 493bf215546Sopenharmony_ci VkMemoryType oldMemoryTypes[MAX_TIER2_MEMORY_TYPES]; 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci memcpy(oldMemoryTypes, mem->memoryTypes, oldMemoryTypeCount * sizeof(VkMemoryType)); 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci mem->memoryTypeCount = 0; 498bf215546Sopenharmony_ci for (unsigned oldMemoryTypeIdx = 0; oldMemoryTypeIdx < oldMemoryTypeCount; ++oldMemoryTypeIdx) { 499bf215546Sopenharmony_ci D3D12_HEAP_FLAGS flags[] = { 500bf215546Sopenharmony_ci D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS, 501bf215546Sopenharmony_ci D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, 502bf215546Sopenharmony_ci /* Note: Vulkan requires *all* images to come from the same memory type as long as 503bf215546Sopenharmony_ci * the tiling property (and a few other misc properties) are the same. So, this 504bf215546Sopenharmony_ci * non-RT/DS texture flag will only be used for TILING_LINEAR textures, which 505bf215546Sopenharmony_ci * can't be render targets. 506bf215546Sopenharmony_ci */ 507bf215546Sopenharmony_ci D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES 508bf215546Sopenharmony_ci }; 509bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(flags); ++i) { 510bf215546Sopenharmony_ci D3D12_HEAP_FLAGS flag = flags[i]; 511bf215546Sopenharmony_ci pdev->heap_flags_for_mem_type[mem->memoryTypeCount] = flag; 512bf215546Sopenharmony_ci mem->memoryTypes[mem->memoryTypeCount] = oldMemoryTypes[oldMemoryTypeIdx]; 513bf215546Sopenharmony_ci mem->memoryTypeCount++; 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci } 516bf215546Sopenharmony_ci } 517bf215546Sopenharmony_ci} 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_cistatic D3D12_HEAP_FLAGS 520bf215546Sopenharmony_cidzn_physical_device_get_heap_flags_for_mem_type(const struct dzn_physical_device *pdev, 521bf215546Sopenharmony_ci uint32_t mem_type) 522bf215546Sopenharmony_ci{ 523bf215546Sopenharmony_ci return pdev->heap_flags_for_mem_type[mem_type]; 524bf215546Sopenharmony_ci} 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ciuint32_t 527bf215546Sopenharmony_cidzn_physical_device_get_mem_type_mask_for_resource(const struct dzn_physical_device *pdev, 528bf215546Sopenharmony_ci const D3D12_RESOURCE_DESC *desc) 529bf215546Sopenharmony_ci{ 530bf215546Sopenharmony_ci if (pdev->options.ResourceHeapTier > D3D12_RESOURCE_HEAP_TIER_1) 531bf215546Sopenharmony_ci return (1u << pdev->memory.memoryTypeCount) - 1; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci D3D12_HEAP_FLAGS deny_flag; 534bf215546Sopenharmony_ci if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) 535bf215546Sopenharmony_ci deny_flag = D3D12_HEAP_FLAG_DENY_BUFFERS; 536bf215546Sopenharmony_ci else if (desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) 537bf215546Sopenharmony_ci deny_flag = D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES; 538bf215546Sopenharmony_ci else 539bf215546Sopenharmony_ci deny_flag = D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci uint32_t mask = 0; 542bf215546Sopenharmony_ci for (unsigned i = 0; i < pdev->memory.memoryTypeCount; ++i) { 543bf215546Sopenharmony_ci if ((pdev->heap_flags_for_mem_type[i] & deny_flag) == D3D12_HEAP_FLAG_NONE) 544bf215546Sopenharmony_ci mask |= (1 << i); 545bf215546Sopenharmony_ci } 546bf215546Sopenharmony_ci return mask; 547bf215546Sopenharmony_ci} 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_cistatic uint32_t 550bf215546Sopenharmony_cidzn_physical_device_get_max_mip_level(bool is_3d) 551bf215546Sopenharmony_ci{ 552bf215546Sopenharmony_ci return is_3d ? 11 : 14; 553bf215546Sopenharmony_ci} 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_cistatic uint32_t 556bf215546Sopenharmony_cidzn_physical_device_get_max_extent(bool is_3d) 557bf215546Sopenharmony_ci{ 558bf215546Sopenharmony_ci uint32_t max_mip = dzn_physical_device_get_max_mip_level(is_3d); 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci return 1 << max_mip; 561bf215546Sopenharmony_ci} 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_cistatic uint32_t 564bf215546Sopenharmony_cidzn_physical_device_get_max_array_layers() 565bf215546Sopenharmony_ci{ 566bf215546Sopenharmony_ci return dzn_physical_device_get_max_extent(false); 567bf215546Sopenharmony_ci} 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_cistatic ID3D12Device2 * 570bf215546Sopenharmony_cidzn_physical_device_get_d3d12_dev(struct dzn_physical_device *pdev) 571bf215546Sopenharmony_ci{ 572bf215546Sopenharmony_ci struct dzn_instance *instance = container_of(pdev->vk.instance, struct dzn_instance, vk); 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci mtx_lock(&pdev->dev_lock); 575bf215546Sopenharmony_ci if (!pdev->dev) { 576bf215546Sopenharmony_ci pdev->dev = d3d12_create_device(pdev->adapter, !instance->dxil_validator); 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci dzn_physical_device_cache_caps(pdev); 579bf215546Sopenharmony_ci dzn_physical_device_init_memory(pdev); 580bf215546Sopenharmony_ci dzn_physical_device_init_uuids(pdev); 581bf215546Sopenharmony_ci } 582bf215546Sopenharmony_ci mtx_unlock(&pdev->dev_lock); 583bf215546Sopenharmony_ci 584bf215546Sopenharmony_ci return pdev->dev; 585bf215546Sopenharmony_ci} 586bf215546Sopenharmony_ci 587bf215546Sopenharmony_ciD3D12_FEATURE_DATA_FORMAT_SUPPORT 588bf215546Sopenharmony_cidzn_physical_device_get_format_support(struct dzn_physical_device *pdev, 589bf215546Sopenharmony_ci VkFormat format) 590bf215546Sopenharmony_ci{ 591bf215546Sopenharmony_ci VkImageUsageFlags usage = 592bf215546Sopenharmony_ci vk_format_is_depth_or_stencil(format) ? 593bf215546Sopenharmony_ci VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0; 594bf215546Sopenharmony_ci VkImageAspectFlags aspects = 0; 595bf215546Sopenharmony_ci VkFormat patched_format = 596bf215546Sopenharmony_ci dzn_graphics_pipeline_patch_vi_format(format); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci if (patched_format != format) { 599bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FORMAT_SUPPORT dfmt_info = { 600bf215546Sopenharmony_ci .Format = dzn_buffer_get_dxgi_format(patched_format), 601bf215546Sopenharmony_ci .Support1 = D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER, 602bf215546Sopenharmony_ci }; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci return dfmt_info; 605bf215546Sopenharmony_ci } 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci if (vk_format_has_depth(format)) 608bf215546Sopenharmony_ci aspects = VK_IMAGE_ASPECT_DEPTH_BIT; 609bf215546Sopenharmony_ci if (vk_format_has_stencil(format)) 610bf215546Sopenharmony_ci aspects = VK_IMAGE_ASPECT_STENCIL_BIT; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FORMAT_SUPPORT dfmt_info = { 613bf215546Sopenharmony_ci .Format = dzn_image_get_dxgi_format(format, usage, aspects), 614bf215546Sopenharmony_ci }; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci ID3D12Device2 *dev = dzn_physical_device_get_d3d12_dev(pdev); 617bf215546Sopenharmony_ci ASSERTED HRESULT hres = 618bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(dev, D3D12_FEATURE_FORMAT_SUPPORT, 619bf215546Sopenharmony_ci &dfmt_info, sizeof(dfmt_info)); 620bf215546Sopenharmony_ci assert(!FAILED(hres)); 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci if (usage != VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) 623bf215546Sopenharmony_ci return dfmt_info; 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci /* Depth/stencil resources have different format when they're accessed 626bf215546Sopenharmony_ci * as textures, query the capabilities for this format too. 627bf215546Sopenharmony_ci */ 628bf215546Sopenharmony_ci dzn_foreach_aspect(aspect, aspects) { 629bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FORMAT_SUPPORT dfmt_info2 = { 630bf215546Sopenharmony_ci .Format = dzn_image_get_dxgi_format(format, 0, aspect), 631bf215546Sopenharmony_ci }; 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci hres = ID3D12Device1_CheckFeatureSupport(dev, D3D12_FEATURE_FORMAT_SUPPORT, 634bf215546Sopenharmony_ci &dfmt_info2, sizeof(dfmt_info2)); 635bf215546Sopenharmony_ci assert(!FAILED(hres)); 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci#define DS_SRV_FORMAT_SUPPORT1_MASK \ 638bf215546Sopenharmony_ci (D3D12_FORMAT_SUPPORT1_SHADER_LOAD | \ 639bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE | \ 640bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON | \ 641bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_MONO_TEXT | \ 642bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE | \ 643bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD | \ 644bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_SHADER_GATHER | \ 645bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW | \ 646bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_SHADER_GATHER_COMPARISON) 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci dfmt_info.Support1 |= dfmt_info2.Support1 & DS_SRV_FORMAT_SUPPORT1_MASK; 649bf215546Sopenharmony_ci dfmt_info.Support2 |= dfmt_info2.Support2; 650bf215546Sopenharmony_ci } 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci return dfmt_info; 653bf215546Sopenharmony_ci} 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_cistatic void 656bf215546Sopenharmony_cidzn_physical_device_get_format_properties(struct dzn_physical_device *pdev, 657bf215546Sopenharmony_ci VkFormat format, 658bf215546Sopenharmony_ci VkFormatProperties2 *properties) 659bf215546Sopenharmony_ci{ 660bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FORMAT_SUPPORT dfmt_info = 661bf215546Sopenharmony_ci dzn_physical_device_get_format_support(pdev, format); 662bf215546Sopenharmony_ci VkFormatProperties *base_props = &properties->formatProperties; 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci vk_foreach_struct(ext, properties->pNext) { 665bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci if (dfmt_info.Format == DXGI_FORMAT_UNKNOWN) { 669bf215546Sopenharmony_ci *base_props = (VkFormatProperties) { 0 }; 670bf215546Sopenharmony_ci return; 671bf215546Sopenharmony_ci } 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci *base_props = (VkFormatProperties) { 674bf215546Sopenharmony_ci .linearTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT, 675bf215546Sopenharmony_ci .optimalTilingFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT, 676bf215546Sopenharmony_ci .bufferFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT, 677bf215546Sopenharmony_ci }; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER) 680bf215546Sopenharmony_ci base_props->bufferFeatures |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci#define TEX_FLAGS (D3D12_FORMAT_SUPPORT1_TEXTURE1D | \ 683bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_TEXTURE2D | \ 684bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_TEXTURE3D | \ 685bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT1_TEXTURECUBE) 686bf215546Sopenharmony_ci if (dfmt_info.Support1 & TEX_FLAGS) { 687bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= 688bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT; 689bf215546Sopenharmony_ci } 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE) { 692bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= 693bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 694bf215546Sopenharmony_ci } 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci if ((dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD) && 697bf215546Sopenharmony_ci (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW)) { 698bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 699bf215546Sopenharmony_ci base_props->bufferFeatures |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; 700bf215546Sopenharmony_ci } 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci#define ATOMIC_FLAGS (D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD | \ 703bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS | \ 704bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE | \ 705bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE | \ 706bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX | \ 707bf215546Sopenharmony_ci D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX) 708bf215546Sopenharmony_ci if ((dfmt_info.Support2 & ATOMIC_FLAGS) == ATOMIC_FLAGS) { 709bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; 710bf215546Sopenharmony_ci base_props->bufferFeatures |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 711bf215546Sopenharmony_ci } 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD) 714bf215546Sopenharmony_ci base_props->bufferFeatures |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci /* Color/depth/stencil attachment cap implies input attachement cap, and input 717bf215546Sopenharmony_ci * attachment loads are lowered to texture loads in dozen, hence the requirement 718bf215546Sopenharmony_ci * to have shader-load support. 719bf215546Sopenharmony_ci */ 720bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD) { 721bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET) { 722bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= 723bf215546Sopenharmony_ci VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 724bf215546Sopenharmony_ci } 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_BLENDABLE) 727bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci if (dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL) { 730bf215546Sopenharmony_ci base_props->optimalTilingFeatures |= 731bf215546Sopenharmony_ci VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 732bf215546Sopenharmony_ci } 733bf215546Sopenharmony_ci } 734bf215546Sopenharmony_ci 735bf215546Sopenharmony_ci /* B4G4R4A4 support is required, but d3d12 doesn't support it. We map this 736bf215546Sopenharmony_ci * format to R4G4B4A4 and adjust the SRV component-mapping to fake 737bf215546Sopenharmony_ci * B4G4R4A4, but that forces us to limit the usage to sampling, which, 738bf215546Sopenharmony_ci * luckily, is exactly what we need to support the required features. 739bf215546Sopenharmony_ci */ 740bf215546Sopenharmony_ci if (format == VK_FORMAT_B4G4R4A4_UNORM_PACK16) { 741bf215546Sopenharmony_ci VkFormatFeatureFlags bgra4_req_features = 742bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | 743bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_DST_BIT | 744bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 745bf215546Sopenharmony_ci VK_FORMAT_FEATURE_BLIT_SRC_BIT | 746bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 747bf215546Sopenharmony_ci base_props->optimalTilingFeatures &= bgra4_req_features; 748bf215546Sopenharmony_ci base_props->bufferFeatures = 749bf215546Sopenharmony_ci VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT; 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci /* depth/stencil format shouldn't advertise buffer features */ 753bf215546Sopenharmony_ci if (vk_format_is_depth_or_stencil(format)) 754bf215546Sopenharmony_ci base_props->bufferFeatures = 0; 755bf215546Sopenharmony_ci} 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_cistatic VkResult 758bf215546Sopenharmony_cidzn_physical_device_get_image_format_properties(struct dzn_physical_device *pdev, 759bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 760bf215546Sopenharmony_ci VkImageFormatProperties2 *properties) 761bf215546Sopenharmony_ci{ 762bf215546Sopenharmony_ci const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 763bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_props = NULL; 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci *properties = (VkImageFormatProperties2) { 766bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, 767bf215546Sopenharmony_ci }; 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci /* Extract input structs */ 770bf215546Sopenharmony_ci vk_foreach_struct_const(s, info->pNext) { 771bf215546Sopenharmony_ci switch (s->sType) { 772bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 773bf215546Sopenharmony_ci external_info = (const VkPhysicalDeviceExternalImageFormatInfo *)s; 774bf215546Sopenharmony_ci break; 775bf215546Sopenharmony_ci default: 776bf215546Sopenharmony_ci dzn_debug_ignored_stype(s->sType); 777bf215546Sopenharmony_ci break; 778bf215546Sopenharmony_ci } 779bf215546Sopenharmony_ci } 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_ci assert(info->tiling == VK_IMAGE_TILING_OPTIMAL || info->tiling == VK_IMAGE_TILING_LINEAR); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci /* Extract output structs */ 784bf215546Sopenharmony_ci vk_foreach_struct(s, properties->pNext) { 785bf215546Sopenharmony_ci switch (s->sType) { 786bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 787bf215546Sopenharmony_ci external_props = (VkExternalImageFormatProperties *)s; 788bf215546Sopenharmony_ci external_props->externalMemoryProperties = (VkExternalMemoryProperties) { 0 }; 789bf215546Sopenharmony_ci break; 790bf215546Sopenharmony_ci default: 791bf215546Sopenharmony_ci dzn_debug_ignored_stype(s->sType); 792bf215546Sopenharmony_ci break; 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci } 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci /* TODO: support image import */ 797bf215546Sopenharmony_ci if (external_info && external_info->handleType != 0) 798bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci if (info->tiling != VK_IMAGE_TILING_OPTIMAL && 801bf215546Sopenharmony_ci (info->usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT))) 802bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci if (info->tiling != VK_IMAGE_TILING_OPTIMAL && 805bf215546Sopenharmony_ci vk_format_is_depth_or_stencil(info->format)) 806bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_ci D3D12_FEATURE_DATA_FORMAT_SUPPORT dfmt_info = 809bf215546Sopenharmony_ci dzn_physical_device_get_format_support(pdev, info->format); 810bf215546Sopenharmony_ci if (dfmt_info.Format == DXGI_FORMAT_UNKNOWN) 811bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 812bf215546Sopenharmony_ci 813bf215546Sopenharmony_ci bool is_bgra4 = info->format == VK_FORMAT_B4G4R4A4_UNORM_PACK16; 814bf215546Sopenharmony_ci ID3D12Device2 *dev = dzn_physical_device_get_d3d12_dev(pdev); 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci if ((info->type == VK_IMAGE_TYPE_1D && !(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE1D)) || 817bf215546Sopenharmony_ci (info->type == VK_IMAGE_TYPE_2D && !(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE2D)) || 818bf215546Sopenharmony_ci (info->type == VK_IMAGE_TYPE_3D && !(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURE3D)) || 819bf215546Sopenharmony_ci ((info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 820bf215546Sopenharmony_ci !(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TEXTURECUBE))) 821bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 822bf215546Sopenharmony_ci 823bf215546Sopenharmony_ci if ((info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) && 824bf215546Sopenharmony_ci !(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE)) 825bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ci if ((info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && 828bf215546Sopenharmony_ci (!(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_SHADER_LOAD) || is_bgra4)) 829bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 830bf215546Sopenharmony_ci 831bf215546Sopenharmony_ci if ((info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && 832bf215546Sopenharmony_ci (!(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET) || is_bgra4)) 833bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci if ((info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && 836bf215546Sopenharmony_ci (!(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL) || is_bgra4)) 837bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci if ((info->usage & VK_IMAGE_USAGE_STORAGE_BIT) && 840bf215546Sopenharmony_ci (!(dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW) || is_bgra4)) 841bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 842bf215546Sopenharmony_ci 843bf215546Sopenharmony_ci if (info->type == VK_IMAGE_TYPE_3D && info->tiling != VK_IMAGE_TILING_OPTIMAL) 844bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci bool is_3d = info->type == VK_IMAGE_TYPE_3D; 847bf215546Sopenharmony_ci uint32_t max_extent = dzn_physical_device_get_max_extent(is_3d); 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 850bf215546Sopenharmony_ci dfmt_info.Support1 & D3D12_FORMAT_SUPPORT1_MIP) 851bf215546Sopenharmony_ci properties->imageFormatProperties.maxMipLevels = dzn_physical_device_get_max_mip_level(is_3d) + 1; 852bf215546Sopenharmony_ci else 853bf215546Sopenharmony_ci properties->imageFormatProperties.maxMipLevels = 1; 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci if (info->tiling == VK_IMAGE_TILING_OPTIMAL && info->type != VK_IMAGE_TYPE_3D) 856bf215546Sopenharmony_ci properties->imageFormatProperties.maxArrayLayers = dzn_physical_device_get_max_array_layers(); 857bf215546Sopenharmony_ci else 858bf215546Sopenharmony_ci properties->imageFormatProperties.maxArrayLayers = 1; 859bf215546Sopenharmony_ci 860bf215546Sopenharmony_ci switch (info->type) { 861bf215546Sopenharmony_ci case VK_IMAGE_TYPE_1D: 862bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.width = max_extent; 863bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.height = 1; 864bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.depth = 1; 865bf215546Sopenharmony_ci break; 866bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 867bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.width = max_extent; 868bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.height = max_extent; 869bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.depth = 1; 870bf215546Sopenharmony_ci break; 871bf215546Sopenharmony_ci case VK_IMAGE_TYPE_3D: 872bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.width = max_extent; 873bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.height = max_extent; 874bf215546Sopenharmony_ci properties->imageFormatProperties.maxExtent.depth = max_extent; 875bf215546Sopenharmony_ci break; 876bf215546Sopenharmony_ci default: 877bf215546Sopenharmony_ci unreachable("bad VkImageType"); 878bf215546Sopenharmony_ci } 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci /* From the Vulkan 1.0 spec, section 34.1.1. Supported Sample Counts: 881bf215546Sopenharmony_ci * 882bf215546Sopenharmony_ci * sampleCounts will be set to VK_SAMPLE_COUNT_1_BIT if at least one of the 883bf215546Sopenharmony_ci * following conditions is true: 884bf215546Sopenharmony_ci * 885bf215546Sopenharmony_ci * - tiling is VK_IMAGE_TILING_LINEAR 886bf215546Sopenharmony_ci * - type is not VK_IMAGE_TYPE_2D 887bf215546Sopenharmony_ci * - flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT 888bf215546Sopenharmony_ci * - neither the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag nor the 889bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in 890bf215546Sopenharmony_ci * VkFormatProperties::optimalTilingFeatures returned by 891bf215546Sopenharmony_ci * vkGetPhysicalDeviceFormatProperties is set. 892bf215546Sopenharmony_ci * 893bf215546Sopenharmony_ci * D3D12 has a few more constraints: 894bf215546Sopenharmony_ci * - no UAVs on multisample resources 895bf215546Sopenharmony_ci */ 896bf215546Sopenharmony_ci bool rt_or_ds_cap = 897bf215546Sopenharmony_ci dfmt_info.Support1 & 898bf215546Sopenharmony_ci (D3D12_FORMAT_SUPPORT1_RENDER_TARGET | D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL); 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci properties->imageFormatProperties.sampleCounts = VK_SAMPLE_COUNT_1_BIT; 901bf215546Sopenharmony_ci if (info->tiling != VK_IMAGE_TILING_LINEAR && 902bf215546Sopenharmony_ci info->type == VK_IMAGE_TYPE_2D && 903bf215546Sopenharmony_ci !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 904bf215546Sopenharmony_ci rt_or_ds_cap && !is_bgra4 && 905bf215546Sopenharmony_ci !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 906bf215546Sopenharmony_ci for (uint32_t s = VK_SAMPLE_COUNT_2_BIT; s < VK_SAMPLE_COUNT_64_BIT; s <<= 1) { 907bf215546Sopenharmony_ci D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS ms_info = { 908bf215546Sopenharmony_ci .Format = dfmt_info.Format, 909bf215546Sopenharmony_ci .SampleCount = s, 910bf215546Sopenharmony_ci }; 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci HRESULT hres = 913bf215546Sopenharmony_ci ID3D12Device1_CheckFeatureSupport(dev, D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, 914bf215546Sopenharmony_ci &ms_info, sizeof(ms_info)); 915bf215546Sopenharmony_ci if (!FAILED(hres) && ms_info.NumQualityLevels > 0) 916bf215546Sopenharmony_ci properties->imageFormatProperties.sampleCounts |= s; 917bf215546Sopenharmony_ci } 918bf215546Sopenharmony_ci } 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci /* TODO: set correct value here */ 921bf215546Sopenharmony_ci properties->imageFormatProperties.maxResourceSize = UINT32_MAX; 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci return VK_SUCCESS; 924bf215546Sopenharmony_ci} 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 927bf215546Sopenharmony_cidzn_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, 928bf215546Sopenharmony_ci VkFormat format, 929bf215546Sopenharmony_ci VkFormatProperties2 *pFormatProperties) 930bf215546Sopenharmony_ci{ 931bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_ci dzn_physical_device_get_format_properties(pdev, format, pFormatProperties); 934bf215546Sopenharmony_ci} 935bf215546Sopenharmony_ci 936bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 937bf215546Sopenharmony_cidzn_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 938bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 939bf215546Sopenharmony_ci VkImageFormatProperties2 *props) 940bf215546Sopenharmony_ci{ 941bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci return dzn_physical_device_get_image_format_properties(pdev, info, props); 944bf215546Sopenharmony_ci} 945bf215546Sopenharmony_ci 946bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 947bf215546Sopenharmony_cidzn_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, 948bf215546Sopenharmony_ci VkFormat format, 949bf215546Sopenharmony_ci VkImageType type, 950bf215546Sopenharmony_ci VkImageTiling tiling, 951bf215546Sopenharmony_ci VkImageUsageFlags usage, 952bf215546Sopenharmony_ci VkImageCreateFlags createFlags, 953bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties) 954bf215546Sopenharmony_ci{ 955bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 info = { 956bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 957bf215546Sopenharmony_ci .format = format, 958bf215546Sopenharmony_ci .type = type, 959bf215546Sopenharmony_ci .tiling = tiling, 960bf215546Sopenharmony_ci .usage = usage, 961bf215546Sopenharmony_ci .flags = createFlags, 962bf215546Sopenharmony_ci }; 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci VkImageFormatProperties2 props = { 0 }; 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci VkResult result = 967bf215546Sopenharmony_ci dzn_GetPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &props); 968bf215546Sopenharmony_ci *pImageFormatProperties = props.imageFormatProperties; 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_ci return result; 971bf215546Sopenharmony_ci} 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 974bf215546Sopenharmony_cidzn_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, 975bf215546Sopenharmony_ci VkFormat format, 976bf215546Sopenharmony_ci VkImageType type, 977bf215546Sopenharmony_ci VkSampleCountFlagBits samples, 978bf215546Sopenharmony_ci VkImageUsageFlags usage, 979bf215546Sopenharmony_ci VkImageTiling tiling, 980bf215546Sopenharmony_ci uint32_t *pPropertyCount, 981bf215546Sopenharmony_ci VkSparseImageFormatProperties *pProperties) 982bf215546Sopenharmony_ci{ 983bf215546Sopenharmony_ci *pPropertyCount = 0; 984bf215546Sopenharmony_ci} 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 987bf215546Sopenharmony_cidzn_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, 988bf215546Sopenharmony_ci const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 989bf215546Sopenharmony_ci uint32_t *pPropertyCount, 990bf215546Sopenharmony_ci VkSparseImageFormatProperties2 *pProperties) 991bf215546Sopenharmony_ci{ 992bf215546Sopenharmony_ci *pPropertyCount = 0; 993bf215546Sopenharmony_ci} 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 996bf215546Sopenharmony_cidzn_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice, 997bf215546Sopenharmony_ci const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 998bf215546Sopenharmony_ci VkExternalBufferProperties *pExternalBufferProperties) 999bf215546Sopenharmony_ci{ 1000bf215546Sopenharmony_ci pExternalBufferProperties->externalMemoryProperties = 1001bf215546Sopenharmony_ci (VkExternalMemoryProperties) { 1002bf215546Sopenharmony_ci .compatibleHandleTypes = (VkExternalMemoryHandleTypeFlags)pExternalBufferInfo->handleType, 1003bf215546Sopenharmony_ci }; 1004bf215546Sopenharmony_ci} 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_ciVkResult 1007bf215546Sopenharmony_cidzn_instance_add_physical_device(struct dzn_instance *instance, 1008bf215546Sopenharmony_ci IUnknown *adapter, 1009bf215546Sopenharmony_ci const struct dzn_physical_device_desc *desc) 1010bf215546Sopenharmony_ci{ 1011bf215546Sopenharmony_ci if ((instance->debug_flags & DZN_DEBUG_WARP) && 1012bf215546Sopenharmony_ci !desc->is_warp) 1013bf215546Sopenharmony_ci return VK_SUCCESS; 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci return dzn_physical_device_create(instance, adapter, desc); 1016bf215546Sopenharmony_ci} 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1019bf215546Sopenharmony_cidzn_EnumeratePhysicalDevices(VkInstance inst, 1020bf215546Sopenharmony_ci uint32_t *pPhysicalDeviceCount, 1021bf215546Sopenharmony_ci VkPhysicalDevice *pPhysicalDevices) 1022bf215546Sopenharmony_ci{ 1023bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_instance, instance, inst); 1024bf215546Sopenharmony_ci 1025bf215546Sopenharmony_ci if (!instance->physical_devices_enumerated) { 1026bf215546Sopenharmony_ci VkResult result = dzn_enumerate_physical_devices_dxcore(instance); 1027bf215546Sopenharmony_ci#ifdef _WIN32 1028bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1029bf215546Sopenharmony_ci result = dzn_enumerate_physical_devices_dxgi(instance); 1030bf215546Sopenharmony_ci#endif 1031bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1032bf215546Sopenharmony_ci return result; 1033bf215546Sopenharmony_ci } 1034bf215546Sopenharmony_ci 1035bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out, pPhysicalDevices, 1036bf215546Sopenharmony_ci pPhysicalDeviceCount); 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci list_for_each_entry(struct dzn_physical_device, pdev, &instance->physical_devices, link) { 1039bf215546Sopenharmony_ci vk_outarray_append_typed(VkPhysicalDevice, &out, i) 1040bf215546Sopenharmony_ci *i = dzn_physical_device_to_handle(pdev); 1041bf215546Sopenharmony_ci } 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci instance->physical_devices_enumerated = true; 1044bf215546Sopenharmony_ci return vk_outarray_status(&out); 1045bf215546Sopenharmony_ci} 1046bf215546Sopenharmony_ci 1047bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1048bf215546Sopenharmony_cidzn_EnumerateInstanceVersion(uint32_t *pApiVersion) 1049bf215546Sopenharmony_ci{ 1050bf215546Sopenharmony_ci *pApiVersion = DZN_API_VERSION; 1051bf215546Sopenharmony_ci return VK_SUCCESS; 1052bf215546Sopenharmony_ci} 1053bf215546Sopenharmony_ci 1054bf215546Sopenharmony_cistatic bool 1055bf215546Sopenharmony_cidzn_physical_device_supports_compressed_format(struct dzn_physical_device *pdev, 1056bf215546Sopenharmony_ci const VkFormat *formats, 1057bf215546Sopenharmony_ci uint32_t format_count) 1058bf215546Sopenharmony_ci{ 1059bf215546Sopenharmony_ci#define REQUIRED_COMPRESSED_CAPS \ 1060bf215546Sopenharmony_ci (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | \ 1061bf215546Sopenharmony_ci VK_FORMAT_FEATURE_BLIT_SRC_BIT | \ 1062bf215546Sopenharmony_ci VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) 1063bf215546Sopenharmony_ci for (uint32_t i = 0; i < format_count; i++) { 1064bf215546Sopenharmony_ci VkFormatProperties2 props = { 0 }; 1065bf215546Sopenharmony_ci dzn_physical_device_get_format_properties(pdev, formats[i], &props); 1066bf215546Sopenharmony_ci if ((props.formatProperties.optimalTilingFeatures & REQUIRED_COMPRESSED_CAPS) != REQUIRED_COMPRESSED_CAPS) 1067bf215546Sopenharmony_ci return false; 1068bf215546Sopenharmony_ci } 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_ci return true; 1071bf215546Sopenharmony_ci} 1072bf215546Sopenharmony_ci 1073bf215546Sopenharmony_cistatic bool 1074bf215546Sopenharmony_cidzn_physical_device_supports_bc(struct dzn_physical_device *pdev) 1075bf215546Sopenharmony_ci{ 1076bf215546Sopenharmony_ci static const VkFormat formats[] = { 1077bf215546Sopenharmony_ci VK_FORMAT_BC1_RGB_UNORM_BLOCK, 1078bf215546Sopenharmony_ci VK_FORMAT_BC1_RGB_SRGB_BLOCK, 1079bf215546Sopenharmony_ci VK_FORMAT_BC1_RGBA_UNORM_BLOCK, 1080bf215546Sopenharmony_ci VK_FORMAT_BC1_RGBA_SRGB_BLOCK, 1081bf215546Sopenharmony_ci VK_FORMAT_BC2_UNORM_BLOCK, 1082bf215546Sopenharmony_ci VK_FORMAT_BC2_SRGB_BLOCK, 1083bf215546Sopenharmony_ci VK_FORMAT_BC3_UNORM_BLOCK, 1084bf215546Sopenharmony_ci VK_FORMAT_BC3_SRGB_BLOCK, 1085bf215546Sopenharmony_ci VK_FORMAT_BC4_UNORM_BLOCK, 1086bf215546Sopenharmony_ci VK_FORMAT_BC4_SNORM_BLOCK, 1087bf215546Sopenharmony_ci VK_FORMAT_BC5_UNORM_BLOCK, 1088bf215546Sopenharmony_ci VK_FORMAT_BC5_SNORM_BLOCK, 1089bf215546Sopenharmony_ci VK_FORMAT_BC6H_UFLOAT_BLOCK, 1090bf215546Sopenharmony_ci VK_FORMAT_BC6H_SFLOAT_BLOCK, 1091bf215546Sopenharmony_ci VK_FORMAT_BC7_UNORM_BLOCK, 1092bf215546Sopenharmony_ci VK_FORMAT_BC7_SRGB_BLOCK, 1093bf215546Sopenharmony_ci }; 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci return dzn_physical_device_supports_compressed_format(pdev, formats, ARRAY_SIZE(formats)); 1096bf215546Sopenharmony_ci} 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_cistatic bool 1099bf215546Sopenharmony_cidzn_physical_device_supports_depth_bounds(struct dzn_physical_device *pdev) 1100bf215546Sopenharmony_ci{ 1101bf215546Sopenharmony_ci dzn_physical_device_get_d3d12_dev(pdev); 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci return pdev->options2.DepthBoundsTestSupported; 1104bf215546Sopenharmony_ci} 1105bf215546Sopenharmony_ci 1106bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1107bf215546Sopenharmony_cidzn_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, 1108bf215546Sopenharmony_ci VkPhysicalDeviceFeatures2 *pFeatures) 1109bf215546Sopenharmony_ci{ 1110bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_ci pFeatures->features = (VkPhysicalDeviceFeatures) { 1113bf215546Sopenharmony_ci .robustBufferAccess = true, /* This feature is mandatory */ 1114bf215546Sopenharmony_ci .fullDrawIndexUint32 = false, 1115bf215546Sopenharmony_ci .imageCubeArray = true, 1116bf215546Sopenharmony_ci .independentBlend = false, 1117bf215546Sopenharmony_ci .geometryShader = true, 1118bf215546Sopenharmony_ci .tessellationShader = false, 1119bf215546Sopenharmony_ci .sampleRateShading = true, 1120bf215546Sopenharmony_ci .dualSrcBlend = false, 1121bf215546Sopenharmony_ci .logicOp = false, 1122bf215546Sopenharmony_ci .multiDrawIndirect = true, 1123bf215546Sopenharmony_ci .drawIndirectFirstInstance = true, 1124bf215546Sopenharmony_ci .depthClamp = true, 1125bf215546Sopenharmony_ci .depthBiasClamp = true, 1126bf215546Sopenharmony_ci .fillModeNonSolid = false, 1127bf215546Sopenharmony_ci .depthBounds = dzn_physical_device_supports_depth_bounds(pdev), 1128bf215546Sopenharmony_ci .wideLines = false, 1129bf215546Sopenharmony_ci .largePoints = false, 1130bf215546Sopenharmony_ci .alphaToOne = false, 1131bf215546Sopenharmony_ci .multiViewport = false, 1132bf215546Sopenharmony_ci .samplerAnisotropy = true, 1133bf215546Sopenharmony_ci .textureCompressionETC2 = false, 1134bf215546Sopenharmony_ci .textureCompressionASTC_LDR = false, 1135bf215546Sopenharmony_ci .textureCompressionBC = dzn_physical_device_supports_bc(pdev), 1136bf215546Sopenharmony_ci .occlusionQueryPrecise = true, 1137bf215546Sopenharmony_ci .pipelineStatisticsQuery = true, 1138bf215546Sopenharmony_ci .vertexPipelineStoresAndAtomics = true, 1139bf215546Sopenharmony_ci .fragmentStoresAndAtomics = true, 1140bf215546Sopenharmony_ci .shaderTessellationAndGeometryPointSize = false, 1141bf215546Sopenharmony_ci .shaderImageGatherExtended = true, 1142bf215546Sopenharmony_ci .shaderStorageImageExtendedFormats = false, 1143bf215546Sopenharmony_ci .shaderStorageImageMultisample = false, 1144bf215546Sopenharmony_ci .shaderStorageImageReadWithoutFormat = false, 1145bf215546Sopenharmony_ci .shaderStorageImageWriteWithoutFormat = false, 1146bf215546Sopenharmony_ci .shaderUniformBufferArrayDynamicIndexing = true, 1147bf215546Sopenharmony_ci .shaderSampledImageArrayDynamicIndexing = true, 1148bf215546Sopenharmony_ci .shaderStorageBufferArrayDynamicIndexing = true, 1149bf215546Sopenharmony_ci .shaderStorageImageArrayDynamicIndexing = true, 1150bf215546Sopenharmony_ci .shaderClipDistance = true, 1151bf215546Sopenharmony_ci .shaderCullDistance = true, 1152bf215546Sopenharmony_ci .shaderFloat64 = false, 1153bf215546Sopenharmony_ci .shaderInt64 = false, 1154bf215546Sopenharmony_ci .shaderInt16 = false, 1155bf215546Sopenharmony_ci .shaderResourceResidency = false, 1156bf215546Sopenharmony_ci .shaderResourceMinLod = false, 1157bf215546Sopenharmony_ci .sparseBinding = false, 1158bf215546Sopenharmony_ci .sparseResidencyBuffer = false, 1159bf215546Sopenharmony_ci .sparseResidencyImage2D = false, 1160bf215546Sopenharmony_ci .sparseResidencyImage3D = false, 1161bf215546Sopenharmony_ci .sparseResidency2Samples = false, 1162bf215546Sopenharmony_ci .sparseResidency4Samples = false, 1163bf215546Sopenharmony_ci .sparseResidency8Samples = false, 1164bf215546Sopenharmony_ci .sparseResidency16Samples = false, 1165bf215546Sopenharmony_ci .sparseResidencyAliased = false, 1166bf215546Sopenharmony_ci .variableMultisampleRate = false, 1167bf215546Sopenharmony_ci .inheritedQueries = false, 1168bf215546Sopenharmony_ci }; 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci VkPhysicalDeviceVulkan11Features core_1_1 = { 1171bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, 1172bf215546Sopenharmony_ci .storageBuffer16BitAccess = false, 1173bf215546Sopenharmony_ci .uniformAndStorageBuffer16BitAccess = false, 1174bf215546Sopenharmony_ci .storagePushConstant16 = false, 1175bf215546Sopenharmony_ci .storageInputOutput16 = false, 1176bf215546Sopenharmony_ci .multiview = false, 1177bf215546Sopenharmony_ci .multiviewGeometryShader = false, 1178bf215546Sopenharmony_ci .multiviewTessellationShader = false, 1179bf215546Sopenharmony_ci .variablePointersStorageBuffer = true, 1180bf215546Sopenharmony_ci .variablePointers = true, 1181bf215546Sopenharmony_ci .protectedMemory = false, 1182bf215546Sopenharmony_ci .samplerYcbcrConversion = false, 1183bf215546Sopenharmony_ci .shaderDrawParameters = true, 1184bf215546Sopenharmony_ci }; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci const VkPhysicalDeviceVulkan12Features core_1_2 = { 1187bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, 1188bf215546Sopenharmony_ci .samplerMirrorClampToEdge = false, 1189bf215546Sopenharmony_ci .drawIndirectCount = false, 1190bf215546Sopenharmony_ci .storageBuffer8BitAccess = false, 1191bf215546Sopenharmony_ci .uniformAndStorageBuffer8BitAccess = false, 1192bf215546Sopenharmony_ci .storagePushConstant8 = false, 1193bf215546Sopenharmony_ci .shaderBufferInt64Atomics = false, 1194bf215546Sopenharmony_ci .shaderSharedInt64Atomics = false, 1195bf215546Sopenharmony_ci .shaderFloat16 = false, 1196bf215546Sopenharmony_ci .shaderInt8 = false, 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci .descriptorIndexing = false, 1199bf215546Sopenharmony_ci .shaderInputAttachmentArrayDynamicIndexing = true, 1200bf215546Sopenharmony_ci .shaderUniformTexelBufferArrayDynamicIndexing = true, 1201bf215546Sopenharmony_ci .shaderStorageTexelBufferArrayDynamicIndexing = true, 1202bf215546Sopenharmony_ci .shaderUniformBufferArrayNonUniformIndexing = false, 1203bf215546Sopenharmony_ci .shaderSampledImageArrayNonUniformIndexing = false, 1204bf215546Sopenharmony_ci .shaderStorageBufferArrayNonUniformIndexing = false, 1205bf215546Sopenharmony_ci .shaderStorageImageArrayNonUniformIndexing = false, 1206bf215546Sopenharmony_ci .shaderInputAttachmentArrayNonUniformIndexing = false, 1207bf215546Sopenharmony_ci .shaderUniformTexelBufferArrayNonUniformIndexing = false, 1208bf215546Sopenharmony_ci .shaderStorageTexelBufferArrayNonUniformIndexing = false, 1209bf215546Sopenharmony_ci .descriptorBindingUniformBufferUpdateAfterBind = false, 1210bf215546Sopenharmony_ci .descriptorBindingSampledImageUpdateAfterBind = false, 1211bf215546Sopenharmony_ci .descriptorBindingStorageImageUpdateAfterBind = false, 1212bf215546Sopenharmony_ci .descriptorBindingStorageBufferUpdateAfterBind = false, 1213bf215546Sopenharmony_ci .descriptorBindingUniformTexelBufferUpdateAfterBind = false, 1214bf215546Sopenharmony_ci .descriptorBindingStorageTexelBufferUpdateAfterBind = false, 1215bf215546Sopenharmony_ci .descriptorBindingUpdateUnusedWhilePending = false, 1216bf215546Sopenharmony_ci .descriptorBindingPartiallyBound = false, 1217bf215546Sopenharmony_ci .descriptorBindingVariableDescriptorCount = false, 1218bf215546Sopenharmony_ci .runtimeDescriptorArray = false, 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci .samplerFilterMinmax = false, 1221bf215546Sopenharmony_ci .scalarBlockLayout = false, 1222bf215546Sopenharmony_ci .imagelessFramebuffer = false, 1223bf215546Sopenharmony_ci .uniformBufferStandardLayout = false, 1224bf215546Sopenharmony_ci .shaderSubgroupExtendedTypes = false, 1225bf215546Sopenharmony_ci .separateDepthStencilLayouts = false, 1226bf215546Sopenharmony_ci .hostQueryReset = false, 1227bf215546Sopenharmony_ci .timelineSemaphore = false, 1228bf215546Sopenharmony_ci .bufferDeviceAddress = false, 1229bf215546Sopenharmony_ci .bufferDeviceAddressCaptureReplay = false, 1230bf215546Sopenharmony_ci .bufferDeviceAddressMultiDevice = false, 1231bf215546Sopenharmony_ci .vulkanMemoryModel = false, 1232bf215546Sopenharmony_ci .vulkanMemoryModelDeviceScope = false, 1233bf215546Sopenharmony_ci .vulkanMemoryModelAvailabilityVisibilityChains = false, 1234bf215546Sopenharmony_ci .shaderOutputViewportIndex = false, 1235bf215546Sopenharmony_ci .shaderOutputLayer = false, 1236bf215546Sopenharmony_ci .subgroupBroadcastDynamicId = false, 1237bf215546Sopenharmony_ci }; 1238bf215546Sopenharmony_ci 1239bf215546Sopenharmony_ci const VkPhysicalDeviceVulkan13Features core_1_3 = { 1240bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, 1241bf215546Sopenharmony_ci .robustImageAccess = false, 1242bf215546Sopenharmony_ci .inlineUniformBlock = false, 1243bf215546Sopenharmony_ci .descriptorBindingInlineUniformBlockUpdateAfterBind = false, 1244bf215546Sopenharmony_ci .pipelineCreationCacheControl = false, 1245bf215546Sopenharmony_ci .privateData = true, 1246bf215546Sopenharmony_ci .shaderDemoteToHelperInvocation = false, 1247bf215546Sopenharmony_ci .shaderTerminateInvocation = false, 1248bf215546Sopenharmony_ci .subgroupSizeControl = false, 1249bf215546Sopenharmony_ci .computeFullSubgroups = false, 1250bf215546Sopenharmony_ci .synchronization2 = true, 1251bf215546Sopenharmony_ci .textureCompressionASTC_HDR = false, 1252bf215546Sopenharmony_ci .shaderZeroInitializeWorkgroupMemory = false, 1253bf215546Sopenharmony_ci .dynamicRendering = false, 1254bf215546Sopenharmony_ci .shaderIntegerDotProduct = false, 1255bf215546Sopenharmony_ci .maintenance4 = false, 1256bf215546Sopenharmony_ci }; 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci vk_foreach_struct(ext, pFeatures->pNext) { 1259bf215546Sopenharmony_ci if (vk_get_physical_device_core_1_1_feature_ext(ext, &core_1_1) || 1260bf215546Sopenharmony_ci vk_get_physical_device_core_1_2_feature_ext(ext, &core_1_2) || 1261bf215546Sopenharmony_ci vk_get_physical_device_core_1_3_feature_ext(ext, &core_1_3)) 1262bf215546Sopenharmony_ci continue; 1263bf215546Sopenharmony_ci 1264bf215546Sopenharmony_ci switch (ext->sType) { 1265bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { 1266bf215546Sopenharmony_ci VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features = 1267bf215546Sopenharmony_ci (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext; 1268bf215546Sopenharmony_ci features->vertexAttributeInstanceRateDivisor = true; 1269bf215546Sopenharmony_ci features->vertexAttributeInstanceRateZeroDivisor = true; 1270bf215546Sopenharmony_ci break; 1271bf215546Sopenharmony_ci } 1272bf215546Sopenharmony_ci default: 1273bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 1274bf215546Sopenharmony_ci break; 1275bf215546Sopenharmony_ci } 1276bf215546Sopenharmony_ci } 1277bf215546Sopenharmony_ci} 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 1281bf215546Sopenharmony_cidzn_GetInstanceProcAddr(VkInstance _instance, 1282bf215546Sopenharmony_ci const char *pName) 1283bf215546Sopenharmony_ci{ 1284bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_instance, instance, _instance); 1285bf215546Sopenharmony_ci return vk_instance_get_proc_addr(&instance->vk, 1286bf215546Sopenharmony_ci &dzn_instance_entrypoints, 1287bf215546Sopenharmony_ci pName); 1288bf215546Sopenharmony_ci} 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci/* Windows will use a dll definition file to avoid build errors. */ 1291bf215546Sopenharmony_ci#ifdef _WIN32 1292bf215546Sopenharmony_ci#undef PUBLIC 1293bf215546Sopenharmony_ci#define PUBLIC 1294bf215546Sopenharmony_ci#endif 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci/* With version 1+ of the loader interface the ICD should expose 1297bf215546Sopenharmony_ci * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps. 1298bf215546Sopenharmony_ci */ 1299bf215546Sopenharmony_ciPUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 1300bf215546Sopenharmony_civk_icdGetInstanceProcAddr(VkInstance instance, 1301bf215546Sopenharmony_ci const char *pName); 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ciPUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 1304bf215546Sopenharmony_civk_icdGetInstanceProcAddr(VkInstance instance, 1305bf215546Sopenharmony_ci const char *pName) 1306bf215546Sopenharmony_ci{ 1307bf215546Sopenharmony_ci return dzn_GetInstanceProcAddr(instance, pName); 1308bf215546Sopenharmony_ci} 1309bf215546Sopenharmony_ci 1310bf215546Sopenharmony_ci/* With version 4+ of the loader interface the ICD should expose 1311bf215546Sopenharmony_ci * vk_icdGetPhysicalDeviceProcAddr() 1312bf215546Sopenharmony_ci */ 1313bf215546Sopenharmony_ciPUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 1314bf215546Sopenharmony_civk_icdGetPhysicalDeviceProcAddr(VkInstance _instance, 1315bf215546Sopenharmony_ci const char *pName); 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ciVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL 1318bf215546Sopenharmony_civk_icdGetPhysicalDeviceProcAddr(VkInstance _instance, 1319bf215546Sopenharmony_ci const char *pName) 1320bf215546Sopenharmony_ci{ 1321bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_instance, instance, _instance); 1322bf215546Sopenharmony_ci return vk_instance_get_physical_device_proc_addr(&instance->vk, pName); 1323bf215546Sopenharmony_ci} 1324bf215546Sopenharmony_ci 1325bf215546Sopenharmony_ci/* vk_icd.h does not declare this function, so we declare it here to 1326bf215546Sopenharmony_ci * suppress Wmissing-prototypes. 1327bf215546Sopenharmony_ci */ 1328bf215546Sopenharmony_ciPUBLIC VKAPI_ATTR VkResult VKAPI_CALL 1329bf215546Sopenharmony_civk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion); 1330bf215546Sopenharmony_ci 1331bf215546Sopenharmony_ciPUBLIC VKAPI_ATTR VkResult VKAPI_CALL 1332bf215546Sopenharmony_civk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion) 1333bf215546Sopenharmony_ci{ 1334bf215546Sopenharmony_ci /* For the full details on loader interface versioning, see 1335bf215546Sopenharmony_ci * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>. 1336bf215546Sopenharmony_ci * What follows is a condensed summary, to help you navigate the large and 1337bf215546Sopenharmony_ci * confusing official doc. 1338bf215546Sopenharmony_ci * 1339bf215546Sopenharmony_ci * - Loader interface v0 is incompatible with later versions. We don't 1340bf215546Sopenharmony_ci * support it. 1341bf215546Sopenharmony_ci * 1342bf215546Sopenharmony_ci * - In loader interface v1: 1343bf215546Sopenharmony_ci * - The first ICD entrypoint called by the loader is 1344bf215546Sopenharmony_ci * vk_icdGetInstanceProcAddr(). The ICD must statically expose this 1345bf215546Sopenharmony_ci * entrypoint. 1346bf215546Sopenharmony_ci * - The ICD must statically expose no other Vulkan symbol unless it is 1347bf215546Sopenharmony_ci * linked with -Bsymbolic. 1348bf215546Sopenharmony_ci * - Each dispatchable Vulkan handle created by the ICD must be 1349bf215546Sopenharmony_ci * a pointer to a struct whose first member is VK_LOADER_DATA. The 1350bf215546Sopenharmony_ci * ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC. 1351bf215546Sopenharmony_ci * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and 1352bf215546Sopenharmony_ci * vkDestroySurfaceKHR(). The ICD must be capable of working with 1353bf215546Sopenharmony_ci * such loader-managed surfaces. 1354bf215546Sopenharmony_ci * 1355bf215546Sopenharmony_ci * - Loader interface v2 differs from v1 in: 1356bf215546Sopenharmony_ci * - The first ICD entrypoint called by the loader is 1357bf215546Sopenharmony_ci * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must 1358bf215546Sopenharmony_ci * statically expose this entrypoint. 1359bf215546Sopenharmony_ci * 1360bf215546Sopenharmony_ci * - Loader interface v3 differs from v2 in: 1361bf215546Sopenharmony_ci * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(), 1362bf215546Sopenharmony_ci * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR, 1363bf215546Sopenharmony_ci * because the loader no longer does so. 1364bf215546Sopenharmony_ci * 1365bf215546Sopenharmony_ci * - Loader interface v4 differs from v3 in: 1366bf215546Sopenharmony_ci * - The ICD must implement vk_icdGetPhysicalDeviceProcAddr(). 1367bf215546Sopenharmony_ci * 1368bf215546Sopenharmony_ci * - Loader interface v5 differs from v4 in: 1369bf215546Sopenharmony_ci * - The ICD must support Vulkan API version 1.1 and must not return 1370bf215546Sopenharmony_ci * VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a 1371bf215546Sopenharmony_ci * Vulkan Loader with interface v4 or smaller is being used and the 1372bf215546Sopenharmony_ci * application provides an API version that is greater than 1.0. 1373bf215546Sopenharmony_ci */ 1374bf215546Sopenharmony_ci *pSupportedVersion = MIN2(*pSupportedVersion, 5u); 1375bf215546Sopenharmony_ci return VK_SUCCESS; 1376bf215546Sopenharmony_ci} 1377bf215546Sopenharmony_ci 1378bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1379bf215546Sopenharmony_cidzn_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, 1380bf215546Sopenharmony_ci VkPhysicalDeviceProperties2 *pProperties) 1381bf215546Sopenharmony_ci{ 1382bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdevice, physicalDevice); 1383bf215546Sopenharmony_ci 1384bf215546Sopenharmony_ci (void)dzn_physical_device_get_d3d12_dev(pdevice); 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_ci /* minimum from the spec */ 1387bf215546Sopenharmony_ci const VkSampleCountFlags supported_sample_counts = 1388bf215546Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | 1389bf215546Sopenharmony_ci VK_SAMPLE_COUNT_8_BIT | VK_SAMPLE_COUNT_16_BIT; 1390bf215546Sopenharmony_ci 1391bf215546Sopenharmony_ci /* FIXME: this is mostly bunk for now */ 1392bf215546Sopenharmony_ci VkPhysicalDeviceLimits limits = { 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_ci /* TODO: support older feature levels */ 1395bf215546Sopenharmony_ci .maxImageDimension1D = (1 << 14), 1396bf215546Sopenharmony_ci .maxImageDimension2D = (1 << 14), 1397bf215546Sopenharmony_ci .maxImageDimension3D = (1 << 11), 1398bf215546Sopenharmony_ci .maxImageDimensionCube = (1 << 14), 1399bf215546Sopenharmony_ci .maxImageArrayLayers = (1 << 11), 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci /* from here on, we simply use the minimum values from the spec for now */ 1402bf215546Sopenharmony_ci .maxTexelBufferElements = 65536, 1403bf215546Sopenharmony_ci .maxUniformBufferRange = 16384, 1404bf215546Sopenharmony_ci .maxStorageBufferRange = (1ul << 27), 1405bf215546Sopenharmony_ci .maxPushConstantsSize = 128, 1406bf215546Sopenharmony_ci .maxMemoryAllocationCount = 4096, 1407bf215546Sopenharmony_ci .maxSamplerAllocationCount = 4000, 1408bf215546Sopenharmony_ci .bufferImageGranularity = 131072, 1409bf215546Sopenharmony_ci .sparseAddressSpaceSize = 0, 1410bf215546Sopenharmony_ci .maxBoundDescriptorSets = MAX_SETS, 1411bf215546Sopenharmony_ci .maxPerStageDescriptorSamplers = 1412bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier == D3D12_RESOURCE_HEAP_TIER_1 ? 1413bf215546Sopenharmony_ci 16u : MAX_DESCS_PER_SAMPLER_HEAP, 1414bf215546Sopenharmony_ci .maxPerStageDescriptorUniformBuffers = 1415bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier <= D3D12_RESOURCE_HEAP_TIER_2 ? 1416bf215546Sopenharmony_ci 14u : MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1417bf215546Sopenharmony_ci .maxPerStageDescriptorStorageBuffers = 1418bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier <= D3D12_RESOURCE_HEAP_TIER_2 ? 1419bf215546Sopenharmony_ci 64u : MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1420bf215546Sopenharmony_ci .maxPerStageDescriptorSampledImages = 1421bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier == D3D12_RESOURCE_HEAP_TIER_1 ? 1422bf215546Sopenharmony_ci 128u : MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1423bf215546Sopenharmony_ci .maxPerStageDescriptorStorageImages = 1424bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier <= D3D12_RESOURCE_HEAP_TIER_2 ? 1425bf215546Sopenharmony_ci 64u : MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1426bf215546Sopenharmony_ci .maxPerStageDescriptorInputAttachments = 1427bf215546Sopenharmony_ci pdevice->options.ResourceHeapTier == D3D12_RESOURCE_HEAP_TIER_1 ? 1428bf215546Sopenharmony_ci 128u : MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1429bf215546Sopenharmony_ci .maxPerStageResources = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1430bf215546Sopenharmony_ci .maxDescriptorSetSamplers = MAX_DESCS_PER_SAMPLER_HEAP, 1431bf215546Sopenharmony_ci .maxDescriptorSetUniformBuffers = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1432bf215546Sopenharmony_ci .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS, 1433bf215546Sopenharmony_ci .maxDescriptorSetStorageBuffers = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1434bf215546Sopenharmony_ci .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS, 1435bf215546Sopenharmony_ci .maxDescriptorSetSampledImages = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1436bf215546Sopenharmony_ci .maxDescriptorSetStorageImages = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1437bf215546Sopenharmony_ci .maxDescriptorSetInputAttachments = MAX_DESCS_PER_CBV_SRV_UAV_HEAP, 1438bf215546Sopenharmony_ci .maxVertexInputAttributes = MIN2(D3D12_STANDARD_VERTEX_ELEMENT_COUNT, MAX_VERTEX_GENERIC_ATTRIBS), 1439bf215546Sopenharmony_ci .maxVertexInputBindings = MAX_VBS, 1440bf215546Sopenharmony_ci .maxVertexInputAttributeOffset = 2047, 1441bf215546Sopenharmony_ci .maxVertexInputBindingStride = 2048, 1442bf215546Sopenharmony_ci .maxVertexOutputComponents = 64, 1443bf215546Sopenharmony_ci .maxTessellationGenerationLevel = 0, 1444bf215546Sopenharmony_ci .maxTessellationPatchSize = 0, 1445bf215546Sopenharmony_ci .maxTessellationControlPerVertexInputComponents = 0, 1446bf215546Sopenharmony_ci .maxTessellationControlPerVertexOutputComponents = 0, 1447bf215546Sopenharmony_ci .maxTessellationControlPerPatchOutputComponents = 0, 1448bf215546Sopenharmony_ci .maxTessellationControlTotalOutputComponents = 0, 1449bf215546Sopenharmony_ci .maxTessellationEvaluationInputComponents = 0, 1450bf215546Sopenharmony_ci .maxTessellationEvaluationOutputComponents = 0, 1451bf215546Sopenharmony_ci .maxGeometryShaderInvocations = 0, 1452bf215546Sopenharmony_ci .maxGeometryInputComponents = 0, 1453bf215546Sopenharmony_ci .maxGeometryOutputComponents = 0, 1454bf215546Sopenharmony_ci .maxGeometryOutputVertices = 0, 1455bf215546Sopenharmony_ci .maxGeometryTotalOutputComponents = 0, 1456bf215546Sopenharmony_ci .maxFragmentInputComponents = 64, 1457bf215546Sopenharmony_ci .maxFragmentOutputAttachments = 4, 1458bf215546Sopenharmony_ci .maxFragmentDualSrcAttachments = 0, 1459bf215546Sopenharmony_ci .maxFragmentCombinedOutputResources = 4, 1460bf215546Sopenharmony_ci .maxComputeSharedMemorySize = 16384, 1461bf215546Sopenharmony_ci .maxComputeWorkGroupCount = { 65535, 65535, 65535 }, 1462bf215546Sopenharmony_ci .maxComputeWorkGroupInvocations = 128, 1463bf215546Sopenharmony_ci .maxComputeWorkGroupSize = { 128, 128, 64 }, 1464bf215546Sopenharmony_ci .subPixelPrecisionBits = 4, 1465bf215546Sopenharmony_ci .subTexelPrecisionBits = 4, 1466bf215546Sopenharmony_ci .mipmapPrecisionBits = 4, 1467bf215546Sopenharmony_ci .maxDrawIndexedIndexValue = 0x00ffffff, 1468bf215546Sopenharmony_ci .maxDrawIndirectCount = UINT32_MAX, 1469bf215546Sopenharmony_ci .maxSamplerLodBias = 2.0f, 1470bf215546Sopenharmony_ci .maxSamplerAnisotropy = 1.0f, 1471bf215546Sopenharmony_ci .maxViewports = 1, 1472bf215546Sopenharmony_ci .maxViewportDimensions = { 4096, 4096 }, 1473bf215546Sopenharmony_ci .viewportBoundsRange = { -8192, 8191 }, 1474bf215546Sopenharmony_ci .viewportSubPixelBits = 0, 1475bf215546Sopenharmony_ci .minMemoryMapAlignment = 64, 1476bf215546Sopenharmony_ci .minTexelBufferOffsetAlignment = 256, 1477bf215546Sopenharmony_ci .minUniformBufferOffsetAlignment = 256, 1478bf215546Sopenharmony_ci .minStorageBufferOffsetAlignment = 256, 1479bf215546Sopenharmony_ci .minTexelOffset = -8, 1480bf215546Sopenharmony_ci .maxTexelOffset = 7, 1481bf215546Sopenharmony_ci .minTexelGatherOffset = 0, 1482bf215546Sopenharmony_ci .maxTexelGatherOffset = 0, 1483bf215546Sopenharmony_ci .minInterpolationOffset = -0.5f, 1484bf215546Sopenharmony_ci .maxInterpolationOffset = 0.5f, 1485bf215546Sopenharmony_ci .subPixelInterpolationOffsetBits = 4, 1486bf215546Sopenharmony_ci .maxFramebufferWidth = 4096, 1487bf215546Sopenharmony_ci .maxFramebufferHeight = 4096, 1488bf215546Sopenharmony_ci .maxFramebufferLayers = 256, 1489bf215546Sopenharmony_ci .framebufferColorSampleCounts = supported_sample_counts, 1490bf215546Sopenharmony_ci .framebufferDepthSampleCounts = supported_sample_counts, 1491bf215546Sopenharmony_ci .framebufferStencilSampleCounts = supported_sample_counts, 1492bf215546Sopenharmony_ci .framebufferNoAttachmentsSampleCounts = supported_sample_counts, 1493bf215546Sopenharmony_ci .maxColorAttachments = MAX_RTS, 1494bf215546Sopenharmony_ci .sampledImageColorSampleCounts = supported_sample_counts, 1495bf215546Sopenharmony_ci .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT, 1496bf215546Sopenharmony_ci .sampledImageDepthSampleCounts = supported_sample_counts, 1497bf215546Sopenharmony_ci .sampledImageStencilSampleCounts = supported_sample_counts, 1498bf215546Sopenharmony_ci .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT, 1499bf215546Sopenharmony_ci .maxSampleMaskWords = 1, 1500bf215546Sopenharmony_ci .timestampComputeAndGraphics = true, 1501bf215546Sopenharmony_ci .timestampPeriod = pdevice->timestamp_period, 1502bf215546Sopenharmony_ci .maxClipDistances = 8, 1503bf215546Sopenharmony_ci .maxCullDistances = 8, 1504bf215546Sopenharmony_ci .maxCombinedClipAndCullDistances = 8, 1505bf215546Sopenharmony_ci .discreteQueuePriorities = 2, 1506bf215546Sopenharmony_ci .pointSizeRange = { 1.0f, 1.0f }, 1507bf215546Sopenharmony_ci .lineWidthRange = { 1.0f, 1.0f }, 1508bf215546Sopenharmony_ci .pointSizeGranularity = 0.0f, 1509bf215546Sopenharmony_ci .lineWidthGranularity = 0.0f, 1510bf215546Sopenharmony_ci .strictLines = 0, 1511bf215546Sopenharmony_ci .standardSampleLocations = false, 1512bf215546Sopenharmony_ci .optimalBufferCopyOffsetAlignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT, 1513bf215546Sopenharmony_ci .optimalBufferCopyRowPitchAlignment = D3D12_TEXTURE_DATA_PITCH_ALIGNMENT, 1514bf215546Sopenharmony_ci .nonCoherentAtomSize = 256, 1515bf215546Sopenharmony_ci }; 1516bf215546Sopenharmony_ci 1517bf215546Sopenharmony_ci VkPhysicalDeviceType devtype = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; 1518bf215546Sopenharmony_ci if (pdevice->desc.is_warp) 1519bf215546Sopenharmony_ci devtype = VK_PHYSICAL_DEVICE_TYPE_CPU; 1520bf215546Sopenharmony_ci else if (false) { // TODO: detect discreete GPUs 1521bf215546Sopenharmony_ci /* This is a tad tricky to get right, because we need to have the 1522bf215546Sopenharmony_ci * actual ID3D12Device before we can query the 1523bf215546Sopenharmony_ci * D3D12_FEATURE_DATA_ARCHITECTURE structure... So for now, let's 1524bf215546Sopenharmony_ci * just pretend everything is integrated, because... well, that's 1525bf215546Sopenharmony_ci * what I have at hand right now ;) 1526bf215546Sopenharmony_ci */ 1527bf215546Sopenharmony_ci devtype = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; 1528bf215546Sopenharmony_ci } 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci pProperties->properties = (VkPhysicalDeviceProperties) { 1531bf215546Sopenharmony_ci .apiVersion = DZN_API_VERSION, 1532bf215546Sopenharmony_ci .driverVersion = vk_get_driver_version(), 1533bf215546Sopenharmony_ci 1534bf215546Sopenharmony_ci .vendorID = pdevice->desc.vendor_id, 1535bf215546Sopenharmony_ci .deviceID = pdevice->desc.device_id, 1536bf215546Sopenharmony_ci .deviceType = devtype, 1537bf215546Sopenharmony_ci 1538bf215546Sopenharmony_ci .limits = limits, 1539bf215546Sopenharmony_ci .sparseProperties = { 0 }, 1540bf215546Sopenharmony_ci }; 1541bf215546Sopenharmony_ci 1542bf215546Sopenharmony_ci snprintf(pProperties->properties.deviceName, 1543bf215546Sopenharmony_ci sizeof(pProperties->properties.deviceName), 1544bf215546Sopenharmony_ci "Microsoft Direct3D12 (%s)", pdevice->desc.description); 1545bf215546Sopenharmony_ci memcpy(pProperties->properties.pipelineCacheUUID, 1546bf215546Sopenharmony_ci pdevice->pipeline_cache_uuid, VK_UUID_SIZE); 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_ci VkPhysicalDeviceVulkan11Properties core_1_1 = { 1549bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, 1550bf215546Sopenharmony_ci .deviceLUIDValid = true, 1551bf215546Sopenharmony_ci .pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, 1552bf215546Sopenharmony_ci .maxMultiviewViewCount = 0, 1553bf215546Sopenharmony_ci .maxMultiviewInstanceIndex = 0, 1554bf215546Sopenharmony_ci .protectedNoFault = false, 1555bf215546Sopenharmony_ci /* Vulkan 1.1 wants this value to be at least 1024. Let's stick to this 1556bf215546Sopenharmony_ci * minimum requirement for now, and hope the total number of samplers 1557bf215546Sopenharmony_ci * across all descriptor sets doesn't exceed 2048, otherwise we'd exceed 1558bf215546Sopenharmony_ci * the maximum number of samplers per heap. For any descriptor set 1559bf215546Sopenharmony_ci * containing more than 1024 descriptors, 1560bf215546Sopenharmony_ci * vkGetDescriptorSetLayoutSupport() can be called to determine if the 1561bf215546Sopenharmony_ci * layout is within D3D12 descriptor heap bounds. 1562bf215546Sopenharmony_ci */ 1563bf215546Sopenharmony_ci .maxPerSetDescriptors = 1024, 1564bf215546Sopenharmony_ci /* According to the spec, the maximum D3D12 resource size is 1565bf215546Sopenharmony_ci * min(max(128MB, 0.25f * (amount of dedicated VRAM)), 2GB), 1566bf215546Sopenharmony_ci * but the limit actually depends on the max(system_ram, VRAM) not 1567bf215546Sopenharmony_ci * just the VRAM. 1568bf215546Sopenharmony_ci */ 1569bf215546Sopenharmony_ci .maxMemoryAllocationSize = 1570bf215546Sopenharmony_ci CLAMP(MAX2(pdevice->desc.dedicated_video_memory, 1571bf215546Sopenharmony_ci pdevice->desc.dedicated_system_memory + 1572bf215546Sopenharmony_ci pdevice->desc.shared_system_memory) / 4, 1573bf215546Sopenharmony_ci 128ull * 1024 * 1024, 2ull * 1024 * 1024 * 1024), 1574bf215546Sopenharmony_ci }; 1575bf215546Sopenharmony_ci memcpy(core_1_1.driverUUID, pdevice->driver_uuid, VK_UUID_SIZE); 1576bf215546Sopenharmony_ci memcpy(core_1_1.deviceUUID, pdevice->device_uuid, VK_UUID_SIZE); 1577bf215546Sopenharmony_ci memcpy(core_1_1.deviceLUID, &pdevice->desc.adapter_luid, VK_LUID_SIZE); 1578bf215546Sopenharmony_ci 1579bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(pdevice->desc.adapter_luid) == sizeof(core_1_1.deviceLUID)); 1580bf215546Sopenharmony_ci 1581bf215546Sopenharmony_ci VkPhysicalDeviceVulkan12Properties core_1_2 = { 1582bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, 1583bf215546Sopenharmony_ci .driverID = VK_DRIVER_ID_MESA_DOZEN, 1584bf215546Sopenharmony_ci .conformanceVersion = (VkConformanceVersion){ 1585bf215546Sopenharmony_ci .major = 0, 1586bf215546Sopenharmony_ci .minor = 0, 1587bf215546Sopenharmony_ci .subminor = 0, 1588bf215546Sopenharmony_ci .patch = 0, 1589bf215546Sopenharmony_ci }, 1590bf215546Sopenharmony_ci .denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, 1591bf215546Sopenharmony_ci .roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, 1592bf215546Sopenharmony_ci .shaderSignedZeroInfNanPreserveFloat16 = false, 1593bf215546Sopenharmony_ci .shaderSignedZeroInfNanPreserveFloat32 = false, 1594bf215546Sopenharmony_ci .shaderSignedZeroInfNanPreserveFloat64 = false, 1595bf215546Sopenharmony_ci .shaderDenormPreserveFloat16 = true, 1596bf215546Sopenharmony_ci .shaderDenormPreserveFloat32 = false, 1597bf215546Sopenharmony_ci .shaderDenormPreserveFloat64 = true, 1598bf215546Sopenharmony_ci .shaderDenormFlushToZeroFloat16 = false, 1599bf215546Sopenharmony_ci .shaderDenormFlushToZeroFloat32 = true, 1600bf215546Sopenharmony_ci .shaderDenormFlushToZeroFloat64 = false, 1601bf215546Sopenharmony_ci .shaderRoundingModeRTEFloat16 = true, 1602bf215546Sopenharmony_ci .shaderRoundingModeRTEFloat32 = true, 1603bf215546Sopenharmony_ci .shaderRoundingModeRTEFloat64 = true, 1604bf215546Sopenharmony_ci .shaderRoundingModeRTZFloat16 = false, 1605bf215546Sopenharmony_ci .shaderRoundingModeRTZFloat32 = false, 1606bf215546Sopenharmony_ci .shaderRoundingModeRTZFloat64 = false, 1607bf215546Sopenharmony_ci .shaderUniformBufferArrayNonUniformIndexingNative = true, 1608bf215546Sopenharmony_ci .shaderSampledImageArrayNonUniformIndexingNative = true, 1609bf215546Sopenharmony_ci .shaderStorageBufferArrayNonUniformIndexingNative = true, 1610bf215546Sopenharmony_ci .shaderStorageImageArrayNonUniformIndexingNative = true, 1611bf215546Sopenharmony_ci .shaderInputAttachmentArrayNonUniformIndexingNative = true, 1612bf215546Sopenharmony_ci .robustBufferAccessUpdateAfterBind = true, 1613bf215546Sopenharmony_ci .quadDivergentImplicitLod = false, 1614bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindSamplers = 0, 1615bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindUniformBuffers = 0, 1616bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindStorageBuffers = 0, 1617bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindSampledImages = 0, 1618bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindStorageImages = 0, 1619bf215546Sopenharmony_ci .maxPerStageDescriptorUpdateAfterBindInputAttachments = 0, 1620bf215546Sopenharmony_ci .maxPerStageUpdateAfterBindResources = 0, 1621bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindSamplers = 0, 1622bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindUniformBuffers = 0, 1623bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = 0, 1624bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindStorageBuffers = 0, 1625bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = 0, 1626bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindSampledImages = 0, 1627bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindStorageImages = 0, 1628bf215546Sopenharmony_ci .maxDescriptorSetUpdateAfterBindInputAttachments = 0, 1629bf215546Sopenharmony_ci 1630bf215546Sopenharmony_ci /* FIXME: add support for VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 1631bf215546Sopenharmony_ci * which is required by the VK 1.2 spec. 1632bf215546Sopenharmony_ci */ 1633bf215546Sopenharmony_ci .supportedDepthResolveModes = VK_RESOLVE_MODE_AVERAGE_BIT, 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci .supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, 1636bf215546Sopenharmony_ci .independentResolveNone = false, 1637bf215546Sopenharmony_ci .independentResolve = false, 1638bf215546Sopenharmony_ci .filterMinmaxSingleComponentFormats = false, 1639bf215546Sopenharmony_ci .filterMinmaxImageComponentMapping = false, 1640bf215546Sopenharmony_ci .maxTimelineSemaphoreValueDifference = UINT64_MAX, 1641bf215546Sopenharmony_ci .framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT, 1642bf215546Sopenharmony_ci }; 1643bf215546Sopenharmony_ci 1644bf215546Sopenharmony_ci snprintf(core_1_2.driverName, VK_MAX_DRIVER_NAME_SIZE, "Dozen"); 1645bf215546Sopenharmony_ci snprintf(core_1_2.driverInfo, VK_MAX_DRIVER_INFO_SIZE, "Mesa " PACKAGE_VERSION MESA_GIT_SHA1); 1646bf215546Sopenharmony_ci 1647bf215546Sopenharmony_ci const VkPhysicalDeviceVulkan13Properties core_1_3 = { 1648bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES, 1649bf215546Sopenharmony_ci }; 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci vk_foreach_struct(ext, pProperties->pNext) { 1652bf215546Sopenharmony_ci if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1) || 1653bf215546Sopenharmony_ci vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2) || 1654bf215546Sopenharmony_ci vk_get_physical_device_core_1_3_property_ext(ext, &core_1_3)) 1655bf215546Sopenharmony_ci continue; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci switch (ext->sType) { 1658bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: { 1659bf215546Sopenharmony_ci VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *attr_div = 1660bf215546Sopenharmony_ci (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext; 1661bf215546Sopenharmony_ci attr_div->maxVertexAttribDivisor = UINT32_MAX; 1662bf215546Sopenharmony_ci break; 1663bf215546Sopenharmony_ci } 1664bf215546Sopenharmony_ci default: 1665bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 1666bf215546Sopenharmony_ci break; 1667bf215546Sopenharmony_ci } 1668bf215546Sopenharmony_ci } 1669bf215546Sopenharmony_ci} 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1672bf215546Sopenharmony_cidzn_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, 1673bf215546Sopenharmony_ci uint32_t *pQueueFamilyPropertyCount, 1674bf215546Sopenharmony_ci VkQueueFamilyProperties2 *pQueueFamilyProperties) 1675bf215546Sopenharmony_ci{ 1676bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 1677bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, 1678bf215546Sopenharmony_ci pQueueFamilyProperties, pQueueFamilyPropertyCount); 1679bf215546Sopenharmony_ci 1680bf215546Sopenharmony_ci (void)dzn_physical_device_get_d3d12_dev(pdev); 1681bf215546Sopenharmony_ci 1682bf215546Sopenharmony_ci for (uint32_t i = 0; i < pdev->queue_family_count; i++) { 1683bf215546Sopenharmony_ci vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) { 1684bf215546Sopenharmony_ci p->queueFamilyProperties = pdev->queue_families[i].props; 1685bf215546Sopenharmony_ci 1686bf215546Sopenharmony_ci vk_foreach_struct(ext, pQueueFamilyProperties->pNext) { 1687bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 1688bf215546Sopenharmony_ci } 1689bf215546Sopenharmony_ci } 1690bf215546Sopenharmony_ci } 1691bf215546Sopenharmony_ci} 1692bf215546Sopenharmony_ci 1693bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1694bf215546Sopenharmony_cidzn_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, 1695bf215546Sopenharmony_ci VkPhysicalDeviceMemoryProperties *pMemoryProperties) 1696bf215546Sopenharmony_ci{ 1697bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 1698bf215546Sopenharmony_ci 1699bf215546Sopenharmony_ci // Ensure memory caps are up-to-date 1700bf215546Sopenharmony_ci (void)dzn_physical_device_get_d3d12_dev(pdev); 1701bf215546Sopenharmony_ci *pMemoryProperties = pdev->memory; 1702bf215546Sopenharmony_ci} 1703bf215546Sopenharmony_ci 1704bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1705bf215546Sopenharmony_cidzn_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, 1706bf215546Sopenharmony_ci VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) 1707bf215546Sopenharmony_ci{ 1708bf215546Sopenharmony_ci dzn_GetPhysicalDeviceMemoryProperties(physicalDevice, 1709bf215546Sopenharmony_ci &pMemoryProperties->memoryProperties); 1710bf215546Sopenharmony_ci 1711bf215546Sopenharmony_ci vk_foreach_struct(ext, pMemoryProperties->pNext) { 1712bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 1713bf215546Sopenharmony_ci } 1714bf215546Sopenharmony_ci} 1715bf215546Sopenharmony_ci 1716bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1717bf215546Sopenharmony_cidzn_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount, 1718bf215546Sopenharmony_ci VkLayerProperties *pProperties) 1719bf215546Sopenharmony_ci{ 1720bf215546Sopenharmony_ci if (pProperties == NULL) { 1721bf215546Sopenharmony_ci *pPropertyCount = 0; 1722bf215546Sopenharmony_ci return VK_SUCCESS; 1723bf215546Sopenharmony_ci } 1724bf215546Sopenharmony_ci 1725bf215546Sopenharmony_ci return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); 1726bf215546Sopenharmony_ci} 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_cistatic VkResult 1729bf215546Sopenharmony_cidzn_queue_sync_wait(struct dzn_queue *queue, const struct vk_sync_wait *wait) 1730bf215546Sopenharmony_ci{ 1731bf215546Sopenharmony_ci if (wait->sync->type == &vk_sync_dummy_type) 1732bf215546Sopenharmony_ci return VK_SUCCESS; 1733bf215546Sopenharmony_ci 1734bf215546Sopenharmony_ci struct dzn_device *device = container_of(queue->vk.base.device, struct dzn_device, vk); 1735bf215546Sopenharmony_ci assert(wait->sync->type == &dzn_sync_type); 1736bf215546Sopenharmony_ci struct dzn_sync *sync = container_of(wait->sync, struct dzn_sync, vk); 1737bf215546Sopenharmony_ci uint64_t value = 1738bf215546Sopenharmony_ci (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? wait->wait_value : 1; 1739bf215546Sopenharmony_ci 1740bf215546Sopenharmony_ci assert(sync->fence != NULL); 1741bf215546Sopenharmony_ci 1742bf215546Sopenharmony_ci if (value > 0 && FAILED(ID3D12CommandQueue_Wait(queue->cmdqueue, sync->fence, value))) 1743bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1744bf215546Sopenharmony_ci 1745bf215546Sopenharmony_ci return VK_SUCCESS; 1746bf215546Sopenharmony_ci} 1747bf215546Sopenharmony_ci 1748bf215546Sopenharmony_cistatic VkResult 1749bf215546Sopenharmony_cidzn_queue_sync_signal(struct dzn_queue *queue, const struct vk_sync_signal *signal) 1750bf215546Sopenharmony_ci{ 1751bf215546Sopenharmony_ci if (signal->sync->type == &vk_sync_dummy_type) 1752bf215546Sopenharmony_ci return VK_SUCCESS; 1753bf215546Sopenharmony_ci 1754bf215546Sopenharmony_ci struct dzn_device *device = container_of(queue->vk.base.device, struct dzn_device, vk); 1755bf215546Sopenharmony_ci assert(signal->sync->type == &dzn_sync_type); 1756bf215546Sopenharmony_ci struct dzn_sync *sync = container_of(signal->sync, struct dzn_sync, vk); 1757bf215546Sopenharmony_ci uint64_t value = 1758bf215546Sopenharmony_ci (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? signal->signal_value : 1; 1759bf215546Sopenharmony_ci assert(value > 0); 1760bf215546Sopenharmony_ci 1761bf215546Sopenharmony_ci assert(sync->fence != NULL); 1762bf215546Sopenharmony_ci 1763bf215546Sopenharmony_ci if (FAILED(ID3D12CommandQueue_Signal(queue->cmdqueue, sync->fence, value))) 1764bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1765bf215546Sopenharmony_ci 1766bf215546Sopenharmony_ci return VK_SUCCESS; 1767bf215546Sopenharmony_ci} 1768bf215546Sopenharmony_ci 1769bf215546Sopenharmony_cistatic VkResult 1770bf215546Sopenharmony_cidzn_queue_submit(struct vk_queue *q, 1771bf215546Sopenharmony_ci struct vk_queue_submit *info) 1772bf215546Sopenharmony_ci{ 1773bf215546Sopenharmony_ci struct dzn_queue *queue = container_of(q, struct dzn_queue, vk); 1774bf215546Sopenharmony_ci struct dzn_device *device = container_of(q->base.device, struct dzn_device, vk); 1775bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 1776bf215546Sopenharmony_ci 1777bf215546Sopenharmony_ci for (uint32_t i = 0; i < info->wait_count; i++) { 1778bf215546Sopenharmony_ci result = dzn_queue_sync_wait(queue, &info->waits[i]); 1779bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1780bf215546Sopenharmony_ci return result; 1781bf215546Sopenharmony_ci } 1782bf215546Sopenharmony_ci 1783bf215546Sopenharmony_ci for (uint32_t i = 0; i < info->command_buffer_count; i++) { 1784bf215546Sopenharmony_ci struct dzn_cmd_buffer *cmd_buffer = 1785bf215546Sopenharmony_ci container_of(info->command_buffers[i], struct dzn_cmd_buffer, vk); 1786bf215546Sopenharmony_ci 1787bf215546Sopenharmony_ci ID3D12CommandList *cmdlists[] = { (ID3D12CommandList *)cmd_buffer->cmdlist }; 1788bf215546Sopenharmony_ci 1789bf215546Sopenharmony_ci util_dynarray_foreach(&cmd_buffer->events.wait, struct dzn_event *, evt) { 1790bf215546Sopenharmony_ci if (FAILED(ID3D12CommandQueue_Wait(queue->cmdqueue, (*evt)->fence, 1))) 1791bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1792bf215546Sopenharmony_ci } 1793bf215546Sopenharmony_ci 1794bf215546Sopenharmony_ci util_dynarray_foreach(&cmd_buffer->queries.wait, struct dzn_cmd_buffer_query_range, range) { 1795bf215546Sopenharmony_ci mtx_lock(&range->qpool->queries_lock); 1796bf215546Sopenharmony_ci for (uint32_t q = range->start; q < range->start + range->count; q++) { 1797bf215546Sopenharmony_ci struct dzn_query *query = &range->qpool->queries[q]; 1798bf215546Sopenharmony_ci 1799bf215546Sopenharmony_ci if (query->fence && 1800bf215546Sopenharmony_ci FAILED(ID3D12CommandQueue_Wait(queue->cmdqueue, query->fence, query->fence_value))) 1801bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1802bf215546Sopenharmony_ci } 1803bf215546Sopenharmony_ci mtx_unlock(&range->qpool->queries_lock); 1804bf215546Sopenharmony_ci } 1805bf215546Sopenharmony_ci 1806bf215546Sopenharmony_ci util_dynarray_foreach(&cmd_buffer->queries.reset, struct dzn_cmd_buffer_query_range, range) { 1807bf215546Sopenharmony_ci mtx_lock(&range->qpool->queries_lock); 1808bf215546Sopenharmony_ci for (uint32_t q = range->start; q < range->start + range->count; q++) { 1809bf215546Sopenharmony_ci struct dzn_query *query = &range->qpool->queries[q]; 1810bf215546Sopenharmony_ci if (query->fence) { 1811bf215546Sopenharmony_ci ID3D12Fence_Release(query->fence); 1812bf215546Sopenharmony_ci query->fence = NULL; 1813bf215546Sopenharmony_ci } 1814bf215546Sopenharmony_ci query->fence_value = 0; 1815bf215546Sopenharmony_ci } 1816bf215546Sopenharmony_ci mtx_unlock(&range->qpool->queries_lock); 1817bf215546Sopenharmony_ci } 1818bf215546Sopenharmony_ci 1819bf215546Sopenharmony_ci ID3D12CommandQueue_ExecuteCommandLists(queue->cmdqueue, 1, cmdlists); 1820bf215546Sopenharmony_ci 1821bf215546Sopenharmony_ci util_dynarray_foreach(&cmd_buffer->events.signal, struct dzn_cmd_event_signal, evt) { 1822bf215546Sopenharmony_ci if (FAILED(ID3D12CommandQueue_Signal(queue->cmdqueue, evt->event->fence, evt->value ? 1 : 0))) 1823bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1824bf215546Sopenharmony_ci } 1825bf215546Sopenharmony_ci 1826bf215546Sopenharmony_ci util_dynarray_foreach(&cmd_buffer->queries.signal, struct dzn_cmd_buffer_query_range, range) { 1827bf215546Sopenharmony_ci mtx_lock(&range->qpool->queries_lock); 1828bf215546Sopenharmony_ci for (uint32_t q = range->start; q < range->start + range->count; q++) { 1829bf215546Sopenharmony_ci struct dzn_query *query = &range->qpool->queries[q]; 1830bf215546Sopenharmony_ci query->fence_value = queue->fence_point + 1; 1831bf215546Sopenharmony_ci query->fence = queue->fence; 1832bf215546Sopenharmony_ci ID3D12Fence_AddRef(query->fence); 1833bf215546Sopenharmony_ci } 1834bf215546Sopenharmony_ci mtx_unlock(&range->qpool->queries_lock); 1835bf215546Sopenharmony_ci } 1836bf215546Sopenharmony_ci } 1837bf215546Sopenharmony_ci 1838bf215546Sopenharmony_ci for (uint32_t i = 0; i < info->signal_count; i++) { 1839bf215546Sopenharmony_ci result = dzn_queue_sync_signal(queue, &info->signals[i]); 1840bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1841bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1842bf215546Sopenharmony_ci } 1843bf215546Sopenharmony_ci 1844bf215546Sopenharmony_ci if (FAILED(ID3D12CommandQueue_Signal(queue->cmdqueue, queue->fence, ++queue->fence_point))) 1845bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_UNKNOWN); 1846bf215546Sopenharmony_ci 1847bf215546Sopenharmony_ci return VK_SUCCESS; 1848bf215546Sopenharmony_ci} 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_cistatic void 1851bf215546Sopenharmony_cidzn_queue_finish(struct dzn_queue *queue) 1852bf215546Sopenharmony_ci{ 1853bf215546Sopenharmony_ci if (queue->cmdqueue) 1854bf215546Sopenharmony_ci ID3D12CommandQueue_Release(queue->cmdqueue); 1855bf215546Sopenharmony_ci 1856bf215546Sopenharmony_ci if (queue->fence) 1857bf215546Sopenharmony_ci ID3D12Fence_Release(queue->fence); 1858bf215546Sopenharmony_ci 1859bf215546Sopenharmony_ci vk_queue_finish(&queue->vk); 1860bf215546Sopenharmony_ci} 1861bf215546Sopenharmony_ci 1862bf215546Sopenharmony_cistatic VkResult 1863bf215546Sopenharmony_cidzn_queue_init(struct dzn_queue *queue, 1864bf215546Sopenharmony_ci struct dzn_device *device, 1865bf215546Sopenharmony_ci const VkDeviceQueueCreateInfo *pCreateInfo, 1866bf215546Sopenharmony_ci uint32_t index_in_family) 1867bf215546Sopenharmony_ci{ 1868bf215546Sopenharmony_ci struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk); 1869bf215546Sopenharmony_ci 1870bf215546Sopenharmony_ci VkResult result = vk_queue_init(&queue->vk, &device->vk, pCreateInfo, index_in_family); 1871bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1872bf215546Sopenharmony_ci return result; 1873bf215546Sopenharmony_ci 1874bf215546Sopenharmony_ci queue->vk.driver_submit = dzn_queue_submit; 1875bf215546Sopenharmony_ci 1876bf215546Sopenharmony_ci assert(pCreateInfo->queueFamilyIndex < pdev->queue_family_count); 1877bf215546Sopenharmony_ci 1878bf215546Sopenharmony_ci D3D12_COMMAND_QUEUE_DESC queue_desc = 1879bf215546Sopenharmony_ci pdev->queue_families[pCreateInfo->queueFamilyIndex].desc; 1880bf215546Sopenharmony_ci 1881bf215546Sopenharmony_ci float priority_in = pCreateInfo->pQueuePriorities[index_in_family]; 1882bf215546Sopenharmony_ci queue_desc.Priority = 1883bf215546Sopenharmony_ci priority_in > 0.5f ? D3D12_COMMAND_QUEUE_PRIORITY_HIGH : D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; 1884bf215546Sopenharmony_ci queue_desc.NodeMask = 0; 1885bf215546Sopenharmony_ci 1886bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateCommandQueue(device->dev, &queue_desc, 1887bf215546Sopenharmony_ci &IID_ID3D12CommandQueue, 1888bf215546Sopenharmony_ci (void **)&queue->cmdqueue))) { 1889bf215546Sopenharmony_ci dzn_queue_finish(queue); 1890bf215546Sopenharmony_ci return vk_error(device->vk.physical->instance, VK_ERROR_INITIALIZATION_FAILED); 1891bf215546Sopenharmony_ci } 1892bf215546Sopenharmony_ci 1893bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateFence(device->dev, 0, D3D12_FENCE_FLAG_NONE, 1894bf215546Sopenharmony_ci &IID_ID3D12Fence, 1895bf215546Sopenharmony_ci (void **)&queue->fence))) { 1896bf215546Sopenharmony_ci dzn_queue_finish(queue); 1897bf215546Sopenharmony_ci return vk_error(device->vk.physical->instance, VK_ERROR_INITIALIZATION_FAILED); 1898bf215546Sopenharmony_ci } 1899bf215546Sopenharmony_ci 1900bf215546Sopenharmony_ci return VK_SUCCESS; 1901bf215546Sopenharmony_ci} 1902bf215546Sopenharmony_ci 1903bf215546Sopenharmony_cistatic VkResult 1904bf215546Sopenharmony_cicheck_physical_device_features(VkPhysicalDevice physicalDevice, 1905bf215546Sopenharmony_ci const VkPhysicalDeviceFeatures *features) 1906bf215546Sopenharmony_ci{ 1907bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, pdev, physicalDevice); 1908bf215546Sopenharmony_ci 1909bf215546Sopenharmony_ci VkPhysicalDeviceFeatures supported_features; 1910bf215546Sopenharmony_ci 1911bf215546Sopenharmony_ci pdev->vk.dispatch_table.GetPhysicalDeviceFeatures(physicalDevice, &supported_features); 1912bf215546Sopenharmony_ci 1913bf215546Sopenharmony_ci VkBool32 *supported_feature = (VkBool32 *)&supported_features; 1914bf215546Sopenharmony_ci VkBool32 *enabled_feature = (VkBool32 *)features; 1915bf215546Sopenharmony_ci unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 1916bf215546Sopenharmony_ci for (uint32_t i = 0; i < num_features; i++) { 1917bf215546Sopenharmony_ci if (enabled_feature[i] && !supported_feature[i]) 1918bf215546Sopenharmony_ci return VK_ERROR_FEATURE_NOT_PRESENT; 1919bf215546Sopenharmony_ci } 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci return VK_SUCCESS; 1922bf215546Sopenharmony_ci} 1923bf215546Sopenharmony_ci 1924bf215546Sopenharmony_cistatic VkResult 1925bf215546Sopenharmony_cidzn_device_create_sync_for_memory(struct vk_device *device, 1926bf215546Sopenharmony_ci VkDeviceMemory memory, 1927bf215546Sopenharmony_ci bool signal_memory, 1928bf215546Sopenharmony_ci struct vk_sync **sync_out) 1929bf215546Sopenharmony_ci{ 1930bf215546Sopenharmony_ci return vk_sync_create(device, &vk_sync_dummy_type, 1931bf215546Sopenharmony_ci 0, 1, sync_out); 1932bf215546Sopenharmony_ci} 1933bf215546Sopenharmony_ci 1934bf215546Sopenharmony_cistatic VkResult 1935bf215546Sopenharmony_cidzn_device_query_init(struct dzn_device *device) 1936bf215546Sopenharmony_ci{ 1937bf215546Sopenharmony_ci /* FIXME: create the resource in the default heap */ 1938bf215546Sopenharmony_ci D3D12_HEAP_PROPERTIES hprops = dzn_ID3D12Device2_GetCustomHeapProperties(device->dev, 0, D3D12_HEAP_TYPE_UPLOAD); 1939bf215546Sopenharmony_ci D3D12_RESOURCE_DESC rdesc = { 1940bf215546Sopenharmony_ci .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER, 1941bf215546Sopenharmony_ci .Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, 1942bf215546Sopenharmony_ci .Width = DZN_QUERY_REFS_RES_SIZE, 1943bf215546Sopenharmony_ci .Height = 1, 1944bf215546Sopenharmony_ci .DepthOrArraySize = 1, 1945bf215546Sopenharmony_ci .MipLevels = 1, 1946bf215546Sopenharmony_ci .Format = DXGI_FORMAT_UNKNOWN, 1947bf215546Sopenharmony_ci .SampleDesc = { .Count = 1, .Quality = 0 }, 1948bf215546Sopenharmony_ci .Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR, 1949bf215546Sopenharmony_ci .Flags = D3D12_RESOURCE_FLAG_NONE, 1950bf215546Sopenharmony_ci }; 1951bf215546Sopenharmony_ci 1952bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateCommittedResource(device->dev, &hprops, 1953bf215546Sopenharmony_ci D3D12_HEAP_FLAG_NONE, 1954bf215546Sopenharmony_ci &rdesc, 1955bf215546Sopenharmony_ci D3D12_RESOURCE_STATE_GENERIC_READ, 1956bf215546Sopenharmony_ci NULL, 1957bf215546Sopenharmony_ci &IID_ID3D12Resource, 1958bf215546Sopenharmony_ci (void **)&device->queries.refs))) 1959bf215546Sopenharmony_ci return vk_error(device->vk.physical, VK_ERROR_OUT_OF_DEVICE_MEMORY); 1960bf215546Sopenharmony_ci 1961bf215546Sopenharmony_ci uint8_t *queries_ref; 1962bf215546Sopenharmony_ci if (FAILED(ID3D12Resource_Map(device->queries.refs, 0, NULL, (void **)&queries_ref))) 1963bf215546Sopenharmony_ci return vk_error(device->vk.physical, VK_ERROR_OUT_OF_HOST_MEMORY); 1964bf215546Sopenharmony_ci 1965bf215546Sopenharmony_ci memset(queries_ref + DZN_QUERY_REFS_ALL_ONES_OFFSET, 0xff, DZN_QUERY_REFS_SECTION_SIZE); 1966bf215546Sopenharmony_ci memset(queries_ref + DZN_QUERY_REFS_ALL_ZEROS_OFFSET, 0x0, DZN_QUERY_REFS_SECTION_SIZE); 1967bf215546Sopenharmony_ci ID3D12Resource_Unmap(device->queries.refs, 0, NULL); 1968bf215546Sopenharmony_ci 1969bf215546Sopenharmony_ci return VK_SUCCESS; 1970bf215546Sopenharmony_ci} 1971bf215546Sopenharmony_ci 1972bf215546Sopenharmony_cistatic void 1973bf215546Sopenharmony_cidzn_device_query_finish(struct dzn_device *device) 1974bf215546Sopenharmony_ci{ 1975bf215546Sopenharmony_ci if (device->queries.refs) 1976bf215546Sopenharmony_ci ID3D12Resource_Release(device->queries.refs); 1977bf215546Sopenharmony_ci} 1978bf215546Sopenharmony_ci 1979bf215546Sopenharmony_cistatic void 1980bf215546Sopenharmony_cidzn_device_destroy(struct dzn_device *device, const VkAllocationCallbacks *pAllocator) 1981bf215546Sopenharmony_ci{ 1982bf215546Sopenharmony_ci if (!device) 1983bf215546Sopenharmony_ci return; 1984bf215546Sopenharmony_ci 1985bf215546Sopenharmony_ci struct dzn_instance *instance = 1986bf215546Sopenharmony_ci container_of(device->vk.physical->instance, struct dzn_instance, vk); 1987bf215546Sopenharmony_ci 1988bf215546Sopenharmony_ci vk_foreach_queue_safe(q, &device->vk) { 1989bf215546Sopenharmony_ci struct dzn_queue *queue = container_of(q, struct dzn_queue, vk); 1990bf215546Sopenharmony_ci 1991bf215546Sopenharmony_ci dzn_queue_finish(queue); 1992bf215546Sopenharmony_ci } 1993bf215546Sopenharmony_ci 1994bf215546Sopenharmony_ci dzn_device_query_finish(device); 1995bf215546Sopenharmony_ci dzn_meta_finish(device); 1996bf215546Sopenharmony_ci 1997bf215546Sopenharmony_ci if (device->dev) 1998bf215546Sopenharmony_ci ID3D12Device1_Release(device->dev); 1999bf215546Sopenharmony_ci 2000bf215546Sopenharmony_ci vk_device_finish(&device->vk); 2001bf215546Sopenharmony_ci vk_free2(&instance->vk.alloc, pAllocator, device); 2002bf215546Sopenharmony_ci} 2003bf215546Sopenharmony_ci 2004bf215546Sopenharmony_cistatic VkResult 2005bf215546Sopenharmony_cidzn_device_check_status(struct vk_device *dev) 2006bf215546Sopenharmony_ci{ 2007bf215546Sopenharmony_ci struct dzn_device *device = container_of(dev, struct dzn_device, vk); 2008bf215546Sopenharmony_ci 2009bf215546Sopenharmony_ci if (FAILED(ID3D12Device_GetDeviceRemovedReason(device->dev))) 2010bf215546Sopenharmony_ci return vk_device_set_lost(&device->vk, "D3D12 device removed"); 2011bf215546Sopenharmony_ci 2012bf215546Sopenharmony_ci return VK_SUCCESS; 2013bf215546Sopenharmony_ci} 2014bf215546Sopenharmony_ci 2015bf215546Sopenharmony_cistatic VkResult 2016bf215546Sopenharmony_cidzn_device_create(struct dzn_physical_device *pdev, 2017bf215546Sopenharmony_ci const VkDeviceCreateInfo *pCreateInfo, 2018bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2019bf215546Sopenharmony_ci VkDevice *out) 2020bf215546Sopenharmony_ci{ 2021bf215546Sopenharmony_ci struct dzn_instance *instance = container_of(pdev->vk.instance, struct dzn_instance, vk); 2022bf215546Sopenharmony_ci 2023bf215546Sopenharmony_ci uint32_t queue_count = 0; 2024bf215546Sopenharmony_ci for (uint32_t qf = 0; qf < pCreateInfo->queueCreateInfoCount; qf++) { 2025bf215546Sopenharmony_ci const VkDeviceQueueCreateInfo *qinfo = &pCreateInfo->pQueueCreateInfos[qf]; 2026bf215546Sopenharmony_ci queue_count += qinfo->queueCount; 2027bf215546Sopenharmony_ci } 2028bf215546Sopenharmony_ci 2029bf215546Sopenharmony_ci VK_MULTIALLOC(ma); 2030bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_device, device, 1); 2031bf215546Sopenharmony_ci VK_MULTIALLOC_DECL(&ma, struct dzn_queue, queues, queue_count); 2032bf215546Sopenharmony_ci 2033bf215546Sopenharmony_ci if (!vk_multialloc_zalloc2(&ma, &instance->vk.alloc, pAllocator, 2034bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_DEVICE)) 2035bf215546Sopenharmony_ci return vk_error(pdev, VK_ERROR_OUT_OF_HOST_MEMORY); 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci struct vk_device_dispatch_table dispatch_table; 2038bf215546Sopenharmony_ci 2039bf215546Sopenharmony_ci /* For secondary command buffer support, overwrite any command entrypoints 2040bf215546Sopenharmony_ci * in the main device-level dispatch table with 2041bf215546Sopenharmony_ci * vk_cmd_enqueue_unless_primary_Cmd*. 2042bf215546Sopenharmony_ci */ 2043bf215546Sopenharmony_ci vk_device_dispatch_table_from_entrypoints(&dispatch_table, 2044bf215546Sopenharmony_ci &vk_cmd_enqueue_unless_primary_device_entrypoints, true); 2045bf215546Sopenharmony_ci vk_device_dispatch_table_from_entrypoints(&dispatch_table, 2046bf215546Sopenharmony_ci &dzn_device_entrypoints, false); 2047bf215546Sopenharmony_ci vk_device_dispatch_table_from_entrypoints(&dispatch_table, 2048bf215546Sopenharmony_ci &wsi_device_entrypoints, false); 2049bf215546Sopenharmony_ci 2050bf215546Sopenharmony_ci /* Populate our primary cmd_dispatch table. */ 2051bf215546Sopenharmony_ci vk_device_dispatch_table_from_entrypoints(&device->cmd_dispatch, 2052bf215546Sopenharmony_ci &dzn_device_entrypoints, true); 2053bf215546Sopenharmony_ci vk_device_dispatch_table_from_entrypoints(&device->cmd_dispatch, 2054bf215546Sopenharmony_ci &vk_common_device_entrypoints, 2055bf215546Sopenharmony_ci false); 2056bf215546Sopenharmony_ci 2057bf215546Sopenharmony_ci VkResult result = 2058bf215546Sopenharmony_ci vk_device_init(&device->vk, &pdev->vk, &dispatch_table, pCreateInfo, pAllocator); 2059bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 2060bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, device); 2061bf215546Sopenharmony_ci return result; 2062bf215546Sopenharmony_ci } 2063bf215546Sopenharmony_ci 2064bf215546Sopenharmony_ci /* Must be done after vk_device_init() because this function memset(0) the 2065bf215546Sopenharmony_ci * whole struct. 2066bf215546Sopenharmony_ci */ 2067bf215546Sopenharmony_ci device->vk.command_dispatch_table = &device->cmd_dispatch; 2068bf215546Sopenharmony_ci device->vk.create_sync_for_memory = dzn_device_create_sync_for_memory; 2069bf215546Sopenharmony_ci device->vk.check_status = dzn_device_check_status; 2070bf215546Sopenharmony_ci 2071bf215546Sopenharmony_ci device->dev = dzn_physical_device_get_d3d12_dev(pdev); 2072bf215546Sopenharmony_ci if (!device->dev) { 2073bf215546Sopenharmony_ci dzn_device_destroy(device, pAllocator); 2074bf215546Sopenharmony_ci return vk_error(pdev, VK_ERROR_INITIALIZATION_FAILED); 2075bf215546Sopenharmony_ci } 2076bf215546Sopenharmony_ci 2077bf215546Sopenharmony_ci ID3D12Device1_AddRef(device->dev); 2078bf215546Sopenharmony_ci 2079bf215546Sopenharmony_ci ID3D12InfoQueue *info_queue; 2080bf215546Sopenharmony_ci if (SUCCEEDED(ID3D12Device1_QueryInterface(device->dev, 2081bf215546Sopenharmony_ci &IID_ID3D12InfoQueue, 2082bf215546Sopenharmony_ci (void **)&info_queue))) { 2083bf215546Sopenharmony_ci D3D12_MESSAGE_SEVERITY severities[] = { 2084bf215546Sopenharmony_ci D3D12_MESSAGE_SEVERITY_INFO, 2085bf215546Sopenharmony_ci D3D12_MESSAGE_SEVERITY_WARNING, 2086bf215546Sopenharmony_ci }; 2087bf215546Sopenharmony_ci 2088bf215546Sopenharmony_ci D3D12_MESSAGE_ID msg_ids[] = { 2089bf215546Sopenharmony_ci D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE, 2090bf215546Sopenharmony_ci }; 2091bf215546Sopenharmony_ci 2092bf215546Sopenharmony_ci D3D12_INFO_QUEUE_FILTER NewFilter = { 0 }; 2093bf215546Sopenharmony_ci NewFilter.DenyList.NumSeverities = ARRAY_SIZE(severities); 2094bf215546Sopenharmony_ci NewFilter.DenyList.pSeverityList = severities; 2095bf215546Sopenharmony_ci NewFilter.DenyList.NumIDs = ARRAY_SIZE(msg_ids); 2096bf215546Sopenharmony_ci NewFilter.DenyList.pIDList = msg_ids; 2097bf215546Sopenharmony_ci 2098bf215546Sopenharmony_ci ID3D12InfoQueue_PushStorageFilter(info_queue, &NewFilter); 2099bf215546Sopenharmony_ci } 2100bf215546Sopenharmony_ci 2101bf215546Sopenharmony_ci result = dzn_meta_init(device); 2102bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 2103bf215546Sopenharmony_ci dzn_device_destroy(device, pAllocator); 2104bf215546Sopenharmony_ci return result; 2105bf215546Sopenharmony_ci } 2106bf215546Sopenharmony_ci 2107bf215546Sopenharmony_ci result = dzn_device_query_init(device); 2108bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 2109bf215546Sopenharmony_ci dzn_device_destroy(device, pAllocator); 2110bf215546Sopenharmony_ci return result; 2111bf215546Sopenharmony_ci } 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci uint32_t qindex = 0; 2114bf215546Sopenharmony_ci for (uint32_t qf = 0; qf < pCreateInfo->queueCreateInfoCount; qf++) { 2115bf215546Sopenharmony_ci const VkDeviceQueueCreateInfo *qinfo = &pCreateInfo->pQueueCreateInfos[qf]; 2116bf215546Sopenharmony_ci 2117bf215546Sopenharmony_ci for (uint32_t q = 0; q < qinfo->queueCount; q++) { 2118bf215546Sopenharmony_ci result = 2119bf215546Sopenharmony_ci dzn_queue_init(&queues[qindex++], device, qinfo, q); 2120bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 2121bf215546Sopenharmony_ci dzn_device_destroy(device, pAllocator); 2122bf215546Sopenharmony_ci return result; 2123bf215546Sopenharmony_ci } 2124bf215546Sopenharmony_ci } 2125bf215546Sopenharmony_ci } 2126bf215546Sopenharmony_ci 2127bf215546Sopenharmony_ci assert(queue_count == qindex); 2128bf215546Sopenharmony_ci *out = dzn_device_to_handle(device); 2129bf215546Sopenharmony_ci return VK_SUCCESS; 2130bf215546Sopenharmony_ci} 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_ciID3D12RootSignature * 2133bf215546Sopenharmony_cidzn_device_create_root_sig(struct dzn_device *device, 2134bf215546Sopenharmony_ci const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc) 2135bf215546Sopenharmony_ci{ 2136bf215546Sopenharmony_ci struct dzn_instance *instance = 2137bf215546Sopenharmony_ci container_of(device->vk.physical->instance, struct dzn_instance, vk); 2138bf215546Sopenharmony_ci ID3D12RootSignature *root_sig = NULL; 2139bf215546Sopenharmony_ci ID3DBlob *sig = NULL, *error = NULL; 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_ci if (FAILED(instance->d3d12.serialize_root_sig(desc, 2142bf215546Sopenharmony_ci &sig, &error))) { 2143bf215546Sopenharmony_ci if (instance->debug_flags & DZN_DEBUG_SIG) { 2144bf215546Sopenharmony_ci const char *error_msg = (const char *)ID3D10Blob_GetBufferPointer(error); 2145bf215546Sopenharmony_ci fprintf(stderr, 2146bf215546Sopenharmony_ci "== SERIALIZE ROOT SIG ERROR =============================================\n" 2147bf215546Sopenharmony_ci "%s\n" 2148bf215546Sopenharmony_ci "== END ==========================================================\n", 2149bf215546Sopenharmony_ci error_msg); 2150bf215546Sopenharmony_ci } 2151bf215546Sopenharmony_ci 2152bf215546Sopenharmony_ci goto out; 2153bf215546Sopenharmony_ci } 2154bf215546Sopenharmony_ci 2155bf215546Sopenharmony_ci ID3D12Device1_CreateRootSignature(device->dev, 0, 2156bf215546Sopenharmony_ci ID3D10Blob_GetBufferPointer(sig), 2157bf215546Sopenharmony_ci ID3D10Blob_GetBufferSize(sig), 2158bf215546Sopenharmony_ci &IID_ID3D12RootSignature, 2159bf215546Sopenharmony_ci (void **)&root_sig); 2160bf215546Sopenharmony_ci 2161bf215546Sopenharmony_ciout: 2162bf215546Sopenharmony_ci if (error) 2163bf215546Sopenharmony_ci ID3D10Blob_Release(error); 2164bf215546Sopenharmony_ci 2165bf215546Sopenharmony_ci if (sig) 2166bf215546Sopenharmony_ci ID3D10Blob_Release(sig); 2167bf215546Sopenharmony_ci 2168bf215546Sopenharmony_ci return root_sig; 2169bf215546Sopenharmony_ci} 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2172bf215546Sopenharmony_cidzn_CreateDevice(VkPhysicalDevice physicalDevice, 2173bf215546Sopenharmony_ci const VkDeviceCreateInfo *pCreateInfo, 2174bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2175bf215546Sopenharmony_ci VkDevice *pDevice) 2176bf215546Sopenharmony_ci{ 2177bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_physical_device, physical_device, physicalDevice); 2178bf215546Sopenharmony_ci VkResult result; 2179bf215546Sopenharmony_ci 2180bf215546Sopenharmony_ci assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); 2181bf215546Sopenharmony_ci 2182bf215546Sopenharmony_ci /* Check enabled features */ 2183bf215546Sopenharmony_ci if (pCreateInfo->pEnabledFeatures) { 2184bf215546Sopenharmony_ci result = check_physical_device_features(physicalDevice, 2185bf215546Sopenharmony_ci pCreateInfo->pEnabledFeatures); 2186bf215546Sopenharmony_ci if (result != VK_SUCCESS) 2187bf215546Sopenharmony_ci return vk_error(physical_device, result); 2188bf215546Sopenharmony_ci } 2189bf215546Sopenharmony_ci 2190bf215546Sopenharmony_ci /* Check requested queues and fail if we are requested to create any 2191bf215546Sopenharmony_ci * queues with flags we don't support. 2192bf215546Sopenharmony_ci */ 2193bf215546Sopenharmony_ci assert(pCreateInfo->queueCreateInfoCount > 0); 2194bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { 2195bf215546Sopenharmony_ci if (pCreateInfo->pQueueCreateInfos[i].flags != 0) 2196bf215546Sopenharmony_ci return vk_error(physical_device, VK_ERROR_INITIALIZATION_FAILED); 2197bf215546Sopenharmony_ci } 2198bf215546Sopenharmony_ci 2199bf215546Sopenharmony_ci return dzn_device_create(physical_device, pCreateInfo, pAllocator, pDevice); 2200bf215546Sopenharmony_ci} 2201bf215546Sopenharmony_ci 2202bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2203bf215546Sopenharmony_cidzn_DestroyDevice(VkDevice dev, 2204bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2205bf215546Sopenharmony_ci{ 2206bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, dev); 2207bf215546Sopenharmony_ci 2208bf215546Sopenharmony_ci device->vk.dispatch_table.DeviceWaitIdle(dev); 2209bf215546Sopenharmony_ci 2210bf215546Sopenharmony_ci dzn_device_destroy(device, pAllocator); 2211bf215546Sopenharmony_ci} 2212bf215546Sopenharmony_ci 2213bf215546Sopenharmony_cistatic void 2214bf215546Sopenharmony_cidzn_device_memory_destroy(struct dzn_device_memory *mem, 2215bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2216bf215546Sopenharmony_ci{ 2217bf215546Sopenharmony_ci if (!mem) 2218bf215546Sopenharmony_ci return; 2219bf215546Sopenharmony_ci 2220bf215546Sopenharmony_ci struct dzn_device *device = container_of(mem->base.device, struct dzn_device, vk); 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ci if (mem->map) 2223bf215546Sopenharmony_ci ID3D12Resource_Unmap(mem->map_res, 0, NULL); 2224bf215546Sopenharmony_ci 2225bf215546Sopenharmony_ci if (mem->map_res) 2226bf215546Sopenharmony_ci ID3D12Resource_Release(mem->map_res); 2227bf215546Sopenharmony_ci 2228bf215546Sopenharmony_ci if (mem->heap) 2229bf215546Sopenharmony_ci ID3D12Heap_Release(mem->heap); 2230bf215546Sopenharmony_ci 2231bf215546Sopenharmony_ci vk_object_base_finish(&mem->base); 2232bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, mem); 2233bf215546Sopenharmony_ci} 2234bf215546Sopenharmony_ci 2235bf215546Sopenharmony_cistatic VkResult 2236bf215546Sopenharmony_cidzn_device_memory_create(struct dzn_device *device, 2237bf215546Sopenharmony_ci const VkMemoryAllocateInfo *pAllocateInfo, 2238bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2239bf215546Sopenharmony_ci VkDeviceMemory *out) 2240bf215546Sopenharmony_ci{ 2241bf215546Sopenharmony_ci struct dzn_physical_device *pdevice = 2242bf215546Sopenharmony_ci container_of(device->vk.physical, struct dzn_physical_device, vk); 2243bf215546Sopenharmony_ci 2244bf215546Sopenharmony_ci struct dzn_device_memory *mem = 2245bf215546Sopenharmony_ci vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8, 2246bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2247bf215546Sopenharmony_ci if (!mem) 2248bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2249bf215546Sopenharmony_ci 2250bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY); 2251bf215546Sopenharmony_ci 2252bf215546Sopenharmony_ci /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */ 2253bf215546Sopenharmony_ci assert(pAllocateInfo->allocationSize > 0); 2254bf215546Sopenharmony_ci 2255bf215546Sopenharmony_ci mem->size = pAllocateInfo->allocationSize; 2256bf215546Sopenharmony_ci 2257bf215546Sopenharmony_ci const struct dzn_buffer *buffer = NULL; 2258bf215546Sopenharmony_ci const struct dzn_image *image = NULL; 2259bf215546Sopenharmony_ci 2260bf215546Sopenharmony_ci vk_foreach_struct_const(ext, pAllocateInfo->pNext) { 2261bf215546Sopenharmony_ci switch (ext->sType) { 2262bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: { 2263bf215546Sopenharmony_ci UNUSED const VkExportMemoryAllocateInfo *exp = 2264bf215546Sopenharmony_ci (const VkExportMemoryAllocateInfo *)ext; 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci // TODO: support export 2267bf215546Sopenharmony_ci assert(exp->handleTypes == 0); 2268bf215546Sopenharmony_ci break; 2269bf215546Sopenharmony_ci } 2270bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: { 2271bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo *dedicated = 2272bf215546Sopenharmony_ci (const VkMemoryDedicatedAllocateInfo *)ext; 2273bf215546Sopenharmony_ci 2274bf215546Sopenharmony_ci buffer = dzn_buffer_from_handle(dedicated->buffer); 2275bf215546Sopenharmony_ci image = dzn_image_from_handle(dedicated->image); 2276bf215546Sopenharmony_ci assert(!buffer || !image); 2277bf215546Sopenharmony_ci break; 2278bf215546Sopenharmony_ci } 2279bf215546Sopenharmony_ci default: 2280bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 2281bf215546Sopenharmony_ci break; 2282bf215546Sopenharmony_ci } 2283bf215546Sopenharmony_ci } 2284bf215546Sopenharmony_ci 2285bf215546Sopenharmony_ci const VkMemoryType *mem_type = 2286bf215546Sopenharmony_ci &pdevice->memory.memoryTypes[pAllocateInfo->memoryTypeIndex]; 2287bf215546Sopenharmony_ci 2288bf215546Sopenharmony_ci D3D12_HEAP_DESC heap_desc = { 0 }; 2289bf215546Sopenharmony_ci 2290bf215546Sopenharmony_ci heap_desc.SizeInBytes = pAllocateInfo->allocationSize; 2291bf215546Sopenharmony_ci if (buffer) { 2292bf215546Sopenharmony_ci heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2293bf215546Sopenharmony_ci } else if (image) { 2294bf215546Sopenharmony_ci heap_desc.Alignment = 2295bf215546Sopenharmony_ci image->vk.samples > 1 ? 2296bf215546Sopenharmony_ci D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : 2297bf215546Sopenharmony_ci D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2298bf215546Sopenharmony_ci } else { 2299bf215546Sopenharmony_ci heap_desc.Alignment = 2300bf215546Sopenharmony_ci heap_desc.SizeInBytes >= D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT ? 2301bf215546Sopenharmony_ci D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : 2302bf215546Sopenharmony_ci D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2303bf215546Sopenharmony_ci } 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_ci heap_desc.Flags = 2306bf215546Sopenharmony_ci dzn_physical_device_get_heap_flags_for_mem_type(pdevice, 2307bf215546Sopenharmony_ci pAllocateInfo->memoryTypeIndex); 2308bf215546Sopenharmony_ci 2309bf215546Sopenharmony_ci /* TODO: Unsure about this logic??? */ 2310bf215546Sopenharmony_ci mem->initial_state = D3D12_RESOURCE_STATE_COMMON; 2311bf215546Sopenharmony_ci heap_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; 2312bf215546Sopenharmony_ci heap_desc.Properties.MemoryPoolPreference = 2313bf215546Sopenharmony_ci ((mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) && 2314bf215546Sopenharmony_ci !pdevice->architecture.UMA) ? 2315bf215546Sopenharmony_ci D3D12_MEMORY_POOL_L1 : D3D12_MEMORY_POOL_L0; 2316bf215546Sopenharmony_ci if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) { 2317bf215546Sopenharmony_ci heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; 2318bf215546Sopenharmony_ci } else if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { 2319bf215546Sopenharmony_ci heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; 2320bf215546Sopenharmony_ci } else { 2321bf215546Sopenharmony_ci heap_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE; 2322bf215546Sopenharmony_ci } 2323bf215546Sopenharmony_ci 2324bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateHeap(device->dev, &heap_desc, 2325bf215546Sopenharmony_ci &IID_ID3D12Heap, 2326bf215546Sopenharmony_ci (void **)&mem->heap))) { 2327bf215546Sopenharmony_ci dzn_device_memory_destroy(mem, pAllocator); 2328bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 2329bf215546Sopenharmony_ci } 2330bf215546Sopenharmony_ci 2331bf215546Sopenharmony_ci if ((mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && 2332bf215546Sopenharmony_ci !(heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)){ 2333bf215546Sopenharmony_ci D3D12_RESOURCE_DESC res_desc = { 0 }; 2334bf215546Sopenharmony_ci res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; 2335bf215546Sopenharmony_ci res_desc.Format = DXGI_FORMAT_UNKNOWN; 2336bf215546Sopenharmony_ci res_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2337bf215546Sopenharmony_ci res_desc.Width = heap_desc.SizeInBytes; 2338bf215546Sopenharmony_ci res_desc.Height = 1; 2339bf215546Sopenharmony_ci res_desc.DepthOrArraySize = 1; 2340bf215546Sopenharmony_ci res_desc.MipLevels = 1; 2341bf215546Sopenharmony_ci res_desc.SampleDesc.Count = 1; 2342bf215546Sopenharmony_ci res_desc.SampleDesc.Quality = 0; 2343bf215546Sopenharmony_ci res_desc.Flags = D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; 2344bf215546Sopenharmony_ci res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; 2345bf215546Sopenharmony_ci HRESULT hr = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, 0, &res_desc, 2346bf215546Sopenharmony_ci mem->initial_state, 2347bf215546Sopenharmony_ci NULL, 2348bf215546Sopenharmony_ci &IID_ID3D12Resource, 2349bf215546Sopenharmony_ci (void **)&mem->map_res); 2350bf215546Sopenharmony_ci if (FAILED(hr)) { 2351bf215546Sopenharmony_ci dzn_device_memory_destroy(mem, pAllocator); 2352bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 2353bf215546Sopenharmony_ci } 2354bf215546Sopenharmony_ci } 2355bf215546Sopenharmony_ci 2356bf215546Sopenharmony_ci *out = dzn_device_memory_to_handle(mem); 2357bf215546Sopenharmony_ci return VK_SUCCESS; 2358bf215546Sopenharmony_ci} 2359bf215546Sopenharmony_ci 2360bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2361bf215546Sopenharmony_cidzn_AllocateMemory(VkDevice device, 2362bf215546Sopenharmony_ci const VkMemoryAllocateInfo *pAllocateInfo, 2363bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2364bf215546Sopenharmony_ci VkDeviceMemory *pMem) 2365bf215546Sopenharmony_ci{ 2366bf215546Sopenharmony_ci return dzn_device_memory_create(dzn_device_from_handle(device), 2367bf215546Sopenharmony_ci pAllocateInfo, pAllocator, pMem); 2368bf215546Sopenharmony_ci} 2369bf215546Sopenharmony_ci 2370bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2371bf215546Sopenharmony_cidzn_FreeMemory(VkDevice device, 2372bf215546Sopenharmony_ci VkDeviceMemory mem, 2373bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2374bf215546Sopenharmony_ci{ 2375bf215546Sopenharmony_ci dzn_device_memory_destroy(dzn_device_memory_from_handle(mem), pAllocator); 2376bf215546Sopenharmony_ci} 2377bf215546Sopenharmony_ci 2378bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2379bf215546Sopenharmony_cidzn_MapMemory(VkDevice _device, 2380bf215546Sopenharmony_ci VkDeviceMemory _memory, 2381bf215546Sopenharmony_ci VkDeviceSize offset, 2382bf215546Sopenharmony_ci VkDeviceSize size, 2383bf215546Sopenharmony_ci VkMemoryMapFlags flags, 2384bf215546Sopenharmony_ci void **ppData) 2385bf215546Sopenharmony_ci{ 2386bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, _device); 2387bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device_memory, mem, _memory); 2388bf215546Sopenharmony_ci 2389bf215546Sopenharmony_ci if (mem == NULL) { 2390bf215546Sopenharmony_ci *ppData = NULL; 2391bf215546Sopenharmony_ci return VK_SUCCESS; 2392bf215546Sopenharmony_ci } 2393bf215546Sopenharmony_ci 2394bf215546Sopenharmony_ci if (size == VK_WHOLE_SIZE) 2395bf215546Sopenharmony_ci size = mem->size - offset; 2396bf215546Sopenharmony_ci 2397bf215546Sopenharmony_ci /* From the Vulkan spec version 1.0.32 docs for MapMemory: 2398bf215546Sopenharmony_ci * 2399bf215546Sopenharmony_ci * * If size is not equal to VK_WHOLE_SIZE, size must be greater than 0 2400bf215546Sopenharmony_ci * assert(size != 0); 2401bf215546Sopenharmony_ci * * If size is not equal to VK_WHOLE_SIZE, size must be less than or 2402bf215546Sopenharmony_ci * equal to the size of the memory minus offset 2403bf215546Sopenharmony_ci */ 2404bf215546Sopenharmony_ci assert(size > 0); 2405bf215546Sopenharmony_ci assert(offset + size <= mem->size); 2406bf215546Sopenharmony_ci 2407bf215546Sopenharmony_ci assert(mem->map_res); 2408bf215546Sopenharmony_ci D3D12_RANGE range = { 0 }; 2409bf215546Sopenharmony_ci range.Begin = offset; 2410bf215546Sopenharmony_ci range.End = offset + size; 2411bf215546Sopenharmony_ci void *map = NULL; 2412bf215546Sopenharmony_ci if (FAILED(ID3D12Resource_Map(mem->map_res, 0, &range, &map))) 2413bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED); 2414bf215546Sopenharmony_ci 2415bf215546Sopenharmony_ci mem->map = map; 2416bf215546Sopenharmony_ci mem->map_size = size; 2417bf215546Sopenharmony_ci 2418bf215546Sopenharmony_ci *ppData = ((uint8_t *) map) + offset; 2419bf215546Sopenharmony_ci 2420bf215546Sopenharmony_ci return VK_SUCCESS; 2421bf215546Sopenharmony_ci} 2422bf215546Sopenharmony_ci 2423bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2424bf215546Sopenharmony_cidzn_UnmapMemory(VkDevice _device, 2425bf215546Sopenharmony_ci VkDeviceMemory _memory) 2426bf215546Sopenharmony_ci{ 2427bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device_memory, mem, _memory); 2428bf215546Sopenharmony_ci 2429bf215546Sopenharmony_ci if (mem == NULL) 2430bf215546Sopenharmony_ci return; 2431bf215546Sopenharmony_ci 2432bf215546Sopenharmony_ci assert(mem->map_res); 2433bf215546Sopenharmony_ci ID3D12Resource_Unmap(mem->map_res, 0, NULL); 2434bf215546Sopenharmony_ci 2435bf215546Sopenharmony_ci mem->map = NULL; 2436bf215546Sopenharmony_ci mem->map_size = 0; 2437bf215546Sopenharmony_ci} 2438bf215546Sopenharmony_ci 2439bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2440bf215546Sopenharmony_cidzn_FlushMappedMemoryRanges(VkDevice _device, 2441bf215546Sopenharmony_ci uint32_t memoryRangeCount, 2442bf215546Sopenharmony_ci const VkMappedMemoryRange *pMemoryRanges) 2443bf215546Sopenharmony_ci{ 2444bf215546Sopenharmony_ci return VK_SUCCESS; 2445bf215546Sopenharmony_ci} 2446bf215546Sopenharmony_ci 2447bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2448bf215546Sopenharmony_cidzn_InvalidateMappedMemoryRanges(VkDevice _device, 2449bf215546Sopenharmony_ci uint32_t memoryRangeCount, 2450bf215546Sopenharmony_ci const VkMappedMemoryRange *pMemoryRanges) 2451bf215546Sopenharmony_ci{ 2452bf215546Sopenharmony_ci return VK_SUCCESS; 2453bf215546Sopenharmony_ci} 2454bf215546Sopenharmony_ci 2455bf215546Sopenharmony_cistatic void 2456bf215546Sopenharmony_cidzn_buffer_destroy(struct dzn_buffer *buf, const VkAllocationCallbacks *pAllocator) 2457bf215546Sopenharmony_ci{ 2458bf215546Sopenharmony_ci if (!buf) 2459bf215546Sopenharmony_ci return; 2460bf215546Sopenharmony_ci 2461bf215546Sopenharmony_ci struct dzn_device *device = container_of(buf->base.device, struct dzn_device, vk); 2462bf215546Sopenharmony_ci 2463bf215546Sopenharmony_ci if (buf->res) 2464bf215546Sopenharmony_ci ID3D12Resource_Release(buf->res); 2465bf215546Sopenharmony_ci 2466bf215546Sopenharmony_ci vk_object_base_finish(&buf->base); 2467bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, buf); 2468bf215546Sopenharmony_ci} 2469bf215546Sopenharmony_ci 2470bf215546Sopenharmony_cistatic VkResult 2471bf215546Sopenharmony_cidzn_buffer_create(struct dzn_device *device, 2472bf215546Sopenharmony_ci const VkBufferCreateInfo *pCreateInfo, 2473bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2474bf215546Sopenharmony_ci VkBuffer *out) 2475bf215546Sopenharmony_ci{ 2476bf215546Sopenharmony_ci struct dzn_buffer *buf = 2477bf215546Sopenharmony_ci vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*buf), 8, 2478bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2479bf215546Sopenharmony_ci if (!buf) 2480bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2481bf215546Sopenharmony_ci 2482bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &buf->base, VK_OBJECT_TYPE_BUFFER); 2483bf215546Sopenharmony_ci buf->create_flags = pCreateInfo->flags; 2484bf215546Sopenharmony_ci buf->size = pCreateInfo->size; 2485bf215546Sopenharmony_ci buf->usage = pCreateInfo->usage; 2486bf215546Sopenharmony_ci 2487bf215546Sopenharmony_ci if (buf->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) 2488bf215546Sopenharmony_ci buf->size = ALIGN_POT(buf->size, 256); 2489bf215546Sopenharmony_ci 2490bf215546Sopenharmony_ci buf->desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; 2491bf215546Sopenharmony_ci buf->desc.Format = DXGI_FORMAT_UNKNOWN; 2492bf215546Sopenharmony_ci buf->desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2493bf215546Sopenharmony_ci buf->desc.Width = buf->size; 2494bf215546Sopenharmony_ci buf->desc.Height = 1; 2495bf215546Sopenharmony_ci buf->desc.DepthOrArraySize = 1; 2496bf215546Sopenharmony_ci buf->desc.MipLevels = 1; 2497bf215546Sopenharmony_ci buf->desc.SampleDesc.Count = 1; 2498bf215546Sopenharmony_ci buf->desc.SampleDesc.Quality = 0; 2499bf215546Sopenharmony_ci buf->desc.Flags = D3D12_RESOURCE_FLAG_NONE; 2500bf215546Sopenharmony_ci buf->desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; 2501bf215546Sopenharmony_ci 2502bf215546Sopenharmony_ci if (buf->usage & 2503bf215546Sopenharmony_ci (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | 2504bf215546Sopenharmony_ci VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) 2505bf215546Sopenharmony_ci buf->desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; 2506bf215546Sopenharmony_ci 2507bf215546Sopenharmony_ci *out = dzn_buffer_to_handle(buf); 2508bf215546Sopenharmony_ci return VK_SUCCESS; 2509bf215546Sopenharmony_ci} 2510bf215546Sopenharmony_ci 2511bf215546Sopenharmony_ciDXGI_FORMAT 2512bf215546Sopenharmony_cidzn_buffer_get_dxgi_format(VkFormat format) 2513bf215546Sopenharmony_ci{ 2514bf215546Sopenharmony_ci enum pipe_format pfmt = vk_format_to_pipe_format(format); 2515bf215546Sopenharmony_ci 2516bf215546Sopenharmony_ci return dzn_pipe_to_dxgi_format(pfmt); 2517bf215546Sopenharmony_ci} 2518bf215546Sopenharmony_ci 2519bf215546Sopenharmony_ciD3D12_TEXTURE_COPY_LOCATION 2520bf215546Sopenharmony_cidzn_buffer_get_copy_loc(const struct dzn_buffer *buf, 2521bf215546Sopenharmony_ci VkFormat format, 2522bf215546Sopenharmony_ci const VkBufferImageCopy2 *region, 2523bf215546Sopenharmony_ci VkImageAspectFlagBits aspect, 2524bf215546Sopenharmony_ci uint32_t layer) 2525bf215546Sopenharmony_ci{ 2526bf215546Sopenharmony_ci const uint32_t buffer_row_length = 2527bf215546Sopenharmony_ci region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width; 2528bf215546Sopenharmony_ci 2529bf215546Sopenharmony_ci VkFormat plane_format = dzn_image_get_plane_format(format, aspect); 2530bf215546Sopenharmony_ci 2531bf215546Sopenharmony_ci enum pipe_format pfmt = vk_format_to_pipe_format(plane_format); 2532bf215546Sopenharmony_ci uint32_t blksz = util_format_get_blocksize(pfmt); 2533bf215546Sopenharmony_ci uint32_t blkw = util_format_get_blockwidth(pfmt); 2534bf215546Sopenharmony_ci uint32_t blkh = util_format_get_blockheight(pfmt); 2535bf215546Sopenharmony_ci 2536bf215546Sopenharmony_ci D3D12_TEXTURE_COPY_LOCATION loc = { 2537bf215546Sopenharmony_ci .pResource = buf->res, 2538bf215546Sopenharmony_ci .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, 2539bf215546Sopenharmony_ci .PlacedFootprint = { 2540bf215546Sopenharmony_ci .Footprint = { 2541bf215546Sopenharmony_ci .Format = 2542bf215546Sopenharmony_ci dzn_image_get_placed_footprint_format(format, aspect), 2543bf215546Sopenharmony_ci .Width = region->imageExtent.width, 2544bf215546Sopenharmony_ci .Height = region->imageExtent.height, 2545bf215546Sopenharmony_ci .Depth = region->imageExtent.depth, 2546bf215546Sopenharmony_ci .RowPitch = blksz * DIV_ROUND_UP(buffer_row_length, blkw), 2547bf215546Sopenharmony_ci }, 2548bf215546Sopenharmony_ci }, 2549bf215546Sopenharmony_ci }; 2550bf215546Sopenharmony_ci 2551bf215546Sopenharmony_ci uint32_t buffer_layer_stride = 2552bf215546Sopenharmony_ci loc.PlacedFootprint.Footprint.RowPitch * 2553bf215546Sopenharmony_ci DIV_ROUND_UP(loc.PlacedFootprint.Footprint.Height, blkh); 2554bf215546Sopenharmony_ci 2555bf215546Sopenharmony_ci loc.PlacedFootprint.Offset = 2556bf215546Sopenharmony_ci region->bufferOffset + (layer * buffer_layer_stride); 2557bf215546Sopenharmony_ci 2558bf215546Sopenharmony_ci return loc; 2559bf215546Sopenharmony_ci} 2560bf215546Sopenharmony_ci 2561bf215546Sopenharmony_ciD3D12_TEXTURE_COPY_LOCATION 2562bf215546Sopenharmony_cidzn_buffer_get_line_copy_loc(const struct dzn_buffer *buf, VkFormat format, 2563bf215546Sopenharmony_ci const VkBufferImageCopy2 *region, 2564bf215546Sopenharmony_ci const D3D12_TEXTURE_COPY_LOCATION *loc, 2565bf215546Sopenharmony_ci uint32_t y, uint32_t z, uint32_t *start_x) 2566bf215546Sopenharmony_ci{ 2567bf215546Sopenharmony_ci uint32_t buffer_row_length = 2568bf215546Sopenharmony_ci region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width; 2569bf215546Sopenharmony_ci uint32_t buffer_image_height = 2570bf215546Sopenharmony_ci region->bufferImageHeight ? region->bufferImageHeight : region->imageExtent.height; 2571bf215546Sopenharmony_ci 2572bf215546Sopenharmony_ci format = dzn_image_get_plane_format(format, region->imageSubresource.aspectMask); 2573bf215546Sopenharmony_ci 2574bf215546Sopenharmony_ci enum pipe_format pfmt = vk_format_to_pipe_format(format); 2575bf215546Sopenharmony_ci uint32_t blksz = util_format_get_blocksize(pfmt); 2576bf215546Sopenharmony_ci uint32_t blkw = util_format_get_blockwidth(pfmt); 2577bf215546Sopenharmony_ci uint32_t blkh = util_format_get_blockheight(pfmt); 2578bf215546Sopenharmony_ci uint32_t blkd = util_format_get_blockdepth(pfmt); 2579bf215546Sopenharmony_ci D3D12_TEXTURE_COPY_LOCATION new_loc = *loc; 2580bf215546Sopenharmony_ci uint32_t buffer_row_stride = 2581bf215546Sopenharmony_ci DIV_ROUND_UP(buffer_row_length, blkw) * blksz; 2582bf215546Sopenharmony_ci uint32_t buffer_layer_stride = 2583bf215546Sopenharmony_ci buffer_row_stride * 2584bf215546Sopenharmony_ci DIV_ROUND_UP(buffer_image_height, blkh); 2585bf215546Sopenharmony_ci 2586bf215546Sopenharmony_ci uint64_t tex_offset = 2587bf215546Sopenharmony_ci ((y / blkh) * buffer_row_stride) + 2588bf215546Sopenharmony_ci ((z / blkd) * buffer_layer_stride); 2589bf215546Sopenharmony_ci uint64_t offset = loc->PlacedFootprint.Offset + tex_offset; 2590bf215546Sopenharmony_ci uint32_t offset_alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; 2591bf215546Sopenharmony_ci 2592bf215546Sopenharmony_ci while (offset_alignment % blksz) 2593bf215546Sopenharmony_ci offset_alignment += D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; 2594bf215546Sopenharmony_ci 2595bf215546Sopenharmony_ci new_loc.PlacedFootprint.Footprint.Height = blkh; 2596bf215546Sopenharmony_ci new_loc.PlacedFootprint.Footprint.Depth = 1; 2597bf215546Sopenharmony_ci new_loc.PlacedFootprint.Offset = (offset / offset_alignment) * offset_alignment; 2598bf215546Sopenharmony_ci *start_x = ((offset % offset_alignment) / blksz) * blkw; 2599bf215546Sopenharmony_ci new_loc.PlacedFootprint.Footprint.Width = *start_x + region->imageExtent.width; 2600bf215546Sopenharmony_ci new_loc.PlacedFootprint.Footprint.RowPitch = 2601bf215546Sopenharmony_ci ALIGN_POT(DIV_ROUND_UP(new_loc.PlacedFootprint.Footprint.Width, blkw) * blksz, 2602bf215546Sopenharmony_ci D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); 2603bf215546Sopenharmony_ci return new_loc; 2604bf215546Sopenharmony_ci} 2605bf215546Sopenharmony_ci 2606bf215546Sopenharmony_cibool 2607bf215546Sopenharmony_cidzn_buffer_supports_region_copy(const D3D12_TEXTURE_COPY_LOCATION *loc) 2608bf215546Sopenharmony_ci{ 2609bf215546Sopenharmony_ci return !(loc->PlacedFootprint.Offset & (D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT - 1)) && 2610bf215546Sopenharmony_ci !(loc->PlacedFootprint.Footprint.RowPitch & (D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1)); 2611bf215546Sopenharmony_ci} 2612bf215546Sopenharmony_ci 2613bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2614bf215546Sopenharmony_cidzn_CreateBuffer(VkDevice device, 2615bf215546Sopenharmony_ci const VkBufferCreateInfo *pCreateInfo, 2616bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2617bf215546Sopenharmony_ci VkBuffer *pBuffer) 2618bf215546Sopenharmony_ci{ 2619bf215546Sopenharmony_ci return dzn_buffer_create(dzn_device_from_handle(device), 2620bf215546Sopenharmony_ci pCreateInfo, pAllocator, pBuffer); 2621bf215546Sopenharmony_ci} 2622bf215546Sopenharmony_ci 2623bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2624bf215546Sopenharmony_cidzn_DestroyBuffer(VkDevice device, 2625bf215546Sopenharmony_ci VkBuffer buffer, 2626bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2627bf215546Sopenharmony_ci{ 2628bf215546Sopenharmony_ci dzn_buffer_destroy(dzn_buffer_from_handle(buffer), pAllocator); 2629bf215546Sopenharmony_ci} 2630bf215546Sopenharmony_ci 2631bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2632bf215546Sopenharmony_cidzn_GetBufferMemoryRequirements2(VkDevice dev, 2633bf215546Sopenharmony_ci const VkBufferMemoryRequirementsInfo2 *pInfo, 2634bf215546Sopenharmony_ci VkMemoryRequirements2 *pMemoryRequirements) 2635bf215546Sopenharmony_ci{ 2636bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, dev); 2637bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_buffer, buffer, pInfo->buffer); 2638bf215546Sopenharmony_ci struct dzn_physical_device *pdev = 2639bf215546Sopenharmony_ci container_of(device->vk.physical, struct dzn_physical_device, vk); 2640bf215546Sopenharmony_ci 2641bf215546Sopenharmony_ci /* uh, this is grossly over-estimating things */ 2642bf215546Sopenharmony_ci uint32_t alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; 2643bf215546Sopenharmony_ci VkDeviceSize size = buffer->size; 2644bf215546Sopenharmony_ci 2645bf215546Sopenharmony_ci if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) { 2646bf215546Sopenharmony_ci alignment = MAX2(alignment, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); 2647bf215546Sopenharmony_ci size = ALIGN_POT(size, D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT); 2648bf215546Sopenharmony_ci } 2649bf215546Sopenharmony_ci 2650bf215546Sopenharmony_ci pMemoryRequirements->memoryRequirements.size = size; 2651bf215546Sopenharmony_ci pMemoryRequirements->memoryRequirements.alignment = alignment; 2652bf215546Sopenharmony_ci pMemoryRequirements->memoryRequirements.memoryTypeBits = 2653bf215546Sopenharmony_ci dzn_physical_device_get_mem_type_mask_for_resource(pdev, &buffer->desc); 2654bf215546Sopenharmony_ci 2655bf215546Sopenharmony_ci vk_foreach_struct(ext, pMemoryRequirements->pNext) { 2656bf215546Sopenharmony_ci switch (ext->sType) { 2657bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { 2658bf215546Sopenharmony_ci VkMemoryDedicatedRequirements *requirements = 2659bf215546Sopenharmony_ci (VkMemoryDedicatedRequirements *)ext; 2660bf215546Sopenharmony_ci /* TODO: figure out dedicated allocations */ 2661bf215546Sopenharmony_ci requirements->prefersDedicatedAllocation = false; 2662bf215546Sopenharmony_ci requirements->requiresDedicatedAllocation = false; 2663bf215546Sopenharmony_ci break; 2664bf215546Sopenharmony_ci } 2665bf215546Sopenharmony_ci 2666bf215546Sopenharmony_ci default: 2667bf215546Sopenharmony_ci dzn_debug_ignored_stype(ext->sType); 2668bf215546Sopenharmony_ci break; 2669bf215546Sopenharmony_ci } 2670bf215546Sopenharmony_ci } 2671bf215546Sopenharmony_ci 2672bf215546Sopenharmony_ci#if 0 2673bf215546Sopenharmony_ci D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo( 2674bf215546Sopenharmony_ci UINT visibleMask, 2675bf215546Sopenharmony_ci UINT numResourceDescs, 2676bf215546Sopenharmony_ci const D3D12_RESOURCE_DESC *pResourceDescs); 2677bf215546Sopenharmony_ci#endif 2678bf215546Sopenharmony_ci} 2679bf215546Sopenharmony_ci 2680bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2681bf215546Sopenharmony_cidzn_BindBufferMemory2(VkDevice _device, 2682bf215546Sopenharmony_ci uint32_t bindInfoCount, 2683bf215546Sopenharmony_ci const VkBindBufferMemoryInfo *pBindInfos) 2684bf215546Sopenharmony_ci{ 2685bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, _device); 2686bf215546Sopenharmony_ci 2687bf215546Sopenharmony_ci for (uint32_t i = 0; i < bindInfoCount; i++) { 2688bf215546Sopenharmony_ci assert(pBindInfos[i].sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO); 2689bf215546Sopenharmony_ci 2690bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device_memory, mem, pBindInfos[i].memory); 2691bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_buffer, buffer, pBindInfos[i].buffer); 2692bf215546Sopenharmony_ci 2693bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, 2694bf215546Sopenharmony_ci pBindInfos[i].memoryOffset, 2695bf215546Sopenharmony_ci &buffer->desc, 2696bf215546Sopenharmony_ci mem->initial_state, 2697bf215546Sopenharmony_ci NULL, 2698bf215546Sopenharmony_ci &IID_ID3D12Resource, 2699bf215546Sopenharmony_ci (void **)&buffer->res))) 2700bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2701bf215546Sopenharmony_ci } 2702bf215546Sopenharmony_ci 2703bf215546Sopenharmony_ci return VK_SUCCESS; 2704bf215546Sopenharmony_ci} 2705bf215546Sopenharmony_ci 2706bf215546Sopenharmony_cistatic void 2707bf215546Sopenharmony_cidzn_event_destroy(struct dzn_event *event, 2708bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2709bf215546Sopenharmony_ci{ 2710bf215546Sopenharmony_ci if (!event) 2711bf215546Sopenharmony_ci return; 2712bf215546Sopenharmony_ci 2713bf215546Sopenharmony_ci struct dzn_device *device = 2714bf215546Sopenharmony_ci container_of(event->base.device, struct dzn_device, vk); 2715bf215546Sopenharmony_ci 2716bf215546Sopenharmony_ci if (event->fence) 2717bf215546Sopenharmony_ci ID3D12Fence_Release(event->fence); 2718bf215546Sopenharmony_ci 2719bf215546Sopenharmony_ci vk_object_base_finish(&event->base); 2720bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, event); 2721bf215546Sopenharmony_ci} 2722bf215546Sopenharmony_ci 2723bf215546Sopenharmony_cistatic VkResult 2724bf215546Sopenharmony_cidzn_event_create(struct dzn_device *device, 2725bf215546Sopenharmony_ci const VkEventCreateInfo *pCreateInfo, 2726bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2727bf215546Sopenharmony_ci VkEvent *out) 2728bf215546Sopenharmony_ci{ 2729bf215546Sopenharmony_ci struct dzn_event *event = 2730bf215546Sopenharmony_ci vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*event), 8, 2731bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2732bf215546Sopenharmony_ci if (!event) 2733bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2734bf215546Sopenharmony_ci 2735bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT); 2736bf215546Sopenharmony_ci 2737bf215546Sopenharmony_ci if (FAILED(ID3D12Device1_CreateFence(device->dev, 0, D3D12_FENCE_FLAG_NONE, 2738bf215546Sopenharmony_ci &IID_ID3D12Fence, 2739bf215546Sopenharmony_ci (void **)&event->fence))) { 2740bf215546Sopenharmony_ci dzn_event_destroy(event, pAllocator); 2741bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2742bf215546Sopenharmony_ci } 2743bf215546Sopenharmony_ci 2744bf215546Sopenharmony_ci *out = dzn_event_to_handle(event); 2745bf215546Sopenharmony_ci return VK_SUCCESS; 2746bf215546Sopenharmony_ci} 2747bf215546Sopenharmony_ci 2748bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2749bf215546Sopenharmony_cidzn_CreateEvent(VkDevice device, 2750bf215546Sopenharmony_ci const VkEventCreateInfo *pCreateInfo, 2751bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2752bf215546Sopenharmony_ci VkEvent *pEvent) 2753bf215546Sopenharmony_ci{ 2754bf215546Sopenharmony_ci return dzn_event_create(dzn_device_from_handle(device), 2755bf215546Sopenharmony_ci pCreateInfo, pAllocator, pEvent); 2756bf215546Sopenharmony_ci} 2757bf215546Sopenharmony_ci 2758bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2759bf215546Sopenharmony_cidzn_DestroyEvent(VkDevice device, 2760bf215546Sopenharmony_ci VkEvent event, 2761bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2762bf215546Sopenharmony_ci{ 2763bf215546Sopenharmony_ci dzn_event_destroy(dzn_event_from_handle(event), pAllocator); 2764bf215546Sopenharmony_ci} 2765bf215546Sopenharmony_ci 2766bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2767bf215546Sopenharmony_cidzn_ResetEvent(VkDevice dev, 2768bf215546Sopenharmony_ci VkEvent evt) 2769bf215546Sopenharmony_ci{ 2770bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, dev); 2771bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_event, event, evt); 2772bf215546Sopenharmony_ci 2773bf215546Sopenharmony_ci if (FAILED(ID3D12Fence_Signal(event->fence, 0))) 2774bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 2775bf215546Sopenharmony_ci 2776bf215546Sopenharmony_ci return VK_SUCCESS; 2777bf215546Sopenharmony_ci} 2778bf215546Sopenharmony_ci 2779bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2780bf215546Sopenharmony_cidzn_SetEvent(VkDevice dev, 2781bf215546Sopenharmony_ci VkEvent evt) 2782bf215546Sopenharmony_ci{ 2783bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device, device, dev); 2784bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_event, event, evt); 2785bf215546Sopenharmony_ci 2786bf215546Sopenharmony_ci if (FAILED(ID3D12Fence_Signal(event->fence, 1))) 2787bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 2788bf215546Sopenharmony_ci 2789bf215546Sopenharmony_ci return VK_SUCCESS; 2790bf215546Sopenharmony_ci} 2791bf215546Sopenharmony_ci 2792bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2793bf215546Sopenharmony_cidzn_GetEventStatus(VkDevice device, 2794bf215546Sopenharmony_ci VkEvent evt) 2795bf215546Sopenharmony_ci{ 2796bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_event, event, evt); 2797bf215546Sopenharmony_ci 2798bf215546Sopenharmony_ci return ID3D12Fence_GetCompletedValue(event->fence) == 0 ? 2799bf215546Sopenharmony_ci VK_EVENT_RESET : VK_EVENT_SET; 2800bf215546Sopenharmony_ci} 2801bf215546Sopenharmony_ci 2802bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2803bf215546Sopenharmony_cidzn_GetDeviceMemoryCommitment(VkDevice device, 2804bf215546Sopenharmony_ci VkDeviceMemory memory, 2805bf215546Sopenharmony_ci VkDeviceSize *pCommittedMemoryInBytes) 2806bf215546Sopenharmony_ci{ 2807bf215546Sopenharmony_ci VK_FROM_HANDLE(dzn_device_memory, mem, memory); 2808bf215546Sopenharmony_ci 2809bf215546Sopenharmony_ci // TODO: find if there's a way to query/track actual heap residency 2810bf215546Sopenharmony_ci *pCommittedMemoryInBytes = mem->size; 2811bf215546Sopenharmony_ci} 2812bf215546Sopenharmony_ci 2813bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2814bf215546Sopenharmony_cidzn_QueueBindSparse(VkQueue queue, 2815bf215546Sopenharmony_ci uint32_t bindInfoCount, 2816bf215546Sopenharmony_ci const VkBindSparseInfo *pBindInfo, 2817bf215546Sopenharmony_ci VkFence fence) 2818bf215546Sopenharmony_ci{ 2819bf215546Sopenharmony_ci // FIXME: add proper implem 2820bf215546Sopenharmony_ci dzn_stub(); 2821bf215546Sopenharmony_ci return VK_SUCCESS; 2822bf215546Sopenharmony_ci} 2823bf215546Sopenharmony_ci 2824bf215546Sopenharmony_cistatic D3D12_TEXTURE_ADDRESS_MODE 2825bf215546Sopenharmony_cidzn_sampler_translate_addr_mode(VkSamplerAddressMode in) 2826bf215546Sopenharmony_ci{ 2827bf215546Sopenharmony_ci switch (in) { 2828bf215546Sopenharmony_ci case VK_SAMPLER_ADDRESS_MODE_REPEAT: return D3D12_TEXTURE_ADDRESS_MODE_WRAP; 2829bf215546Sopenharmony_ci case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; 2830bf215546Sopenharmony_ci case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; 2831bf215546Sopenharmony_ci case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_BORDER; 2832bf215546Sopenharmony_ci default: unreachable("Invalid address mode"); 2833bf215546Sopenharmony_ci } 2834bf215546Sopenharmony_ci} 2835bf215546Sopenharmony_ci 2836bf215546Sopenharmony_cistatic void 2837bf215546Sopenharmony_cidzn_sampler_destroy(struct dzn_sampler *sampler, 2838bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2839bf215546Sopenharmony_ci{ 2840bf215546Sopenharmony_ci if (!sampler) 2841bf215546Sopenharmony_ci return; 2842bf215546Sopenharmony_ci 2843bf215546Sopenharmony_ci struct dzn_device *device = 2844bf215546Sopenharmony_ci container_of(sampler->base.device, struct dzn_device, vk); 2845bf215546Sopenharmony_ci 2846bf215546Sopenharmony_ci vk_object_base_finish(&sampler->base); 2847bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, sampler); 2848bf215546Sopenharmony_ci} 2849bf215546Sopenharmony_ci 2850bf215546Sopenharmony_cistatic VkResult 2851bf215546Sopenharmony_cidzn_sampler_create(struct dzn_device *device, 2852bf215546Sopenharmony_ci const VkSamplerCreateInfo *pCreateInfo, 2853bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2854bf215546Sopenharmony_ci VkSampler *out) 2855bf215546Sopenharmony_ci{ 2856bf215546Sopenharmony_ci struct dzn_sampler *sampler = 2857bf215546Sopenharmony_ci vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*sampler), 8, 2858bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2859bf215546Sopenharmony_ci if (!sampler) 2860bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2861bf215546Sopenharmony_ci 2862bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &sampler->base, VK_OBJECT_TYPE_SAMPLER); 2863bf215546Sopenharmony_ci 2864bf215546Sopenharmony_ci const VkSamplerCustomBorderColorCreateInfoEXT *pBorderColor = (const VkSamplerCustomBorderColorCreateInfoEXT *) 2865bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT); 2866bf215546Sopenharmony_ci 2867bf215546Sopenharmony_ci /* TODO: have a sampler pool to allocate shader-invisible descs which we 2868bf215546Sopenharmony_ci * can copy to the desc_set when UpdateDescriptorSets() is called. 2869bf215546Sopenharmony_ci */ 2870bf215546Sopenharmony_ci sampler->desc.Filter = dzn_translate_sampler_filter(pCreateInfo); 2871bf215546Sopenharmony_ci sampler->desc.AddressU = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeU); 2872bf215546Sopenharmony_ci sampler->desc.AddressV = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeV); 2873bf215546Sopenharmony_ci sampler->desc.AddressW = dzn_sampler_translate_addr_mode(pCreateInfo->addressModeW); 2874bf215546Sopenharmony_ci sampler->desc.MipLODBias = pCreateInfo->mipLodBias; 2875bf215546Sopenharmony_ci sampler->desc.MaxAnisotropy = pCreateInfo->maxAnisotropy; 2876bf215546Sopenharmony_ci sampler->desc.MinLOD = pCreateInfo->minLod; 2877bf215546Sopenharmony_ci sampler->desc.MaxLOD = pCreateInfo->maxLod; 2878bf215546Sopenharmony_ci 2879bf215546Sopenharmony_ci if (pCreateInfo->compareEnable) 2880bf215546Sopenharmony_ci sampler->desc.ComparisonFunc = dzn_translate_compare_op(pCreateInfo->compareOp); 2881bf215546Sopenharmony_ci 2882bf215546Sopenharmony_ci bool reads_border_color = 2883bf215546Sopenharmony_ci pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || 2884bf215546Sopenharmony_ci pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || 2885bf215546Sopenharmony_ci pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; 2886bf215546Sopenharmony_ci 2887bf215546Sopenharmony_ci if (reads_border_color) { 2888bf215546Sopenharmony_ci switch (pCreateInfo->borderColor) { 2889bf215546Sopenharmony_ci case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: 2890bf215546Sopenharmony_ci case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: 2891bf215546Sopenharmony_ci sampler->desc.BorderColor[0] = 0.0f; 2892bf215546Sopenharmony_ci sampler->desc.BorderColor[1] = 0.0f; 2893bf215546Sopenharmony_ci sampler->desc.BorderColor[2] = 0.0f; 2894bf215546Sopenharmony_ci sampler->desc.BorderColor[3] = 2895bf215546Sopenharmony_ci pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ? 0.0f : 1.0f; 2896bf215546Sopenharmony_ci sampler->static_border_color = 2897bf215546Sopenharmony_ci pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK ? 2898bf215546Sopenharmony_ci D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK : 2899bf215546Sopenharmony_ci D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK; 2900bf215546Sopenharmony_ci break; 2901bf215546Sopenharmony_ci case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: 2902bf215546Sopenharmony_ci sampler->desc.BorderColor[0] = sampler->desc.BorderColor[1] = 1.0f; 2903bf215546Sopenharmony_ci sampler->desc.BorderColor[2] = sampler->desc.BorderColor[3] = 1.0f; 2904bf215546Sopenharmony_ci sampler->static_border_color = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE; 2905bf215546Sopenharmony_ci break; 2906bf215546Sopenharmony_ci case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT: 2907bf215546Sopenharmony_ci sampler->static_border_color = (D3D12_STATIC_BORDER_COLOR)-1; 2908bf215546Sopenharmony_ci for (unsigned i = 0; i < ARRAY_SIZE(sampler->desc.BorderColor); i++) 2909bf215546Sopenharmony_ci sampler->desc.BorderColor[i] = pBorderColor->customBorderColor.float32[i]; 2910bf215546Sopenharmony_ci break; 2911bf215546Sopenharmony_ci case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: 2912bf215546Sopenharmony_ci case VK_BORDER_COLOR_INT_OPAQUE_BLACK: 2913bf215546Sopenharmony_ci case VK_BORDER_COLOR_INT_OPAQUE_WHITE: 2914bf215546Sopenharmony_ci case VK_BORDER_COLOR_INT_CUSTOM_EXT: 2915bf215546Sopenharmony_ci /* FIXME: sampling from integer textures is not supported yet. */ 2916bf215546Sopenharmony_ci sampler->static_border_color = (D3D12_STATIC_BORDER_COLOR)-1; 2917bf215546Sopenharmony_ci break; 2918bf215546Sopenharmony_ci default: 2919bf215546Sopenharmony_ci unreachable("Unsupported border color"); 2920bf215546Sopenharmony_ci } 2921bf215546Sopenharmony_ci } 2922bf215546Sopenharmony_ci 2923bf215546Sopenharmony_ci *out = dzn_sampler_to_handle(sampler); 2924bf215546Sopenharmony_ci return VK_SUCCESS; 2925bf215546Sopenharmony_ci} 2926bf215546Sopenharmony_ci 2927bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2928bf215546Sopenharmony_cidzn_CreateSampler(VkDevice device, 2929bf215546Sopenharmony_ci const VkSamplerCreateInfo *pCreateInfo, 2930bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2931bf215546Sopenharmony_ci VkSampler *pSampler) 2932bf215546Sopenharmony_ci{ 2933bf215546Sopenharmony_ci return dzn_sampler_create(dzn_device_from_handle(device), 2934bf215546Sopenharmony_ci pCreateInfo, pAllocator, pSampler); 2935bf215546Sopenharmony_ci} 2936bf215546Sopenharmony_ci 2937bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2938bf215546Sopenharmony_cidzn_DestroySampler(VkDevice device, 2939bf215546Sopenharmony_ci VkSampler sampler, 2940bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2941bf215546Sopenharmony_ci{ 2942bf215546Sopenharmony_ci dzn_sampler_destroy(dzn_sampler_from_handle(sampler), pAllocator); 2943bf215546Sopenharmony_ci} 2944bf215546Sopenharmony_ci 2945bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2946bf215546Sopenharmony_cidzn_GetDeviceGroupPeerMemoryFeatures(VkDevice device, 2947bf215546Sopenharmony_ci uint32_t heapIndex, 2948bf215546Sopenharmony_ci uint32_t localDeviceIndex, 2949bf215546Sopenharmony_ci uint32_t remoteDeviceIndex, 2950bf215546Sopenharmony_ci VkPeerMemoryFeatureFlags *pPeerMemoryFeatures) 2951bf215546Sopenharmony_ci{ 2952bf215546Sopenharmony_ci *pPeerMemoryFeatures = 0; 2953bf215546Sopenharmony_ci} 2954bf215546Sopenharmony_ci 2955bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2956bf215546Sopenharmony_cidzn_GetImageSparseMemoryRequirements2(VkDevice device, 2957bf215546Sopenharmony_ci const VkImageSparseMemoryRequirementsInfo2* pInfo, 2958bf215546Sopenharmony_ci uint32_t *pSparseMemoryRequirementCount, 2959bf215546Sopenharmony_ci VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 2960bf215546Sopenharmony_ci{ 2961bf215546Sopenharmony_ci *pSparseMemoryRequirementCount = 0; 2962bf215546Sopenharmony_ci} 2963bf215546Sopenharmony_ci 2964bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 2965bf215546Sopenharmony_cidzn_CreateSamplerYcbcrConversion(VkDevice device, 2966bf215546Sopenharmony_ci const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 2967bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 2968bf215546Sopenharmony_ci VkSamplerYcbcrConversion *pYcbcrConversion) 2969bf215546Sopenharmony_ci{ 2970bf215546Sopenharmony_ci unreachable("Ycbcr sampler conversion is not supported"); 2971bf215546Sopenharmony_ci return VK_SUCCESS; 2972bf215546Sopenharmony_ci} 2973bf215546Sopenharmony_ci 2974bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2975bf215546Sopenharmony_cidzn_DestroySamplerYcbcrConversion(VkDevice device, 2976bf215546Sopenharmony_ci VkSamplerYcbcrConversion YcbcrConversion, 2977bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 2978bf215546Sopenharmony_ci{ 2979bf215546Sopenharmony_ci unreachable("Ycbcr sampler conversion is not supported"); 2980bf215546Sopenharmony_ci} 2981