diff options
Diffstat (limited to 'drivers/d3d12/d3d12_context.cpp')
-rw-r--r-- | drivers/d3d12/d3d12_context.cpp | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/drivers/d3d12/d3d12_context.cpp b/drivers/d3d12/d3d12_context.cpp index 36492b198b..da112d8376 100644 --- a/drivers/d3d12/d3d12_context.cpp +++ b/drivers/d3d12/d3d12_context.cpp @@ -57,25 +57,13 @@ #include <dxguids.h> #endif +// Note: symbol is not available in MinGW and old MSVC import libraries. +const CLSID CLSID_D3D12DeviceFactoryGodot = __uuidof(ID3D12DeviceFactory); +const CLSID CLSID_D3D12DebugGodot = __uuidof(ID3D12Debug); +const CLSID CLSID_D3D12SDKConfigurationGodot = __uuidof(ID3D12SDKConfiguration); + extern "C" { char godot_nir_arch_name[32]; - -#ifdef AGILITY_SDK_ENABLED -__declspec(dllexport) extern const UINT D3D12SDKVersion = 610; -#ifdef AGILITY_SDK_MULTIARCH_ENABLED -#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\arm64"; -#elif defined(__arm__) || defined(_M_ARM) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\arm32"; -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\x86_64"; -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\x86_32"; -#endif -#else -__declspec(dllexport) extern const char *D3D12SDKPath = "\\."; -#endif // AGILITY_SDK_MULTIARCH -#endif // AGILITY_SDK_ENABLED } #ifdef PIX_ENABLED @@ -89,6 +77,8 @@ __declspec(dllexport) extern const char *D3D12SDKPath = "\\."; #endif #endif +#define D3D12_DEBUG_LAYER_BREAK_ON_ERROR 0 + void D3D12Context::_debug_message_func( D3D12_MESSAGE_CATEGORY p_category, D3D12_MESSAGE_SEVERITY p_severity, @@ -237,6 +227,13 @@ Error D3D12Context::_check_capabilities() { } } + D3D12_FEATURE_DATA_D3D12_OPTIONS4 options4 = {}; + res = md.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &options4, sizeof(options4)); + if (SUCCEEDED(res)) { + shader_capabilities.native_16bit_ops = options4.Native16BitShaderOpsSupported; + } + print_verbose(String(" 16-bit ops supported: ") + (shader_capabilities.native_16bit_ops ? "yes" : "no")); + D3D12_FEATURE_DATA_D3D12_OPTIONS6 options6 = {}; res = md.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6)); if (SUCCEEDED(res)) { @@ -295,7 +292,12 @@ Error D3D12Context::_check_capabilities() { Error D3D12Context::_initialize_debug_layers() { ComPtr<ID3D12Debug> debug_controller; - HRESULT res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); + HRESULT res; + if (device_factory) { + res = device_factory->GetConfigurationInterface(CLSID_D3D12DebugGodot, IID_PPV_ARGS(&debug_controller)); + } else { + res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); + } ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_QUERY_FAILED); debug_controller->EnableDebugLayer(); return OK; @@ -501,7 +503,12 @@ void D3D12Context::_dump_adapter_info(int p_index) { } Error D3D12Context::_create_device(DeviceBasics &r_basics) { - HRESULT res = D3D12CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + HRESULT res; + if (device_factory) { + res = device_factory->CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + } else { + res = D3D12CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + } ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); // Create direct command queue. @@ -522,9 +529,8 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) { res = r_basics.device.As(&info_queue); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); -#if 0 // This causes crashes. Needs investigation. ComPtr<ID3D12InfoQueue1> info_queue_1; - device.As(&info_queue_1); + r_basics.device.As(&info_queue_1); if (info_queue_1) { // Custom printing supported (added in Windows 10 Release Preview build 20236). @@ -532,9 +538,7 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) { res = info_queue_1->RegisterMessageCallback(&_debug_message_func, D3D12_MESSAGE_CALLBACK_IGNORE_FILTERS, nullptr, 0); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); - } else -#endif - { + } else { // Rely on D3D12's own debug printing. if (Engine::get_singleton()->is_abort_on_gpu_errors_enabled()) { @@ -566,6 +570,11 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) { res = info_queue->PushStorageFilter(&filter); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); + +#if D3D12_DEBUG_LAYER_BREAK_ON_ERROR + res = info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true); + ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); +#endif } return OK; @@ -808,7 +817,32 @@ Error D3D12Context::_update_swap_chain(Window *window) { return OK; } +void D3D12Context::_init_device_factory() { + uint32_t agility_sdk_version = GLOBAL_GET("rendering/rendering_device/d3d12/agility_sdk_version"); + String agility_sdk_path = String(".\\") + Engine::get_singleton()->get_architecture_name(); + + // Note: symbol is not available in MinGW import library. + PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)GetProcAddress(LoadLibraryW(L"D3D12.dll"), "D3D12GetInterface"); + ERR_FAIL_COND(!d3d_D3D12GetInterface); + + ID3D12SDKConfiguration *sdk_config = nullptr; + if (SUCCEEDED(d3d_D3D12GetInterface(CLSID_D3D12SDKConfigurationGodot, IID_PPV_ARGS(&sdk_config)))) { + ID3D12SDKConfiguration1 *sdk_config1 = nullptr; + if (SUCCEEDED(sdk_config->QueryInterface(&sdk_config1))) { + if (SUCCEEDED(sdk_config1->CreateDeviceFactory(agility_sdk_version, agility_sdk_path.ascii().get_data(), IID_PPV_ARGS(device_factory.GetAddressOf())))) { + d3d_D3D12GetInterface(CLSID_D3D12DeviceFactoryGodot, IID_PPV_ARGS(device_factory.GetAddressOf())); + } else if (SUCCEEDED(sdk_config1->CreateDeviceFactory(agility_sdk_version, ".\\", IID_PPV_ARGS(device_factory.GetAddressOf())))) { + d3d_D3D12GetInterface(CLSID_D3D12DeviceFactoryGodot, IID_PPV_ARGS(device_factory.GetAddressOf())); + } + sdk_config1->Release(); + } + sdk_config->Release(); + } +} + Error D3D12Context::initialize() { + _init_device_factory(); + if (_use_validation_layers()) { Error err = _initialize_debug_layers(); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); @@ -867,7 +901,9 @@ void D3D12Context::_wait_for_idle_queue(ID3D12CommandQueue *p_queue) { #endif } -void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending) { +void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending, bool p_sync) { + ERR_FAIL_COND_MSG(!p_sync, "Flush without sync is not supported."); // This is a special case for Vulkan on mobile XR hardware, not applicable to D3D12 + if (p_flush_setup && command_list_queue[0]) { md.queue->ExecuteCommandLists(1, command_list_queue.ptr()); command_list_queue[0] = nullptr; @@ -1032,27 +1068,6 @@ void D3D12Context::local_device_free(RID p_local_device) { local_device_owner.free(p_local_device); } -void D3D12Context::command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) { -#ifdef PIX_ENABLED - const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id; - PIXBeginEvent(cmd_buf_info->cmd_list.Get(), p_color.to_argb32(), p_label_name.utf8().get_data()); -#endif -} - -void D3D12Context::command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) { -#ifdef PIX_ENABLED - const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id; - PIXSetMarker(cmd_buf_info->cmd_list.Get(), p_color.to_argb32(), p_label_name.utf8().get_data()); -#endif -} - -void D3D12Context::command_end_label(RDD::CommandBufferID p_command_buffer) { -#ifdef PIX_ENABLED - const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id; - PIXEndEvent(cmd_buf_info->cmd_list.Get()); -#endif -} - void D3D12Context::set_object_name(ID3D12Object *p_object, String p_object_name) { ERR_FAIL_NULL(p_object); int name_len = p_object_name.size(); @@ -1101,6 +1116,14 @@ RenderingDeviceDriver *D3D12Context::get_driver(RID p_local_device) { } } +bool D3D12Context::is_debug_utils_enabled() const { +#ifdef PIX_ENABLED + return true; +#else + return false; +#endif +} + D3D12Context::D3D12Context() { command_list_queue.resize(1); // First one is always the setup command. command_list_queue[0] = nullptr; |