Merge pull request #104207 from mbucchia/d3d12-xr
Add support for Direct3D 12 OpenXR backend
This commit is contained in:
commit
e5d1fdcfea
11 changed files with 826 additions and 6 deletions
45
drivers/d3d12/d3d12_hooks.cpp
Normal file
45
drivers/d3d12/d3d12_hooks.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/**************************************************************************/
|
||||
/* d3d12_hooks.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "d3d12_hooks.h"
|
||||
|
||||
D3D12Hooks *D3D12Hooks::singleton = nullptr;
|
||||
|
||||
D3D12Hooks::D3D12Hooks() {
|
||||
if (singleton == nullptr) {
|
||||
singleton = this;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12Hooks::~D3D12Hooks() {
|
||||
if (singleton == this) {
|
||||
singleton = nullptr;
|
||||
}
|
||||
}
|
||||
48
drivers/d3d12/d3d12_hooks.h
Normal file
48
drivers/d3d12/d3d12_hooks.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/**************************************************************************/
|
||||
/* d3d12_hooks.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rendering_device_driver_d3d12.h"
|
||||
|
||||
class D3D12Hooks {
|
||||
private:
|
||||
static D3D12Hooks *singleton;
|
||||
|
||||
public:
|
||||
D3D12Hooks();
|
||||
virtual ~D3D12Hooks();
|
||||
virtual D3D_FEATURE_LEVEL get_feature_level() const = 0;
|
||||
virtual LUID get_adapter_luid() const = 0;
|
||||
virtual void set_device(ID3D12Device *p_device) = 0;
|
||||
virtual void set_command_queue(ID3D12CommandQueue *p_queue) = 0;
|
||||
virtual void cleanup_device() = 0;
|
||||
static D3D12Hooks *get_singleton() { return singleton; }
|
||||
};
|
||||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "rendering_context_driver_d3d12.h"
|
||||
|
||||
#include "d3d12_hooks.h"
|
||||
|
||||
#include "core/config/engine.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/string/ustring.h"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "rendering_device_driver_d3d12.h"
|
||||
|
||||
#include "d3d12_hooks.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/marshalls.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
|
|
@ -1356,7 +1358,105 @@ RDD::TextureID RenderingDeviceDriverD3D12::texture_create(const TextureFormat &p
|
|||
}
|
||||
|
||||
RDD::TextureID RenderingDeviceDriverD3D12::texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) {
|
||||
ERR_FAIL_V_MSG(TextureID(), "Unimplemented!");
|
||||
ID3D12Resource *texture = (ID3D12Resource *)p_native_texture;
|
||||
|
||||
#if defined(_MSC_VER) || !defined(_WIN32)
|
||||
const D3D12_RESOURCE_DESC base_resource_desc = texture->GetDesc();
|
||||
#else
|
||||
D3D12_RESOURCE_DESC base_resource_desc;
|
||||
texture->GetDesc(&base_resource_desc);
|
||||
#endif
|
||||
CD3DX12_RESOURCE_DESC resource_desc(base_resource_desc);
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = {};
|
||||
{
|
||||
srv_desc.Format = RD_TO_D3D12_FORMAT[p_format].general_format;
|
||||
srv_desc.ViewDimension = resource_desc.SampleDesc.Count == 1 ? RD_TEXTURE_TYPE_TO_D3D12_VIEW_DIMENSION_FOR_SRV[p_type] : RD_TEXTURE_TYPE_TO_D3D12_VIEW_DIMENSION_FOR_SRV_MS[p_type];
|
||||
srv_desc.Shader4ComponentMapping = _compute_component_mapping(TextureView{ p_format });
|
||||
|
||||
switch (srv_desc.ViewDimension) {
|
||||
case D3D12_SRV_DIMENSION_TEXTURE1D: {
|
||||
srv_desc.Texture1D.MipLevels = resource_desc.MipLevels;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: {
|
||||
srv_desc.Texture1DArray.MipLevels = resource_desc.MipLevels;
|
||||
srv_desc.Texture1DArray.ArraySize = p_array_layers;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE2D: {
|
||||
srv_desc.Texture2D.MipLevels = resource_desc.MipLevels;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE2DMS: {
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: {
|
||||
srv_desc.Texture2DArray.MipLevels = resource_desc.MipLevels;
|
||||
srv_desc.Texture2DArray.ArraySize = p_array_layers;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: {
|
||||
srv_desc.Texture2DMSArray.ArraySize = p_array_layers;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: {
|
||||
srv_desc.TextureCubeArray.MipLevels = resource_desc.MipLevels;
|
||||
srv_desc.TextureCubeArray.NumCubes = p_array_layers / 6;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURE3D: {
|
||||
srv_desc.Texture3D.MipLevels = resource_desc.MipLevels;
|
||||
} break;
|
||||
case D3D12_SRV_DIMENSION_TEXTURECUBE: {
|
||||
srv_desc.TextureCube.MipLevels = resource_desc.MipLevels;
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = {};
|
||||
{
|
||||
uav_desc.Format = RD_TO_D3D12_FORMAT[p_format].general_format;
|
||||
uav_desc.ViewDimension = resource_desc.SampleDesc.Count == 1 ? RD_TEXTURE_TYPE_TO_D3D12_VIEW_DIMENSION_FOR_UAV[p_type] : D3D12_UAV_DIMENSION_UNKNOWN;
|
||||
|
||||
switch (uav_desc.ViewDimension) {
|
||||
case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: {
|
||||
uav_desc.Texture1DArray.ArraySize = p_array_layers;
|
||||
} break;
|
||||
case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: {
|
||||
// Either for an actual 2D texture array, cubemap or cubemap array.
|
||||
uav_desc.Texture2DArray.ArraySize = p_array_layers;
|
||||
} break;
|
||||
case D3D12_UAV_DIMENSION_TEXTURE3D: {
|
||||
uav_desc.Texture3D.WSize = resource_desc.Depth();
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextureInfo *tex_info = VersatileResource::allocate<TextureInfo>(resources_allocator);
|
||||
tex_info->resource = texture;
|
||||
tex_info->owner_info.resource = nullptr; // Not allocated by us.
|
||||
tex_info->owner_info.allocation = nullptr; // Not allocated by us.
|
||||
tex_info->owner_info.states.subresource_states.resize(resource_desc.MipLevels * p_array_layers);
|
||||
for (uint32_t i = 0; i < tex_info->owner_info.states.subresource_states.size(); i++) {
|
||||
tex_info->owner_info.states.subresource_states[i] = !p_depth_stencil ? D3D12_RESOURCE_STATE_RENDER_TARGET : D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||
}
|
||||
tex_info->states_ptr = &tex_info->owner_info.states;
|
||||
tex_info->format = p_format;
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
tex_info->desc = *(CD3DX12_RESOURCE_DESC *)&resource_desc;
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
tex_info->base_layer = 0;
|
||||
tex_info->layers = p_array_layers;
|
||||
tex_info->base_mip = 0;
|
||||
tex_info->mipmaps = resource_desc.MipLevels;
|
||||
tex_info->view_descs.srv = srv_desc;
|
||||
tex_info->view_descs.uav = uav_desc;
|
||||
#ifdef DEBUG_ENABLED
|
||||
tex_info->created_from_extension = true;
|
||||
#endif
|
||||
return TextureID(tex_info);
|
||||
}
|
||||
|
||||
RDD::TextureID RenderingDeviceDriverD3D12::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {
|
||||
|
|
@ -2077,6 +2177,10 @@ void RenderingDeviceDriverD3D12::command_pipeline_barrier(CommandBufferID p_cmd_
|
|||
if (texture_info->main_texture) {
|
||||
texture_info = texture_info->main_texture;
|
||||
}
|
||||
// Textures created for simultaneous access do not need explicit transitions.
|
||||
if (texture_info->desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS) {
|
||||
continue;
|
||||
}
|
||||
_rd_stages_and_access_to_d3d12(p_src_stages, texture_barrier_rd.prev_layout, texture_barrier_rd.src_access, texture_barrier_d3d12.SyncBefore, texture_barrier_d3d12.AccessBefore);
|
||||
_rd_stages_and_access_to_d3d12(p_dst_stages, texture_barrier_rd.next_layout, texture_barrier_rd.dst_access, texture_barrier_d3d12.SyncAfter, texture_barrier_d3d12.AccessAfter);
|
||||
texture_barrier_d3d12.LayoutBefore = _rd_texture_layout_to_d3d12_barrier_layout(texture_barrier_rd.prev_layout);
|
||||
|
|
@ -2126,7 +2230,9 @@ void RenderingDeviceDriverD3D12::command_pipeline_barrier(CommandBufferID p_cmd_
|
|||
barrier_group.pTextureBarriers = texture_barriers.ptr();
|
||||
}
|
||||
|
||||
cmd_list_7->Barrier(barrier_groups_count, barrier_groups);
|
||||
if (barrier_groups_count) {
|
||||
cmd_list_7->Barrier(barrier_groups_count, barrier_groups);
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
|
|
@ -2212,6 +2318,10 @@ RDD::CommandQueueID RenderingDeviceDriverD3D12::command_queue_create(CommandQueu
|
|||
HRESULT res = device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(d3d_queue.GetAddressOf()));
|
||||
ERR_FAIL_COND_V(!SUCCEEDED(res), CommandQueueID());
|
||||
|
||||
if (p_identify_as_main_queue && D3D12Hooks::get_singleton() != nullptr) {
|
||||
D3D12Hooks::get_singleton()->set_command_queue(d3d_queue.Get());
|
||||
}
|
||||
|
||||
CommandQueueInfo *command_queue = memnew(CommandQueueInfo);
|
||||
command_queue->d3d_queue = d3d_queue;
|
||||
return CommandQueueID(command_queue);
|
||||
|
|
@ -3141,6 +3251,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
|
|||
}
|
||||
|
||||
// - Link NIR shaders.
|
||||
bool can_use_multiview = D3D12Hooks::get_singleton() != nullptr;
|
||||
for (int i = SHADER_STAGE_MAX - 1; i >= 0; i--) {
|
||||
if (!stages_nir_shaders.has(i)) {
|
||||
continue;
|
||||
|
|
@ -3153,6 +3264,26 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
|
|||
break;
|
||||
}
|
||||
}
|
||||
// There is a bug in the Direct3D runtime during creation of a PSO with view instancing. If a fragment
|
||||
// shader uses front/back face detection (SV_IsFrontFace), its signature must include the pixel position
|
||||
// builtin variable (SV_Position), otherwise an Internal Runtime error will occur.
|
||||
if (i == SHADER_STAGE_FRAGMENT && can_use_multiview) {
|
||||
const bool use_front_face =
|
||||
nir_find_variable_with_location(shader, nir_var_shader_in, VARYING_SLOT_FACE) ||
|
||||
(shader->info.inputs_read & VARYING_BIT_FACE) ||
|
||||
nir_find_variable_with_location(shader, nir_var_system_value, SYSTEM_VALUE_FRONT_FACE) ||
|
||||
BITSET_TEST(shader->info.system_values_read, SYSTEM_VALUE_FRONT_FACE);
|
||||
const bool use_position =
|
||||
nir_find_variable_with_location(shader, nir_var_shader_in, VARYING_SLOT_POS) ||
|
||||
(shader->info.inputs_read & VARYING_BIT_POS) ||
|
||||
nir_find_variable_with_location(shader, nir_var_system_value, SYSTEM_VALUE_FRAG_COORD) ||
|
||||
BITSET_TEST(shader->info.system_values_read, SYSTEM_VALUE_FRAG_COORD);
|
||||
if (use_front_face && !use_position) {
|
||||
nir_variable *const pos = nir_variable_create(shader, nir_var_shader_in, glsl_vec4_type(), "gl_FragCoord");
|
||||
pos->data.location = VARYING_SLOT_POS;
|
||||
shader->info.inputs_read |= VARYING_BIT_POS;
|
||||
}
|
||||
}
|
||||
if (prev_shader) {
|
||||
bool requires_runtime_data = {};
|
||||
dxil_spirv_nir_link(shader, prev_shader, &dxil_runtime_conf, &requires_runtime_data);
|
||||
|
|
@ -5615,7 +5746,7 @@ RDD::PipelineID RenderingDeviceDriverD3D12::render_pipeline_create(
|
|||
VectorView<PipelineSpecializationConstant> p_specialization_constants) {
|
||||
const ShaderInfo *shader_info_in = (const ShaderInfo *)p_shader.id;
|
||||
|
||||
CD3DX12_PIPELINE_STATE_STREAM pipeline_desc = {};
|
||||
CD3DX12_PIPELINE_STATE_STREAM1 pipeline_desc = {};
|
||||
|
||||
const RenderPassInfo *pass_info = (const RenderPassInfo *)p_render_pass.id;
|
||||
RenderPipelineInfo render_info;
|
||||
|
|
@ -5808,6 +5939,15 @@ RDD::PipelineID RenderingDeviceDriverD3D12::render_pipeline_create(
|
|||
|
||||
render_info.dyn_params.blend_constant = p_blend_state.blend_constant;
|
||||
|
||||
// Multiview
|
||||
// We are using render target slices for each view.
|
||||
const D3D12_VIEW_INSTANCE_LOCATION viewInstanceLocations[D3D12_MAX_VIEW_INSTANCE_COUNT] = { { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 } };
|
||||
if (pass_info->view_count > 1) {
|
||||
(&pipeline_desc.ViewInstancingDesc)->ViewInstanceCount = pass_info->view_count;
|
||||
(&pipeline_desc.ViewInstancingDesc)->Flags = D3D12_VIEW_INSTANCING_FLAG_NONE;
|
||||
(&pipeline_desc.ViewInstancingDesc)->pViewInstanceLocations = viewInstanceLocations;
|
||||
}
|
||||
|
||||
// Stages bytecodes + specialization constants.
|
||||
|
||||
pipeline_desc.pRootSignature = shader_info_in->root_signature.Get();
|
||||
|
|
@ -6308,6 +6448,9 @@ RenderingDeviceDriverD3D12::RenderingDeviceDriverD3D12(RenderingContextDriverD3D
|
|||
}
|
||||
|
||||
RenderingDeviceDriverD3D12::~RenderingDeviceDriverD3D12() {
|
||||
if (D3D12Hooks::get_singleton() != nullptr) {
|
||||
D3D12Hooks::get_singleton()->cleanup_device();
|
||||
}
|
||||
glsl_type_singleton_decref();
|
||||
}
|
||||
|
||||
|
|
@ -6342,17 +6485,43 @@ Error RenderingDeviceDriverD3D12::_initialize_device() {
|
|||
d3d_D3D12EnableExperimentalFeatures(1, experimental_features, nullptr, nullptr);
|
||||
}
|
||||
|
||||
D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0;
|
||||
// Override the adapter and feature level if needed by the XR backend.
|
||||
if (D3D12Hooks::get_singleton() != nullptr) {
|
||||
const LUID adapter_luid = D3D12Hooks::get_singleton()->get_adapter_luid();
|
||||
requested_feature_level = D3D12Hooks::get_singleton()->get_feature_level();
|
||||
ComPtr<IDXGIAdapter1> desired_adapter;
|
||||
for (UINT adapter_index = 0;; adapter_index++) {
|
||||
// EnumAdapters1 will fail with DXGI_ERROR_NOT_FOUND when there are no more adapters to
|
||||
// enumerate.
|
||||
if (context_driver->dxgi_factory_get()->EnumAdapters1(adapter_index, desired_adapter.ReleaseAndGetAddressOf()) == DXGI_ERROR_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
desired_adapter->GetDesc1(&desc);
|
||||
if (!memcmp(&desc.AdapterLuid, &adapter_luid, sizeof(LUID))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ERR_FAIL_NULL_V(desired_adapter, ERR_CANT_CREATE);
|
||||
adapter = desired_adapter;
|
||||
}
|
||||
|
||||
ID3D12DeviceFactory *device_factory = context_driver->device_factory_get();
|
||||
if (device_factory != nullptr) {
|
||||
res = device_factory->CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf()));
|
||||
res = device_factory->CreateDevice(adapter.Get(), requested_feature_level, IID_PPV_ARGS(device.GetAddressOf()));
|
||||
} else {
|
||||
PFN_D3D12_CREATE_DEVICE d3d_D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12CreateDevice");
|
||||
ERR_FAIL_NULL_V(d3d_D3D12CreateDevice, ERR_CANT_CREATE);
|
||||
|
||||
res = d3d_D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf()));
|
||||
res = d3d_D3D12CreateDevice(adapter.Get(), requested_feature_level, IID_PPV_ARGS(device.GetAddressOf()));
|
||||
}
|
||||
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
|
||||
|
||||
if (D3D12Hooks::get_singleton() != nullptr) {
|
||||
D3D12Hooks::get_singleton()->set_device(device.Get());
|
||||
}
|
||||
|
||||
if (context_driver->use_validation_layers()) {
|
||||
ComPtr<ID3D12InfoQueue> info_queue;
|
||||
res = device.As(&info_queue);
|
||||
|
|
|
|||
|
|
@ -275,6 +275,9 @@ private:
|
|||
|
||||
UINT mapped_subresource = UINT_MAX;
|
||||
SelfList<TextureInfo> pending_clear{ this };
|
||||
#ifdef DEBUG_ENABLED
|
||||
bool created_from_extension = false;
|
||||
#endif
|
||||
};
|
||||
SelfList<TextureInfo>::List textures_pending_clear;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,5 +17,7 @@ if env["metal"]:
|
|||
env_openxr.add_source_files(module_obj, "platform/openxr_metal_extension.mm")
|
||||
if env["opengl3"] and env["platform"] != "macos":
|
||||
env_openxr.add_source_files(module_obj, "platform/openxr_opengl_extension.cpp")
|
||||
if env["d3d12"]:
|
||||
env_openxr.add_source_files(module_obj, "platform/openxr_d3d12_extension.cpp")
|
||||
|
||||
env.modules_sources += module_obj
|
||||
|
|
|
|||
450
modules/openxr/extensions/platform/openxr_d3d12_extension.cpp
Normal file
450
modules/openxr/extensions/platform/openxr_d3d12_extension.cpp
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_d3d12_extension.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "openxr_d3d12_extension.h"
|
||||
|
||||
#ifdef D3D12_ENABLED
|
||||
|
||||
#include "../../openxr_util.h"
|
||||
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
HashMap<String, bool *> OpenXRD3D12Extension::get_requested_extensions() {
|
||||
HashMap<String, bool *> request_extensions;
|
||||
|
||||
request_extensions[XR_KHR_D3D12_ENABLE_EXTENSION_NAME] = nullptr;
|
||||
|
||||
return request_extensions;
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::on_instance_created(const XrInstance p_instance) {
|
||||
// Obtain pointers to functions we're accessing here.
|
||||
ERR_FAIL_NULL(OpenXRAPI::get_singleton());
|
||||
|
||||
EXT_INIT_XR_FUNC(xrGetD3D12GraphicsRequirementsKHR);
|
||||
EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages);
|
||||
}
|
||||
|
||||
D3D_FEATURE_LEVEL OpenXRD3D12Extension::get_feature_level() const {
|
||||
XrGraphicsRequirementsD3D12KHR d3d12_requirements = {
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR, // type
|
||||
nullptr, // next
|
||||
{ 0, 0 }, // adapterLuid
|
||||
(D3D_FEATURE_LEVEL)0 // minFeatureLevel
|
||||
};
|
||||
|
||||
XrResult result = xrGetD3D12GraphicsRequirementsKHR(OpenXRAPI::get_singleton()->get_instance(), OpenXRAPI::get_singleton()->get_system_id(), &d3d12_requirements);
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get Direct3D 12 graphics requirements [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
|
||||
return D3D_FEATURE_LEVEL_11_0; // Good default.
|
||||
}
|
||||
|
||||
// #ifdef DEBUG
|
||||
print_line("OpenXR: xrGetD3D12GraphicsRequirementsKHR:");
|
||||
print_line(" - minFeatureLevel: ", (uint32_t)d3d12_requirements.minFeatureLevel);
|
||||
// #endif
|
||||
|
||||
return d3d12_requirements.minFeatureLevel;
|
||||
}
|
||||
|
||||
LUID OpenXRD3D12Extension::get_adapter_luid() const {
|
||||
XrGraphicsRequirementsD3D12KHR d3d12_requirements = {
|
||||
XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR, // type
|
||||
nullptr, // next
|
||||
{ 0, 0 }, // adapterLuid
|
||||
(D3D_FEATURE_LEVEL)0 // minFeatureLevel
|
||||
};
|
||||
|
||||
XrResult result = xrGetD3D12GraphicsRequirementsKHR(OpenXRAPI::get_singleton()->get_instance(), OpenXRAPI::get_singleton()->get_system_id(), &d3d12_requirements);
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get Direct3D 12 graphics requirements [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
|
||||
return {};
|
||||
}
|
||||
|
||||
return d3d12_requirements.adapterLuid;
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::set_device(ID3D12Device *p_device) {
|
||||
graphics_device = p_device;
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::set_command_queue(ID3D12CommandQueue *p_queue) {
|
||||
command_queue = p_queue;
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::cleanup_device() {
|
||||
command_queue.Reset();
|
||||
graphics_device.Reset();
|
||||
}
|
||||
|
||||
XrGraphicsBindingD3D12KHR OpenXRD3D12Extension::graphics_binding_d3d12;
|
||||
|
||||
void *OpenXRD3D12Extension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
|
||||
DEV_ASSERT(graphics_device && "Graphics Device was not specified yet.");
|
||||
DEV_ASSERT(command_queue && "Command queue was not specified yet.");
|
||||
|
||||
graphics_binding_d3d12.type = XR_TYPE_GRAPHICS_BINDING_D3D12_KHR,
|
||||
graphics_binding_d3d12.next = p_next_pointer;
|
||||
graphics_binding_d3d12.device = graphics_device.Get();
|
||||
graphics_binding_d3d12.queue = command_queue.Get();
|
||||
|
||||
return &graphics_binding_d3d12;
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
|
||||
p_usable_swap_chains.push_back(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
p_usable_swap_chains.push_back(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB);
|
||||
p_usable_swap_chains.push_back(DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||
p_usable_swap_chains.push_back(DXGI_FORMAT_B8G8R8A8_UNORM);
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::get_usable_depth_formats(Vector<int64_t> &p_usable_depth_formats) {
|
||||
p_usable_depth_formats.push_back(DXGI_FORMAT_D32_FLOAT);
|
||||
p_usable_depth_formats.push_back(DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
|
||||
p_usable_depth_formats.push_back(DXGI_FORMAT_D24_UNORM_S8_UINT);
|
||||
p_usable_depth_formats.push_back(DXGI_FORMAT_D16_UNORM);
|
||||
}
|
||||
|
||||
bool OpenXRD3D12Extension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
|
||||
RenderingServer *rendering_server = RenderingServer::get_singleton();
|
||||
ERR_FAIL_NULL_V(rendering_server, false);
|
||||
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
|
||||
ERR_FAIL_NULL_V(rendering_device, false);
|
||||
|
||||
uint32_t swapchain_length;
|
||||
XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr);
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get swapchain image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
LocalVector<XrSwapchainImageD3D12KHR> images;
|
||||
images.resize(swapchain_length);
|
||||
|
||||
for (XrSwapchainImageD3D12KHR &image : images) {
|
||||
image.type = XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR;
|
||||
image.next = nullptr;
|
||||
image.texture = nullptr;
|
||||
}
|
||||
|
||||
result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr());
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get swapchain images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
|
||||
if (data == nullptr) {
|
||||
print_line("OpenXR: Failed to allocate memory for swapchain data");
|
||||
return false;
|
||||
}
|
||||
*r_swapchain_graphics_data = data;
|
||||
data->is_multiview = (p_array_size > 1);
|
||||
|
||||
RenderingDevice::DataFormat format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
RenderingDevice::TextureSamples samples = RenderingDevice::TEXTURE_SAMPLES_1;
|
||||
uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT;
|
||||
|
||||
switch (p_swapchain_format) {
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
// Even though this is an sRGB framebuffer format we're using UNORM here.
|
||||
// The reason here is because Godot does a linear to sRGB conversion while
|
||||
// with the sRGB format, this conversion would be doubled by the hardware.
|
||||
// This also means we're reading the values as is for our preview on screen.
|
||||
// The OpenXR runtime however is still treating this as an sRGB format and
|
||||
// will thus do an sRGB -> Linear conversion as expected.
|
||||
//format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
||||
//format = RenderingDevice::DATA_FORMAT_B8G8R8A8_SRGB;
|
||||
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UNORM;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
format = RenderingDevice::DATA_FORMAT_R8G8B8A8_UINT;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
||||
format = RenderingDevice::DATA_FORMAT_B8G8R8A8_UINT;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_D32_FLOAT:
|
||||
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
||||
format = RenderingDevice::DATA_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
||||
format = RenderingDevice::DATA_FORMAT_D24_UNORM_S8_UINT;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
break;
|
||||
case DXGI_FORMAT_D16_UNORM:
|
||||
format = RenderingDevice::DATA_FORMAT_D16_UNORM;
|
||||
usage_flags |= RenderingDevice::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
break;
|
||||
default:
|
||||
// continue with our default value
|
||||
print_line("OpenXR: Unsupported swapchain format", p_swapchain_format);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p_sample_count) {
|
||||
case 1:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_1;
|
||||
break;
|
||||
case 2:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_2;
|
||||
break;
|
||||
case 4:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_4;
|
||||
break;
|
||||
case 8:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_8;
|
||||
break;
|
||||
case 16:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_16;
|
||||
break;
|
||||
case 32:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_32;
|
||||
break;
|
||||
case 64:
|
||||
samples = RenderingDevice::TEXTURE_SAMPLES_64;
|
||||
break;
|
||||
default:
|
||||
// continue with our default value
|
||||
print_line("OpenXR: Unsupported sample count", p_sample_count);
|
||||
break;
|
||||
}
|
||||
|
||||
Vector<RID> texture_rids;
|
||||
|
||||
for (const XrSwapchainImageD3D12KHR &swapchain_image : images) {
|
||||
RID texture_rid = rendering_device->texture_create_from_extension(
|
||||
p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
|
||||
format,
|
||||
samples,
|
||||
usage_flags,
|
||||
(uint64_t)swapchain_image.texture,
|
||||
p_width,
|
||||
p_height,
|
||||
1,
|
||||
p_array_size);
|
||||
|
||||
texture_rids.push_back(texture_rid);
|
||||
}
|
||||
|
||||
data->texture_rids = texture_rids;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenXRD3D12Extension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||
OpenXRUtil::XrMatrix4x4f matrix;
|
||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_D3D, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RID OpenXRD3D12Extension::get_texture(void *p_swapchain_graphics_data, int p_image_index) {
|
||||
SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
|
||||
ERR_FAIL_NULL_V(data, RID());
|
||||
|
||||
ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID());
|
||||
return data->texture_rids[p_image_index];
|
||||
}
|
||||
|
||||
void OpenXRD3D12Extension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
|
||||
if (*p_swapchain_graphics_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderingServer *rendering_server = RenderingServer::get_singleton();
|
||||
ERR_FAIL_NULL(rendering_server);
|
||||
RenderingDevice *rendering_device = rendering_server->get_rendering_device();
|
||||
ERR_FAIL_NULL(rendering_device);
|
||||
|
||||
SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;
|
||||
|
||||
for (const RID &texture_rid : data->texture_rids) {
|
||||
// This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain.
|
||||
rendering_device->free(texture_rid);
|
||||
}
|
||||
data->texture_rids.clear();
|
||||
|
||||
memdelete(data);
|
||||
*p_swapchain_graphics_data = nullptr;
|
||||
}
|
||||
|
||||
#define ENUM_TO_STRING_CASE(e) \
|
||||
case e: { \
|
||||
return String(#e); \
|
||||
} break;
|
||||
|
||||
String OpenXRD3D12Extension::get_swapchain_format_name(int64_t p_swapchain_format) const {
|
||||
// These are somewhat different per platform, will need to weed some stuff out...
|
||||
switch (p_swapchain_format) {
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_UNKNOWN)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32A32_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32A32_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32A32_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32A32_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32B32_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16B16A16_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G32_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32G8X24_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_D32_FLOAT_S8X24_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R10G10B10A2_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R10G10B10A2_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R10G10B10A2_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R11G11B10_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8B8A8_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16G16_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_D32_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R32_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R24G8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_D24_UNORM_S8_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R24_UNORM_X8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_X24_TYPELESS_G8_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_FLOAT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_D16_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R16_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8_UINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8_SINT)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_A8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R1_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R9G9B9E5_SHAREDEXP)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R8G8_B8G8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_G8R8_G8B8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC1_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC1_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC1_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC2_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC2_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC2_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC3_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC3_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC3_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC4_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC4_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC4_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC5_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC5_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC5_SNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B5G6R5_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B5G5R5A1_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8A8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8X8_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8A8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8X8_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC6H_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC6H_UF16)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC6H_SF16)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC7_TYPELESS)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC7_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_BC7_UNORM_SRGB)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_AYUV)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_Y410)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_Y416)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_NV12)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_P010)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_P016)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_420_OPAQUE)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_YUY2)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_Y210)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_Y216)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_NV11)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_AI44)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_IA44)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_P8)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_A8P8)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_B4G4R4A4_UNORM)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_P208)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_V208)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_V408)
|
||||
ENUM_TO_STRING_CASE(DXGI_FORMAT_A4B4G4R4_UNORM)
|
||||
default: {
|
||||
return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // D3D12_ENABLED
|
||||
84
modules/openxr/extensions/platform/openxr_d3d12_extension.h
Normal file
84
modules/openxr/extensions/platform/openxr_d3d12_extension.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/**************************************************************************/
|
||||
/* openxr_d3d12_extension.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef D3D12_ENABLED
|
||||
|
||||
#include "../../openxr_api.h"
|
||||
#include "../../util.h"
|
||||
#include "../openxr_extension_wrapper.h"
|
||||
|
||||
#include "core/templates/vector.h"
|
||||
#include "drivers/d3d12/d3d12_hooks.h"
|
||||
|
||||
// Always include this as late as possible.
|
||||
#include "../../openxr_platform_inc.h"
|
||||
|
||||
class OpenXRD3D12Extension : public OpenXRGraphicsExtensionWrapper, D3D12Hooks {
|
||||
public:
|
||||
virtual HashMap<String, bool *> get_requested_extensions() override;
|
||||
|
||||
virtual void on_instance_created(const XrInstance p_instance) override;
|
||||
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;
|
||||
|
||||
virtual D3D_FEATURE_LEVEL get_feature_level() const override final;
|
||||
virtual LUID get_adapter_luid() const override final;
|
||||
virtual void set_device(ID3D12Device *p_device) override final;
|
||||
virtual void set_command_queue(ID3D12CommandQueue *p_queue) override final;
|
||||
virtual void cleanup_device() override final;
|
||||
|
||||
virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) override;
|
||||
virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) override;
|
||||
virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override;
|
||||
virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override;
|
||||
virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override;
|
||||
virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override;
|
||||
virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override;
|
||||
virtual RID get_density_map(void *p_swapchain_graphics_data, int p_image_index) override { return RID(); }
|
||||
|
||||
private:
|
||||
static OpenXRD3D12Extension *singleton;
|
||||
|
||||
static XrGraphicsBindingD3D12KHR graphics_binding_d3d12;
|
||||
|
||||
struct SwapchainGraphicsData {
|
||||
bool is_multiview;
|
||||
Vector<RID> texture_rids;
|
||||
};
|
||||
|
||||
EXT_PROTO_XRRESULT_FUNC3(xrGetD3D12GraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsD3D12KHR *), p_graphics_requirements)
|
||||
EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images)
|
||||
|
||||
ComPtr<ID3D12Device> graphics_device;
|
||||
ComPtr<ID3D12CommandQueue> command_queue;
|
||||
};
|
||||
|
||||
#endif // D3D12_ENABLED
|
||||
|
|
@ -52,6 +52,10 @@
|
|||
#include "extensions/platform/openxr_opengl_extension.h"
|
||||
#endif
|
||||
|
||||
#ifdef D3D12_ENABLED
|
||||
#include "extensions/platform/openxr_d3d12_extension.h"
|
||||
#endif
|
||||
|
||||
#include "extensions/openxr_composition_layer_depth_extension.h"
|
||||
#include "extensions/openxr_debug_utils_extension.h"
|
||||
#include "extensions/openxr_eye_gaze_interaction.h"
|
||||
|
|
@ -1679,6 +1683,14 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
|
|||
#else
|
||||
// shouldn't be possible...
|
||||
ERR_FAIL_V(false);
|
||||
#endif
|
||||
} else if (p_rendering_driver == "d3d12") {
|
||||
#ifdef D3D12_ENABLED
|
||||
graphics_extension = memnew(OpenXRD3D12Extension);
|
||||
register_extension_wrapper(graphics_extension);
|
||||
#else
|
||||
// shouldn't be possible...
|
||||
ERR_FAIL_V(false);
|
||||
#endif
|
||||
} else {
|
||||
ERR_FAIL_V_MSG(false, "OpenXR: Unsupported rendering device.");
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@
|
|||
#endif // X11_ENABLED
|
||||
#endif // defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
|
||||
|
||||
#ifdef D3D12_ENABLED
|
||||
#define XR_USE_GRAPHICS_API_D3D12
|
||||
#include "drivers/d3d12/rendering_context_driver_d3d12.h"
|
||||
#endif // D3D12_ENABLED
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
#include <X11/Xlib.h>
|
||||
#endif // X11_ENABLED
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ String ShaderRD::_version_get_sha1(Version *p_version) const {
|
|||
}
|
||||
|
||||
static const char *shader_file_header = "GDSC";
|
||||
static const uint32_t cache_file_version = 3;
|
||||
static const uint32_t cache_file_version = 4;
|
||||
|
||||
String ShaderRD::_get_cache_file_path(Version *p_version, int p_group) {
|
||||
const String &sha1 = _version_get_sha1(p_version);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue