Split RenderingDevice into API-agnostic and RenderingDeviceDriver parts

Credit and thanks to @bruzvg for multiple build fixes, update of 3rd-party items and MinGW support.

Co-authored-by: bruvzg <7645683+bruvzg@users.noreply.github.com>
This commit is contained in:
Pedro J. Estébanez 2023-12-19 12:48:02 +01:00
parent 0567c5df9f
commit 12a519bae2
80 changed files with 35463 additions and 29745 deletions

View File

@ -95,7 +95,7 @@ const PackedStringArray ProjectSettings::_get_supported_features() {
features.append(VERSION_FULL_CONFIG);
features.append(VERSION_FULL_BUILD);
#if defined(VULKAN_ENABLED) || defined(D3D12_ENABLED)
#ifdef RD_ENABLED
features.append("Forward Plus");
features.append("Mobile");
#endif
@ -1399,6 +1399,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64);
GLOBAL_DEF("rendering/rendering_device/pipeline_cache/save_chunk_size_mb", 3.0);
GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64);
GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_resource_descriptors_per_frame", 16384);
custom_prop_info["rendering/rendering_device/d3d12/max_resource_descriptors_per_frame"] = PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/max_resource_descriptors_per_frame", PROPERTY_HINT_RANGE, "512,262144");
GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_sampler_descriptors_per_frame", 1024);

View File

@ -92,6 +92,7 @@
#undef Error
#undef OK
#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum
#undef MemoryBarrier
#endif
// Make room for our constexpr's below by overriding potential system-specific macros.

View File

@ -796,12 +796,13 @@
Returns the data format used to create this texture.
</description>
</method>
<method name="texture_get_native_handle">
<method name="texture_get_native_handle" is_deprecated="true">
<return type="int" />
<param index="0" name="texture" type="RID" />
<description>
Returns the internal graphics handle for this texture object. For use when communicating with third-party APIs mostly with GDExtension.
[b]Note:[/b] This function returns a [code]uint64_t[/code] which internally maps to a [code]GLuint[/code] (OpenGL) or [code]VkImage[/code] (Vulkan).
[i]Deprecated.[/i] Use [method get_driver_resource] with [constant DRIVER_RESOURCE_TEXTURE] instead.
</description>
</method>
<method name="texture_is_format_supported_for_usage" qualifiers="const">
@ -928,44 +929,91 @@
<constant name="DEVICE_TYPE_MAX" value="5" enum="DeviceType">
Represents the size of the [enum DeviceType] enum.
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_DEVICE" value="0" enum="DriverResource">
Vulkan device driver resource. This is a "global" resource and ignores the RID passed in
<constant name="DRIVER_RESOURCE_LOGICAL_DEVICE" value="0" enum="DriverResource">
Specific device object based on a physical device.
- Vulkan: Vulkan device driver resource ([code]VkDevice[/code]). ([code]rid[/code] argument doesn't apply.)
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE" value="1" enum="DriverResource">
Physical device (graphics card) driver resource.
<constant name="DRIVER_RESOURCE_PHYSICAL_DEVICE" value="1" enum="DriverResource">
Physical device the specific logical device is based on.
- Vulkan: [code]VkDevice[/code]. ([code]rid[/code] argument doesn't apply.)
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_INSTANCE" value="2" enum="DriverResource">
Vulkan instance driver resource.
<constant name="DRIVER_RESOURCE_TOPMOST_OBJECT" value="2" enum="DriverResource">
Top-most graphics API entry object.
- Vulkan: [code]VkInstance[/code]. ([code]rid[/code] argument doesn't apply.)
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_QUEUE" value="3" enum="DriverResource">
Vulkan queue driver resource.
<constant name="DRIVER_RESOURCE_COMMAND_QUEUE" value="3" enum="DriverResource">
The main graphics-compute command queue.
- Vulkan: [code]VkQueue[/code]. ([code]rid[/code] argument doesn't apply.)
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX" value="4" enum="DriverResource">
Vulkan queue family index driver resource.
<constant name="DRIVER_RESOURCE_QUEUE_FAMILY" value="4" enum="DriverResource">
The specific family the main queue belongs to.
- Vulkan: the queue family index, an [code]uint32_t[/code]. ([code]rid[/code] argument doesn't apply.)
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE" value="5" enum="DriverResource">
Vulkan image driver resource.
<constant name="DRIVER_RESOURCE_TEXTURE" value="5" enum="DriverResource">
- Vulkan: [code]VkImage[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE_VIEW" value="6" enum="DriverResource">
Vulkan image view driver resource.
<constant name="DRIVER_RESOURCE_TEXTURE_VIEW" value="6" enum="DriverResource">
The view of an owned or shared texture.
- Vulkan: [code]VkImageView[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT" value="7" enum="DriverResource">
Vulkan image native texture format driver resource.
<constant name="DRIVER_RESOURCE_TEXTURE_DATA_FORMAT" value="7" enum="DriverResource">
The native id of the data format of the texture.
- Vulkan: [code]VkFormat[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_SAMPLER" value="8" enum="DriverResource">
Vulkan sampler driver resource.
<constant name="DRIVER_RESOURCE_SAMPLER" value="8" enum="DriverResource">
- Vulkan: [code]VkSampler[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET" value="9" enum="DriverResource">
Vulkan [url=https://vkguide.dev/docs/chapter-4/descriptors/]descriptor set[/url] driver resource.
<constant name="DRIVER_RESOURCE_UNIFORM_SET" value="9" enum="DriverResource">
- Vulkan: [code]VkDescriptorSet[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_BUFFER" value="10" enum="DriverResource">
Vulkan buffer driver resource.
<constant name="DRIVER_RESOURCE_BUFFER" value="10" enum="DriverResource">
Buffer of any kind of (storage, vertex, etc.).
- Vulkan: [code]VkBuffer[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE" value="11" enum="DriverResource">
Vulkan compute pipeline driver resource.
<constant name="DRIVER_RESOURCE_COMPUTE_PIPELINE" value="11" enum="DriverResource">
- Vulkan: [code]VkPipeline[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE" value="12" enum="DriverResource">
Vulkan render pipeline driver resource.
<constant name="DRIVER_RESOURCE_RENDER_PIPELINE" value="12" enum="DriverResource">
- Vulkan: [code]VkPipeline[/code].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_DEVICE" value="0" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_LOGICAL_DEVICE].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE" value="1" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_PHYSICAL_DEVICE].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_INSTANCE" value="2" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_TOPMOST_OBJECT].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_QUEUE" value="3" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_COMMAND_QUEUE].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX" value="4" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_QUEUE_FAMILY].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE" value="5" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_TEXTURE].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE_VIEW" value="6" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_TEXTURE_VIEW].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT" value="7" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_TEXTURE_DATA_FORMAT].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_SAMPLER" value="8" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_SAMPLER].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET" value="9" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_UNIFORM_SET].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_BUFFER" value="10" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_BUFFER].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE" value="11" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_COMPUTE_PIPELINE].
</constant>
<constant name="DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE" value="12" enum="DriverResource" is_deprecated="true">
[i]Deprecated.[/i] Use [constant DRIVER_RESOURCE_RENDER_PIPELINE].
</constant>
<constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat">
4-bit-per-channel red/green channel data format, packed into 8 bits. Values are in the [code][0.0, 1.0][/code] range.

View File

@ -5,36 +5,39 @@ from pathlib import Path
Import("env")
env_d3d12_rd = env.Clone()
env.Append(CPPDEFINES=["RD_ENABLED"])
env_d3d12_rdd = env.Clone()
thirdparty_obj = []
# DirectX Headers (must take precedence over Windows SDK's).
env.Prepend(CPPPATH=["#thirdparty/directx_headers"])
env_d3d12_rd.Prepend(CPPPATH=["#thirdparty/directx_headers"])
env.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"])
env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/directx"])
env_d3d12_rdd.Prepend(CPPPATH=["#thirdparty/directx_headers/include/dxguids"])
# Direct3D 12 Memory Allocator.
env.Append(CPPPATH=["#thirdparty/d3d12ma"])
env_d3d12_rd.Append(CPPPATH=["#thirdparty/d3d12ma"])
env_d3d12_rdd.Append(CPPPATH=["#thirdparty/d3d12ma"])
# Agility SDK.
if env["agility_sdk_path"] != "":
env_d3d12_rd.Append(CPPDEFINES=["AGILITY_SDK_ENABLED"])
env_d3d12_rdd.Append(CPPDEFINES=["AGILITY_SDK_ENABLED"])
if env["agility_sdk_multiarch"]:
env_d3d12_rd.Append(CPPDEFINES=["AGILITY_SDK_MULTIARCH_ENABLED"])
env_d3d12_rdd.Append(CPPDEFINES=["AGILITY_SDK_MULTIARCH_ENABLED"])
# PIX.
if env["pix_path"] != "":
env_d3d12_rd.Append(CPPDEFINES=["PIX_ENABLED"])
env_d3d12_rd.Append(CPPPATH=[env["pix_path"] + "/Include"])
env_d3d12_rdd.Append(CPPDEFINES=["PIX_ENABLED"])
env_d3d12_rdd.Append(CPPPATH=[env["pix_path"] + "/Include"])
# Mesa (SPIR-V to DXIL functionality).
@ -105,12 +108,16 @@ extra_defines = [
"WINDOWS_NO_FUTEX",
]
mesa_ver = Path(mesa_absdir + "/VERSION.info")
if not mesa_ver.is_file():
mesa_ver = Path(mesa_absdir + "/VERSION")
# These defines are inspired by the Meson build scripts in the original repo.
extra_defines += [
"__STDC_CONSTANT_MACROS",
"__STDC_FORMAT_MACROS",
"__STDC_LIMIT_MACROS",
("PACKAGE_VERSION", '\\"' + Path(mesa_absdir + "/VERSION").read_text().strip() + '\\"'),
("PACKAGE_VERSION", '\\"' + mesa_ver.read_text().strip() + '\\"'),
("PACKAGE_BUGREPORT", '\\"https://gitlab.freedesktop.org/mesa/mesa/-/issues\\"'),
"PIPE_SUBSYSTEM_WINDOWS_USER",
("_Static_assert", "static_assert"),
@ -129,11 +136,16 @@ if env.msvc:
"NOMINMAX",
"HAVE_STRUCT_TIMESPEC",
]
else:
extra_defines += [
("__REQUIRED_RPCNDR_H_VERSION__", 475),
"HAVE_STRUCT_TIMESPEC",
]
# This is needed since rendering_device_d3d12.cpp needs to include some Mesa internals.
env_d3d12_rd.Prepend(CPPPATH=mesa_private_inc_paths)
env_d3d12_rdd.Prepend(CPPPATH=mesa_private_inc_paths)
# For the same reason as above, the defines must be the same as in the 3rd-party code itself.
env_d3d12_rd.Append(CPPDEFINES=extra_defines)
env_d3d12_rdd.Append(CPPDEFINES=extra_defines)
# Add all.
@ -144,7 +156,7 @@ env.drivers_sources += thirdparty_obj
# Godot source files.
driver_obj = []
env_d3d12_rd.add_source_files(driver_obj, "*.cpp")
env_d3d12_rdd.add_source_files(driver_obj, "*.cpp")
env.drivers_sources += driver_obj
# Needed to force rebuilding the driver files when the thirdparty code is updated.

View File

@ -37,8 +37,26 @@
#include "core/version.h"
#include "servers/rendering/rendering_device.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wswitch"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
#include "dxcapi.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
#if !defined(_MSC_VER)
#include <guiddef.h>
#include <dxguids.h>
#endif
extern "C" {
char godot_nir_arch_name[32];
@ -47,8 +65,12 @@ __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";
#else
#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 = "\\.";
@ -57,11 +79,15 @@ __declspec(dllexport) extern const char *D3D12SDKPath = "\\.";
}
#ifdef PIX_ENABLED
#if defined(__GNUC__)
#define _MSC_VER 1800
#endif
#define USE_PIX
#include "WinPixEventRuntime/pix3.h"
#if defined(__GNUC__)
#undef _MSC_VER
#endif
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void D3D12Context::_debug_message_func(
D3D12_MESSAGE_CATEGORY p_category,
@ -178,7 +204,7 @@ Error D3D12Context::_check_capabilities() {
D3D12_FEATURE_DATA_SHADER_MODEL shader_model = {};
shader_model.HighestShaderModel = MIN(D3D_HIGHEST_SHADER_MODEL, D3D_SHADER_MODEL_6_6);
HRESULT res = md.device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model));
ERR_FAIL_COND_V_MSG(res, ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", res) + ".");
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
shader_capabilities.shader_model = shader_model.HighestShaderModel;
}
print_verbose("- Shader:");
@ -270,7 +296,7 @@ Error D3D12Context::_check_capabilities() {
Error D3D12Context::_initialize_debug_layers() {
ComPtr<ID3D12Debug> debug_controller;
HRESULT res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller));
ERR_FAIL_COND_V(res, ERR_QUERY_FAILED);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_QUERY_FAILED);
debug_controller->EnableDebugLayer();
return OK;
}
@ -399,7 +425,7 @@ Error D3D12Context::_select_adapter(int &r_index) {
if (SUCCEEDED(res)) {
tearing_supported = result;
} else {
ERR_PRINT("CheckFeatureSupport failed with error " + vformat("0x%08ux", res) + ".");
ERR_PRINT("CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
}
}
@ -423,7 +449,7 @@ void D3D12Context::_dump_adapter_info(int p_index) {
feat_levels.pFeatureLevelsRequested = FEATURE_LEVELS;
HRESULT res = md.device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &feat_levels, sizeof(feat_levels));
ERR_FAIL_COND_MSG(res, "CheckFeatureSupport failed with error " + vformat("0x%08ux", res) + ".");
ERR_FAIL_COND_MSG(!SUCCEEDED(res), "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
// Example: D3D_FEATURE_LEVEL_12_1 = 0xc100.
uint32_t feat_level_major = feat_levels.MaxSupportedFeatureLevel >> 12;
@ -476,25 +502,25 @@ 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()));
ERR_FAIL_COND_V_MSG(res, ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", res) + ".");
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
// Create direct command queue.
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
res = r_basics.device->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(r_basics.queue.GetAddressOf()));
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
// Create sync objects.
res = r_basics.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(r_basics.fence.GetAddressOf()));
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
r_basics.fence_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
ERR_FAIL_NULL_V(r_basics.fence_event, ERR_CANT_CREATE);
if (_use_validation_layers()) {
ComPtr<ID3D12InfoQueue> info_queue;
res = r_basics.device.As(&info_queue);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
#if 0 // This causes crashes. Needs investigation.
ComPtr<ID3D12InfoQueue1> info_queue_1;
@ -505,7 +531,7 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) {
info_queue_1->SetMuteDebugOutput(TRUE);
res = info_queue_1->RegisterMessageCallback(&_debug_message_func, D3D12_MESSAGE_CALLBACK_IGNORE_FILTERS, nullptr, 0);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
} else
#endif
{
@ -513,7 +539,11 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) {
if (Engine::get_singleton()->is_abort_on_gpu_errors_enabled()) {
res = info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
res = info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
res = info_queue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
}
}
D3D12_MESSAGE_SEVERITY severities_to_mute[] = {
@ -535,7 +565,7 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) {
filter.DenyList.pIDList = messages_to_mute;
res = info_queue->PushStorageFilter(&filter);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
}
return OK;
@ -544,7 +574,7 @@ Error D3D12Context::_create_device(DeviceBasics &r_basics) {
Error D3D12Context::_get_device_limits() {
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
HRESULT res = md.device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
ERR_FAIL_COND_V_MSG(res, ERR_UNAVAILABLE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", res) + ".");
ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_UNAVAILABLE, "CheckFeatureSupport failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
// https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-support
gpu_limits.max_srvs_per_shader_stage = options.ResourceBindingTier == D3D12_RESOURCE_BINDING_TIER_1 ? 128 : UINT64_MAX;
@ -567,18 +597,44 @@ bool D3D12Context::_use_validation_layers() {
return Engine::get_singleton()->is_validation_layers_enabled();
}
Error D3D12Context::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
Error D3D12Context::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
Window window;
window.hwnd = p_window;
window.hwnd = ((const WindowPlatformData *)p_platform_data)->window;
window.width = p_width;
window.height = p_height;
window.vsync_mode = p_vsync_mode;
{
RDD::Attachment attachment;
attachment.samples = RD::TEXTURE_SAMPLES_1;
attachment.load_op = RDD::ATTACHMENT_LOAD_OP_CLEAR;
attachment.store_op = RDD::ATTACHMENT_STORE_OP_STORE;
window.render_pass.attachments.push_back(attachment);
RDD::Subpass subpass;
{
RDD::AttachmentReference color_ref;
color_ref.attachment = 0;
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
subpass.color_references.push_back(color_ref);
}
window.render_pass.subpasses.push_back(subpass);
}
for (uint32_t i = 0; i < IMAGE_COUNT; i++) {
Error err = window.framebuffers[i].rtv_heap.allocate(md.device.Get(), D3D12_DESCRIPTOR_HEAP_TYPE_RTV, 1, false);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
window.framebuffers[i].is_screen = true;
window.framebuffers[i].attachments_handle_inds.push_back(0);
}
Error err = _update_swap_chain(&window);
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
windows[p_window_id] = window;
return OK;
}
@ -605,25 +661,20 @@ bool D3D12Context::window_is_valid_swapchain(DisplayServer::WindowID p_window) {
return (bool)w->swapchain;
}
CD3DX12_CPU_DESCRIPTOR_HANDLE D3D12Context::window_get_framebuffer_rtv_handle(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT()));
ERR_FAIL_COND_V(!buffers_prepared, CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT()));
RDD::RenderPassID D3D12Context::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), RDD::RenderPassID());
Window *w = &windows[p_window];
CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(
w->rtv_heap->GetCPUDescriptorHandleForHeapStart(),
w->current_buffer,
md.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV));
return rtv_handle;
return RDD::RenderPassID(&w->render_pass);
}
ID3D12Resource *D3D12Context::window_get_framebuffer_texture(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), nullptr);
ERR_FAIL_COND_V(!buffers_prepared, nullptr);
RDD::FramebufferID D3D12Context::window_get_framebuffer(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), RDD::FramebufferID());
ERR_FAIL_COND_V(!buffers_prepared, RDD::FramebufferID());
Window *w = &windows[p_window];
if (w->swapchain) {
return w->render_targets[w->current_buffer].Get();
return RDD::FramebufferID(&w->framebuffers[w->current_buffer]);
} else {
return nullptr;
return RDD::FramebufferID();
}
}
@ -699,7 +750,6 @@ Error D3D12Context::_update_swap_chain(Window *window) {
for (uint32_t i = 0; i < IMAGE_COUNT; i++) {
window->render_targets[i].Reset();
}
window->rtv_heap.Reset();
// D3D12 docs: "IDXGISwapChain::ResizeBuffers can't be used to add or remove this flag."
bool allow_tearing_flag_changed = (swapchain_flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) != (window->swapchain_flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING);
@ -722,45 +772,37 @@ Error D3D12Context::_update_swap_chain(Window *window) {
ComPtr<IDXGISwapChain1> swapchain;
HRESULT res = dxgi_factory->CreateSwapChainForHwnd(md.queue.Get(), window->hwnd, &swapchain_desc, nullptr, nullptr, swapchain.GetAddressOf());
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
swapchain.As(&window->swapchain);
ERR_FAIL_NULL_V(window->swapchain, ERR_CANT_CREATE);
format = swapchain_desc.Format;
res = dxgi_factory->MakeWindowAssociation(window->hwnd, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
res = window->swapchain->GetDesc1(&swapchain_desc);
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
ERR_FAIL_COND_V(swapchain_desc.BufferCount != IMAGE_COUNT, ERR_BUG);
window->width = swapchain_desc.Width;
window->height = swapchain_desc.Height;
} else {
HRESULT res = window->swapchain->ResizeBuffers(IMAGE_COUNT, window->width, window->height, DXGI_FORMAT_UNKNOWN, swapchain_flags);
ERR_FAIL_COND_V(res, ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_UNAVAILABLE);
}
window->swapchain_flags = swapchain_flags;
window->current_buffer = window->swapchain->GetCurrentBackBufferIndex();
// Describe and create a render target view (RTV) descriptor heap.
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc = {};
rtv_heap_desc.NumDescriptors = IMAGE_COUNT;
rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
HRESULT res = md.device->CreateDescriptorHeap(&rtv_heap_desc, IID_PPV_ARGS(window->rtv_heap.GetAddressOf()));
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(window->rtv_heap->GetCPUDescriptorHandleForHeapStart());
for (uint32_t i = 0; i < IMAGE_COUNT; i++) {
res = window->swapchain->GetBuffer(i, IID_PPV_ARGS(&window->render_targets[i]));
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
RenderingDeviceDriverD3D12::FramebufferInfo *fb_info = &window->framebuffers[i];
RenderingDeviceDriverD3D12::DescriptorsHeap::Walker walker = fb_info->rtv_heap.make_walker();
md.device->CreateRenderTargetView(window->render_targets[i].Get(), nullptr, rtv_handle);
rtv_handle.Offset(1, md.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV));
HRESULT res = window->swapchain->GetBuffer(i, IID_PPV_ARGS(&window->render_targets[i]));
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
md.device->CreateRenderTargetView(window->render_targets[i].Get(), nullptr, walker.get_curr_cpu_handle());
}
return OK;
@ -790,33 +832,28 @@ Error D3D12Context::initialize() {
{
HRESULT res = md.device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(frame_fence.GetAddressOf()));
ERR_FAIL_COND_V(res, ERR_CANT_CREATE);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
frame_fence_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
ERR_FAIL_NULL_V(frame_fence_event, ERR_CANT_CREATE);
}
{ // Initialize allocator.
D3D12MA::ALLOCATOR_DESC allocator_desc = {};
allocator_desc.pDevice = md.device.Get();
allocator_desc.pAdapter = gpu.Get();
HRESULT res = D3D12MA::CreateAllocator(&allocator_desc, &allocator);
ERR_FAIL_COND_V_MSG(res, ERR_CANT_CREATE, "D3D12MA::CreateAllocator failed with error " + vformat("0x%08ux", res) + ".");
}
md.driver = memnew(RenderingDeviceDriverD3D12(this, md.device.Get(), IMAGE_COUNT + 1));
return OK;
}
void D3D12Context::set_setup_list(ID3D12CommandList *p_command_list) {
command_list_queue.write[0] = p_command_list;
void D3D12Context::set_setup_buffer(RDD::CommandBufferID p_command_buffer) {
const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
command_list_queue[0] = cmd_buf_info->cmd_list.Get();
}
void D3D12Context::append_command_list(ID3D12CommandList *p_command_list) {
void D3D12Context::append_command_buffer(RDD::CommandBufferID p_command_buffer) {
if (command_list_queue.size() <= command_list_count) {
command_list_queue.resize(command_list_count + 1);
}
command_list_queue.write[command_list_count] = p_command_list;
const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
command_list_queue[command_list_count] = cmd_buf_info->cmd_list.Get();
command_list_count++;
}
@ -833,7 +870,7 @@ void D3D12Context::_wait_for_idle_queue(ID3D12CommandQueue *p_queue) {
void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending) {
if (p_flush_setup && command_list_queue[0]) {
md.queue->ExecuteCommandLists(1, command_list_queue.ptr());
command_list_queue.write[0] = nullptr;
command_list_queue[0] = nullptr;
}
if (p_flush_pending && command_list_count > 1) {
@ -846,7 +883,7 @@ void D3D12Context::flush(bool p_flush_setup, bool p_flush_pending) {
}
}
void D3D12Context::prepare_buffers(ID3D12GraphicsCommandList *p_command_list) {
Error D3D12Context::prepare_buffers(RDD::CommandBufferID p_command_buffer) {
// Ensure no more than FRAME_LAG renderings are outstanding.
if (frame >= IMAGE_COUNT) {
UINT64 min_value = frame - IMAGE_COUNT;
@ -860,20 +897,21 @@ void D3D12Context::prepare_buffers(ID3D12GraphicsCommandList *p_command_list) {
}
D3D12_RESOURCE_BARRIER *barriers = (D3D12_RESOURCE_BARRIER *)alloca(windows.size() * sizeof(D3D12_RESOURCE_BARRIER));
uint32_t n = 0;
for (KeyValue<int, Window> &E : windows) {
Window *w = &E.value;
w->current_buffer = w->swapchain->GetCurrentBackBufferIndex();
barriers[n++] = CD3DX12_RESOURCE_BARRIER::Transition(w->render_targets[w->current_buffer].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
p_command_list->ResourceBarrier(n, barriers);
const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
cmd_buf_info->cmd_list->ResourceBarrier(n, barriers);
buffers_prepared = true;
return OK;
}
void D3D12Context::postpare_buffers(ID3D12GraphicsCommandList *p_command_list) {
void D3D12Context::postpare_buffers(RDD::CommandBufferID p_command_buffer) {
D3D12_RESOURCE_BARRIER *barriers = (D3D12_RESOURCE_BARRIER *)alloca(windows.size() * sizeof(D3D12_RESOURCE_BARRIER));
uint32_t n = 0;
@ -882,7 +920,8 @@ void D3D12Context::postpare_buffers(ID3D12GraphicsCommandList *p_command_list) {
barriers[n++] = CD3DX12_RESOURCE_BARRIER::Transition(w->render_targets[w->current_buffer].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
}
p_command_list->ResourceBarrier(n, barriers);
const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
cmd_buf_info->cmd_list->ResourceBarrier(n, barriers);
}
Error D3D12Context::swap_buffers() {
@ -902,7 +941,7 @@ Error D3D12Context::swap_buffers() {
md.queue->ExecuteCommandLists(commands_to_submit, commands_ptr);
command_list_queue.write[0] = nullptr;
command_list_queue[0] = nullptr;
command_list_count = 1;
for (KeyValue<int, Window> &E : windows) {
@ -912,8 +951,8 @@ Error D3D12Context::swap_buffers() {
continue;
}
HRESULT res = w->swapchain->Present(w->sync_interval, w->present_flags);
if (res) {
print_verbose("D3D12: Presenting swapchain of window " + itos(E.key) + " failed with error " + vformat("0x%08ux", res) + ".");
if (!SUCCEEDED(res)) {
print_verbose("D3D12: Presenting swapchain of window " + itos(E.key) + " failed with error " + vformat("0x%08ux", (uint64_t)res) + ".");
}
}
@ -927,16 +966,20 @@ Error D3D12Context::swap_buffers() {
void D3D12Context::resize_notify() {
}
ComPtr<ID3D12Device> D3D12Context::get_device() {
return md.device;
RenderingDevice::Capabilities D3D12Context::get_device_capabilities() const {
RenderingDevice::Capabilities c;
c.device_family = RenderingDevice::DEVICE_DIRECTX;
c.version_major = feature_level / 10;
c.version_minor = feature_level % 10;
return c;
}
ComPtr<IDXGIAdapter> D3D12Context::get_adapter() {
return gpu;
ID3D12Device *D3D12Context::get_device() {
return md.device.Get();
}
D3D12MA::Allocator *D3D12Context::get_allocator() {
return allocator.Get();
IDXGIAdapter *D3D12Context::get_adapter() {
return gpu.Get();
}
int D3D12Context::get_swapchain_image_count() const {
@ -947,26 +990,22 @@ DXGI_FORMAT D3D12Context::get_screen_format() const {
return format;
}
D3D12Context::DeviceLimits D3D12Context::get_device_limits() const {
const D3D12Context::DeviceLimits &D3D12Context::get_device_limits() const {
return gpu_limits;
}
RID D3D12Context::local_device_create() {
LocalDevice ld;
_create_device(ld);
ld.driver = memnew(RenderingDeviceDriverD3D12(this, ld.device.Get(), 1));
return local_device_owner.make_rid(ld);
}
ComPtr<ID3D12Device> D3D12Context::local_device_get_d3d12_device(RID p_local_device) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
return ld->device;
}
void D3D12Context::local_device_push_command_lists(RID p_local_device, ID3D12CommandList *const *p_lists, int p_count) {
void D3D12Context::local_device_push_command_buffers(RID p_local_device, const RDD::CommandBufferID *p_buffers, int p_count) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
ERR_FAIL_COND(ld->waiting);
ld->queue->ExecuteCommandLists(p_count, p_lists);
ld->queue->ExecuteCommandLists(p_count, (ID3D12CommandList *const *)p_buffers);
ld->waiting = true;
}
@ -988,27 +1027,29 @@ void D3D12Context::local_device_sync(RID p_local_device) {
void D3D12Context::local_device_free(RID p_local_device) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
memdelete(ld->driver);
CloseHandle(ld->fence_event);
local_device_owner.free(p_local_device);
}
void D3D12Context::command_begin_label(ID3D12GraphicsCommandList *p_command_list, String p_label_name, const Color p_color) {
void D3D12Context::command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
#ifdef PIX_ENABLED
PIXBeginEvent(p_command_list, p_color.to_argb32(), p_label_name.utf8().get_data());
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(ID3D12GraphicsCommandList *p_command_list, String p_label_name, const Color p_color) {
void D3D12Context::command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
#ifdef PIX_ENABLED
PIXSetMarker(p_command_list, p_color.to_argb32(), p_label_name.utf8().get_data());
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(ID3D12GraphicsCommandList *p_command_list) {
void D3D12Context::command_end_label(RDD::CommandBufferID p_command_buffer) {
#ifdef PIX_ENABLED
PIXEndEvent(p_command_list);
const RenderingDeviceDriverD3D12::CommandBufferInfo *cmd_buf_info = (const RenderingDeviceDriverD3D12::CommandBufferInfo *)p_command_buffer.id;
PIXEndEvent(cmd_buf_info->cmd_list.Get());
#endif
}
@ -1050,11 +1091,22 @@ void D3D12Context::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServe
_update_swap_chain(&windows[p_window]);
}
RenderingDeviceDriver *D3D12Context::get_driver(RID p_local_device) {
if (p_local_device.is_valid()) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
ERR_FAIL_NULL_V(ld, nullptr);
return ld->driver;
} else {
return md.driver;
}
}
D3D12Context::D3D12Context() {
command_list_queue.resize(1); // First one is always the setup command.
command_list_queue.write[0] = nullptr;
command_list_queue[0] = nullptr;
strcpy(godot_nir_arch_name, Engine::get_singleton()->get_architecture_name().ascii().get_data());
CharString cs = Engine::get_singleton()->get_architecture_name().ascii();
memcpy(godot_nir_arch_name, (const char *)cs.get_data(), cs.size());
}
D3D12Context::~D3D12Context() {

View File

@ -34,20 +34,38 @@
#include "core/error/error_list.h"
#include "core/os/mutex.h"
#include "core/string/ustring.h"
#include "core/templates/rb_map.h"
#include "core/templates/rid_owner.h"
#include "rendering_device_driver_d3d12.h"
#include "servers/display_server.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/renderer_rd/api_context_rd.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wswitch"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#if defined(AS)
#undef AS
#endif
#include "d3dx12.h"
#include <dxgi1_6.h>
#define D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED
#include "D3D12MemAlloc.h"
#include <wrl/client.h>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
using Microsoft::WRL::ComPtr;
class D3D12Context {
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
class D3D12Context : public ApiContextRD {
public:
struct DeviceLimits {
uint64_t max_srvs_per_shader_stage;
@ -64,15 +82,6 @@ public:
uint32_t supported_operations_flags_rd() const;
};
// Following VulkanContext definition.
struct MultiviewCapabilities {
bool is_supported;
bool geometry_shader_is_supported;
bool tessellation_shader_is_supported;
uint32_t max_view_count;
uint32_t max_instance_count;
};
struct VRSCapabilities {
bool draw_call_supported; // We can specify our fragment rate on a draw call level.
bool primitive_supported; // We can specify our fragment rate on each drawcall.
@ -110,12 +119,13 @@ private:
ComPtr<ID3D12Fence> fence;
HANDLE fence_event = nullptr;
UINT64 fence_value = 0;
RenderingDeviceDriverD3D12 *driver = nullptr;
} md; // 'Main device', as opposed to local device.
uint32_t feature_level = 0; // Major * 10 + minor.
bool tearing_supported = false;
SubgroupCapabilities subgroup_capabilities;
MultiviewCapabilities multiview_capabilities;
RDD::MultiviewCapabilities multiview_capabilities;
VRSCapabilities vrs_capabilities;
ShaderCapabilities shader_capabilities;
StorageBufferCapabilities storage_buffer_capabilities;
@ -126,8 +136,6 @@ private:
RenderingDevice::DeviceType adapter_type = {};
String pipeline_cache_id;
ComPtr<D3D12MA::Allocator> allocator;
bool buffers_prepared = false;
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
@ -146,7 +154,8 @@ private:
int width = 0;
int height = 0;
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
ComPtr<ID3D12DescriptorHeap> rtv_heap;
RenderingDeviceDriverD3D12::RenderPassInfo render_pass;
RenderingDeviceDriverD3D12::FramebufferInfo framebuffers[IMAGE_COUNT];
};
struct LocalDevice : public DeviceBasics {
@ -161,8 +170,8 @@ private:
// Commands.
Vector<ID3D12CommandList *> command_list_queue;
int command_list_count = 1;
LocalVector<ID3D12CommandList *> command_list_queue;
uint32_t command_list_count = 1;
static void _debug_message_func(
D3D12_MESSAGE_CATEGORY p_category,
@ -187,59 +196,63 @@ protected:
virtual bool _use_validation_layers();
public:
uint32_t get_feat_level_major() const { return feature_level / 10; };
uint32_t get_feat_level_minor() const { return feature_level % 10; };
virtual const char *get_api_name() const override final { return "D3D12"; };
virtual RenderingDevice::Capabilities get_device_capabilities() const override final;
const SubgroupCapabilities &get_subgroup_capabilities() const { return subgroup_capabilities; };
const MultiviewCapabilities &get_multiview_capabilities() const { return multiview_capabilities; };
virtual const RDD::MultiviewCapabilities &get_multiview_capabilities() const override final { return multiview_capabilities; };
const VRSCapabilities &get_vrs_capabilities() const { return vrs_capabilities; };
const ShaderCapabilities &get_shader_capabilities() const { return shader_capabilities; };
const StorageBufferCapabilities &get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
const FormatCapabilities &get_format_capabilities() const { return format_capabilities; };
ComPtr<ID3D12Device> get_device();
ComPtr<IDXGIAdapter> get_adapter();
D3D12MA::Allocator *get_allocator();
int get_swapchain_image_count() const;
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);
int window_get_height(DisplayServer::WindowID p_window = 0);
bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0);
void window_destroy(DisplayServer::WindowID p_window_id);
CD3DX12_CPU_DESCRIPTOR_HANDLE window_get_framebuffer_rtv_handle(DisplayServer::WindowID p_window = 0);
ID3D12Resource *window_get_framebuffer_texture(DisplayServer::WindowID p_window = 0);
ID3D12Device *get_device();
IDXGIAdapter *get_adapter();
virtual int get_swapchain_image_count() const override final;
RID local_device_create();
ComPtr<ID3D12Device> local_device_get_d3d12_device(RID p_local_device);
void local_device_push_command_lists(RID p_local_device, ID3D12CommandList *const *p_lists, int p_count);
void local_device_sync(RID p_local_device);
void local_device_free(RID p_local_device);
struct WindowPlatformData {
HWND window;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
virtual void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) override final;
virtual int window_get_width(DisplayServer::WindowID p_window = 0) override final;
virtual int window_get_height(DisplayServer::WindowID p_window = 0) override final;
virtual bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0) override final;
virtual void window_destroy(DisplayServer::WindowID p_window_id) override final;
virtual RDD::RenderPassID window_get_render_pass(DisplayServer::WindowID p_window = 0) override final;
virtual RDD::FramebufferID window_get_framebuffer(DisplayServer::WindowID p_window = 0) override final;
virtual RID local_device_create() override final;
virtual void local_device_push_command_buffers(RID p_local_device, const RDD::CommandBufferID *p_buffers, int p_count) override final;
virtual void local_device_sync(RID p_local_device) override final;
virtual void local_device_free(RID p_local_device) override final;
DXGI_FORMAT get_screen_format() const;
DeviceLimits get_device_limits() const;
const DeviceLimits &get_device_limits() const;
void set_setup_list(ID3D12CommandList *p_command_list);
void append_command_list(ID3D12CommandList *p_command_list);
virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) override final;
virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) override final;
void resize_notify();
void flush(bool p_flush_setup = false, bool p_flush_pending = false);
void prepare_buffers(ID3D12GraphicsCommandList *p_command_list);
void postpare_buffers(ID3D12GraphicsCommandList *p_command_list);
Error swap_buffers();
Error initialize();
virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) override final;
virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) override final;
virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) override final;
virtual Error swap_buffers() override final;
virtual Error initialize() override final;
void command_begin_label(ID3D12GraphicsCommandList *p_command_list, String p_label_name, const Color p_color);
void command_insert_label(ID3D12GraphicsCommandList *p_command_list, String p_label_name, const Color p_color);
void command_end_label(ID3D12GraphicsCommandList *p_command_list);
virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
virtual void command_end_label(RDD::CommandBufferID p_command_buffer) override final;
void set_object_name(ID3D12Object *p_object, String p_object_name);
String get_device_vendor_name() const;
String get_device_name() const;
RenderingDevice::DeviceType get_device_type() const;
String get_device_api_version() const;
String get_device_pipeline_cache_uuid() const;
virtual String get_device_vendor_name() const override final;
virtual String get_device_name() const override final;
virtual RDD::DeviceType get_device_type() const override final;
virtual String get_device_api_version() const override final;
virtual String get_device_pipeline_cache_uuid() const override final;
void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);
DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const;
virtual void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) override final;
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const override final;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) override final;
D3D12Context();
virtual ~D3D12Context();

View File

@ -30,5 +30,22 @@
#include "d3d12_context.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wswitch"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
#if defined(_MSC_VER)
#pragma warning(disable : 4189 4324 4505)
#endif
#include "thirdparty/d3d12ma/D3D12MemAlloc.cpp"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,858 @@
/**************************************************************************/
/* rendering_device_driver_d3d12.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. */
/**************************************************************************/
#ifndef RENDERING_DEVICE_DRIVER_D3D12_H
#define RENDERING_DEVICE_DRIVER_D3D12_H
#include "core/templates/hash_map.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device_driver.h"
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wswitch"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#include "d3dx12.h"
#include <dxgi1_6.h>
#define D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED
#include "D3D12MemAlloc.h"
#include <wrl/client.h>
#if defined(_MSC_VER) && defined(MemoryBarrier)
// Annoying define from winnt.h. Reintroduced by some of the headers above.
#undef MemoryBarrier
#endif
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
using Microsoft::WRL::ComPtr;
#define D3D12_BITCODE_OFFSETS_NUM_STAGES 3
struct dxil_validator;
class D3D12Context;
// Design principles:
// - D3D12 structs are zero-initialized and fields not requiring a non-zero value are omitted (except in cases where expresivity reasons apply).
class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
friend class D3D12Context; // For FramebufferInfo, RenderPassInfo and CommandBufferInfo.
/*****************/
/**** GENERIC ****/
/*****************/
struct D3D12Format {
DXGI_FORMAT family = DXGI_FORMAT_UNKNOWN;
DXGI_FORMAT general_format = DXGI_FORMAT_UNKNOWN;
UINT swizzle = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
DXGI_FORMAT dsv_format = DXGI_FORMAT_UNKNOWN;
};
static const D3D12Format RD_TO_D3D12_FORMAT[RDD::DATA_FORMAT_MAX];
D3D12Context *context = nullptr;
ID3D12Device *device = nullptr; // Owned by the context.
class DescriptorsHeap {
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
ComPtr<ID3D12DescriptorHeap> heap;
uint32_t handle_size = 0;
public:
class Walker { // Texas Ranger.
friend class DescriptorsHeap;
uint32_t handle_size = 0;
uint32_t handle_count = 0;
D3D12_CPU_DESCRIPTOR_HANDLE first_cpu_handle = {};
D3D12_GPU_DESCRIPTOR_HANDLE first_gpu_handle = {};
uint32_t handle_index = 0;
public:
D3D12_CPU_DESCRIPTOR_HANDLE get_curr_cpu_handle();
D3D12_GPU_DESCRIPTOR_HANDLE get_curr_gpu_handle();
_FORCE_INLINE_ void rewind() { handle_index = 0; }
void advance(uint32_t p_count = 1);
uint32_t get_current_handle_index() const { return handle_index; }
uint32_t get_free_handles() { return handle_count - handle_index; }
bool is_at_eof() { return handle_index == handle_count; }
};
Error allocate(ID3D12Device *m_device, D3D12_DESCRIPTOR_HEAP_TYPE m_type, uint32_t m_descriptor_count, bool p_for_gpu);
uint32_t get_descriptor_count() const { return desc.NumDescriptors; }
ID3D12DescriptorHeap *get_heap() const { return heap.Get(); }
Walker make_walker() const;
};
struct {
ComPtr<ID3D12CommandSignature> draw;
ComPtr<ID3D12CommandSignature> draw_indexed;
ComPtr<ID3D12CommandSignature> dispatch;
} indirect_cmd_signatures;
/****************/
/**** MEMORY ****/
/****************/
ComPtr<D3D12MA::Allocator> allocator;
#define USE_SMALL_ALLOCS_POOL // Disabled by now; seems not to be beneficial as it is in Vulkan.
#ifdef USE_SMALL_ALLOCS_POOL
union AllocPoolKey {
struct {
D3D12_HEAP_TYPE heap_type;
D3D12_HEAP_FLAGS heap_flags;
};
uint64_t key = 0;
};
HashMap<uint64_t, ComPtr<D3D12MA::Pool>> small_allocs_pools;
D3D12MA::Pool *_find_or_create_small_allocs_pool(D3D12_HEAP_TYPE p_heap_type, D3D12_HEAP_FLAGS p_heap_flags);
#endif
/******************/
/**** RESOURCE ****/
/******************/
struct ResourceInfo {
struct States {
// As many subresources as mipmaps * layers; planes (for depth-stencil) are tracked together.
TightLocalVector<D3D12_RESOURCE_STATES> subresource_states; // Used only if not a view.
uint32_t last_batch_transitioned_to_uav = 0;
uint32_t last_batch_with_uav_barrier = 0;
};
ID3D12Resource *resource = nullptr; // Non-null even if a view.
struct {
ComPtr<ID3D12Resource> resource;
ComPtr<D3D12MA::Allocation> allocation;
States states;
} owner_info; // All empty if a view.
States *states_ptr = nullptr; // Own or from another if a view.
};
struct BarrierRequest {
static const uint32_t MAX_GROUPS = 4;
// Maybe this is too much data to have it locally. Benchmarking may reveal that
// cache would be used better by having a maximum of local subresource masks and beyond
// that have an allocated vector with the rest.
static const uint32_t MAX_SUBRESOURCES = 4096;
ID3D12Resource *dx_resource = nullptr;
uint8_t subres_mask_qwords = 0;
uint8_t planes = 0;
struct Group {
D3D12_RESOURCE_STATES states = {};
static_assert(MAX_SUBRESOURCES % 64 == 0);
uint64_t subres_mask[MAX_SUBRESOURCES / 64] = {};
} groups[MAX_GROUPS];
uint8_t groups_count = 0;
static const D3D12_RESOURCE_STATES DELETED_GROUP = D3D12_RESOURCE_STATE_COMMON;
};
PagedAllocator<HashMapElement<ResourceInfo::States *, BarrierRequest>> res_barriers_requests_allocator;
HashMap<ResourceInfo::States *, BarrierRequest, HashMapHasherDefault, HashMapComparatorDefault<ResourceInfo::States *>, decltype(res_barriers_requests_allocator)> res_barriers_requests;
LocalVector<D3D12_RESOURCE_BARRIER> res_barriers;
uint32_t res_barriers_count = 0;
uint32_t res_barriers_batch = 0;
#ifdef DEV_ENABLED
int frame_barriers_count = 0;
int frame_barriers_batches_count = 0;
uint64_t frame_barriers_cpu_time = 0;
#endif
void _resource_transition_batch(ResourceInfo *p_resource, uint32_t p_subresource, uint32_t p_num_planes, D3D12_RESOURCE_STATES p_new_state, ID3D12Resource *p_resource_override = nullptr);
void _resource_transitions_flush(ID3D12GraphicsCommandList *p_cmd_list);
/*****************/
/**** BUFFERS ****/
/*****************/
struct BufferInfo : public ResourceInfo {
DataFormat texel_format = DATA_FORMAT_MAX;
uint64_t size = 0;
struct {
bool usable_as_uav : 1;
bool is_for_upload : 1;
} flags = {};
};
public:
virtual BufferID buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type) override final;
virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) override final;
virtual void buffer_free(BufferID p_buffer) override final;
virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) override final;
virtual uint8_t *buffer_map(BufferID p_buffer) override final;
virtual void buffer_unmap(BufferID p_buffer) override final;
/*****************/
/**** TEXTURE ****/
/*****************/
private:
struct TextureInfo : public ResourceInfo {
DataFormat format = DATA_FORMAT_MAX;
CD3DX12_RESOURCE_DESC desc = {};
uint32_t base_layer = 0;
uint32_t layers = 0;
uint32_t base_mip = 0;
uint32_t mipmaps = 0;
struct {
D3D12_SHADER_RESOURCE_VIEW_DESC srv;
D3D12_UNORDERED_ACCESS_VIEW_DESC uav;
} view_descs = {};
ID3D12Resource *main_texture = nullptr;
struct {
D3D12_UNORDERED_ACCESS_VIEW_DESC main_uav_desc;
struct {
HashMap<DXGI_FORMAT, ComPtr<ID3D12Resource>> aliases; // Key is the DXGI format family.
} owner_info = {};
} aliasing_hack = {}; // [[CROSS_FAMILY_ALIASING]]
UINT mapped_subresource = UINT_MAX;
};
HashMap<DXGI_FORMAT, uint32_t> format_sample_counts_mask_cache;
uint32_t _find_max_common_supported_sample_count(VectorView<DXGI_FORMAT> p_formats);
UINT _compute_component_mapping(const TextureView &p_view);
UINT _compute_plane_slice(DataFormat p_format, BitField<TextureAspectBits> p_aspect_bits);
UINT _compute_plane_slice(DataFormat p_format, TextureAspect p_aspect);
struct CommandBufferInfo;
void _discard_texture_subresources(const TextureInfo *p_tex_info, const CommandBufferInfo *p_cmd_buf_info);
public:
virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) override final;
virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) override final;
virtual TextureID texture_create_shared(TextureID p_original_texture, const TextureView &p_view) override final;
virtual TextureID texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) override final;
virtual void texture_free(TextureID p_texture) override final;
virtual uint64_t texture_get_allocation_size(TextureID p_texture) override final;
virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) override final;
virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) override final;
virtual void texture_unmap(TextureID p_texture) override final;
virtual BitField<TextureUsageBits> texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) override final;
/*****************/
/**** SAMPLER ****/
/*****************/
private:
LocalVector<D3D12_SAMPLER_DESC> samplers;
public:
virtual SamplerID sampler_create(const SamplerState &p_state) final override;
virtual void sampler_free(SamplerID p_sampler) final override;
virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) override final;
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
private:
struct VertexFormatInfo {
TightLocalVector<D3D12_INPUT_ELEMENT_DESC> input_elem_descs;
TightLocalVector<UINT> vertex_buffer_strides;
};
public:
virtual VertexFormatID vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) override final;
virtual void vertex_format_free(VertexFormatID p_vertex_format) override final;
/******************/
/**** BARRIERS ****/
/******************/
virtual void command_pipeline_barrier(
CommandBufferID p_cmd_buffer,
BitField<RDD::PipelineStageBits> p_src_stages,
BitField<RDD::PipelineStageBits> p_dst_stages,
VectorView<RDD::MemoryBarrier> p_memory_barriers,
VectorView<RDD::BufferBarrier> p_buffer_barriers,
VectorView<RDD::TextureBarrier> p_texture_barriers) override final;
/*************************/
/**** COMMAND BUFFERS ****/
/*************************/
// ----- POOL -----
virtual CommandPoolID command_pool_create(CommandBufferType p_cmd_buffer_type) override final;
virtual void command_pool_free(CommandPoolID p_cmd_pool) override final;
// ----- BUFFER -----
private:
// Belongs to RENDERING-SUBPASS, but needed here.
struct FramebufferInfo;
struct RenderPassInfo;
struct RenderPassState {
uint32_t current_subpass = UINT32_MAX;
const FramebufferInfo *fb_info = nullptr;
const RenderPassInfo *pass_info = nullptr;
CD3DX12_RECT region_rect = {};
bool region_is_all = false;
const VertexFormatInfo *vf_info = nullptr;
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_views[8] = {};
uint32_t vertex_buffer_count = 0;
};
// Leveraging knowledge of actual usage and D3D12 specifics (namely, command lists from the same allocator
// can't be freely begun and ended), an allocator per list works better.
struct CommandBufferInfo {
ComPtr<ID3D12CommandAllocator> cmd_allocator;
ComPtr<ID3D12GraphicsCommandList> cmd_list;
ID3D12PipelineState *graphics_pso = nullptr;
ID3D12PipelineState *compute_pso = nullptr;
uint32_t graphics_root_signature_crc = 0;
uint32_t compute_root_signature_crc = 0;
RenderPassState render_pass_state;
};
RBMap<CommandPoolID, LocalVector<CommandBufferInfo *>> pools_command_buffers;
CommandPoolID last_command_pool_id;
public:
virtual CommandBufferID command_buffer_create(CommandBufferType p_cmd_buffer_type, CommandPoolID p_cmd_pool) override final;
virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) override final;
virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) override final;
virtual void command_buffer_end(CommandBufferID p_cmd_buffer) override final;
virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) override final;
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
private:
struct FramebufferInfo {
bool is_screen = false;
Size2i size;
TightLocalVector<uint32_t> attachments_handle_inds; // RTV heap index for color; DSV heap index for DSV.
DescriptorsHeap rtv_heap;
DescriptorsHeap dsv_heap; // Used only if not for screen and some depth-stencil attachments.
TightLocalVector<TextureID> attachments; // Color and depth-stencil. Used if not screen.
TextureID vrs_attachment;
};
D3D12_RENDER_TARGET_VIEW_DESC _make_rtv_for_texture(const TextureInfo *p_texture_info, uint32_t p_mipmap_offset, uint32_t p_layer_offset, uint32_t p_layers, bool p_add_bases = true);
D3D12_DEPTH_STENCIL_VIEW_DESC _make_dsv_for_texture(const TextureInfo *p_texture_info);
public:
virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) override final;
virtual void framebuffer_free(FramebufferID p_framebuffer) override final;
/****************/
/**** SHADER ****/
/****************/
private:
static const uint32_t ROOT_SIGNATURE_SIZE = 256;
static const uint32_t PUSH_CONSTANT_SIZE = 128; // Mimicking Vulkan.
enum {
// We can only aim to set a maximum here, since depending on the shader
// there may be more or less root signature free for descriptor tables.
// Therefore, we'll have to rely on the final check at runtime, when building
// the root signature structure for a given shader.
// To be precise, these may be present or not, and their size vary statically:
// - Push constant (we'll assume this is always present to avoid reserving much
// more space for descriptor sets than needed for almost any imaginable case,
// given that most shader templates feature push constants).
// - NIR-DXIL runtime data.
MAX_UNIFORM_SETS = (ROOT_SIGNATURE_SIZE - PUSH_CONSTANT_SIZE) / sizeof(uint32_t),
};
enum RootSignatureLocationType {
RS_LOC_TYPE_RESOURCE,
RS_LOC_TYPE_SAMPLER,
};
enum ResourceClass {
RES_CLASS_INVALID,
RES_CLASS_CBV,
RES_CLASS_SRV,
RES_CLASS_UAV,
};
struct ShaderBinary {
// Version 1: Initial.
// Version 2: 64-bit vertex input mask.
// Version 3: Added SC stage mask.
static const uint32_t VERSION = 3;
// Phase 1: SPIR-V reflection, where the Vulkan/RD interface of the shader is discovered.
// Phase 2: SPIR-V to DXIL translation, where the DXIL interface is discovered, which may have gaps due to optimizations.
struct DataBinding {
// - Phase 1.
uint32_t type = 0;
uint32_t binding = 0;
uint32_t stages = 0;
uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements).
uint32_t writable = 0;
// - Phase 2.
uint32_t res_class = 0;
uint32_t has_sampler = 0;
uint32_t dxil_stages = 0;
struct RootSignatureLocation {
uint32_t root_param_idx = UINT32_MAX; // UINT32_MAX if unused.
uint32_t range_idx = UINT32_MAX; // UINT32_MAX if unused.
};
RootSignatureLocation root_sig_locations[2]; // Index is RootSignatureLocationType.
// We need to sort these to fill the root signature locations properly.
bool operator<(const DataBinding &p_other) const {
return binding < p_other.binding;
}
};
struct SpecializationConstant {
// - Phase 1.
uint32_t type = 0;
uint32_t constant_id = 0;
union {
uint32_t int_value = 0;
float float_value;
bool bool_value;
};
uint32_t stage_flags = 0;
// - Phase 2.
uint64_t stages_bit_offsets[D3D12_BITCODE_OFFSETS_NUM_STAGES] = {};
};
struct Data {
uint64_t vertex_input_mask = 0;
uint32_t fragment_output_mask = 0;
uint32_t specialization_constants_count = 0;
uint32_t spirv_specialization_constants_ids_mask = 0;
uint32_t is_compute = 0;
uint32_t compute_local_size[3] = {};
uint32_t set_count = 0;
uint32_t push_constant_size = 0;
uint32_t dxil_push_constant_stages = 0; // Phase 2.
uint32_t nir_runtime_data_root_param_idx = 0; // Phase 2.
uint32_t stage_count = 0;
uint32_t shader_name_len = 0;
uint32_t root_signature_len = 0;
uint32_t root_signature_crc = 0;
};
};
struct ShaderInfo {
uint32_t dxil_push_constant_size = 0;
uint32_t nir_runtime_data_root_param_idx = UINT32_MAX;
bool is_compute = false;
struct UniformBindingInfo {
uint32_t stages = 0; // Actual shader stages using the uniform (0 if totally optimized out).
ResourceClass res_class = RES_CLASS_INVALID;
UniformType type = UNIFORM_TYPE_MAX;
uint32_t length = UINT32_MAX;
#ifdef DEV_ENABLED
bool writable = false;
#endif
struct RootSignatureLocation {
uint32_t root_param_idx = UINT32_MAX;
uint32_t range_idx = UINT32_MAX;
};
struct {
RootSignatureLocation resource;
RootSignatureLocation sampler;
} root_sig_locations;
};
struct UniformSet {
TightLocalVector<UniformBindingInfo> bindings;
struct {
uint32_t resources = 0;
uint32_t samplers = 0;
} num_root_params;
};
TightLocalVector<UniformSet> sets;
struct SpecializationConstant {
uint32_t constant_id = UINT32_MAX;
uint32_t int_value = UINT32_MAX;
uint64_t stages_bit_offsets[D3D12_BITCODE_OFFSETS_NUM_STAGES] = {};
};
TightLocalVector<SpecializationConstant> specialization_constants;
uint32_t spirv_specialization_constants_ids_mask = 0;
HashMap<ShaderStage, Vector<uint8_t>> stages_bytecode;
ComPtr<ID3D12RootSignature> root_signature;
ComPtr<ID3D12RootSignatureDeserializer> root_signature_deserializer;
const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc = nullptr; // Owned by the deserializer.
uint32_t root_signature_crc = 0;
};
Mutex dxil_mutex;
HashMap<int, dxil_validator *> dxil_validators; // One per WorkerThreadPool thread used for shader compilation, plus one (-1) for all the other.
dxil_validator *_get_dxil_validator_for_current_thread();
uint32_t _shader_patch_dxil_specialization_constant(
PipelineSpecializationConstantType p_type,
const void *p_value,
const uint64_t (&p_stages_bit_offsets)[D3D12_BITCODE_OFFSETS_NUM_STAGES],
HashMap<ShaderStage, Vector<uint8_t>> &r_stages_bytecodes,
bool p_is_first_patch);
bool _shader_apply_specialization_constants(
const ShaderInfo *p_shader_info,
VectorView<PipelineSpecializationConstant> p_specialization_constants,
HashMap<ShaderStage, Vector<uint8_t>> &r_final_stages_bytecode);
bool _shader_sign_dxil_bytecode(ShaderStage p_stage, Vector<uint8_t> &r_dxil_blob);
public:
virtual String shader_get_binary_cache_key() override final;
virtual Vector<uint8_t> shader_compile_binary_from_spirv(VectorView<ShaderStageSPIRVData> p_spirv, const String &p_shader_name) override final;
virtual ShaderID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) override final;
virtual uint32_t shader_get_layout_hash(ShaderID p_shader) override final;
virtual void shader_free(ShaderID p_shader) override final;
/*********************/
/**** UNIFORM SET ****/
/*********************/
private:
struct RootDescriptorTable {
uint32_t root_param_idx = UINT32_MAX;
D3D12_GPU_DESCRIPTOR_HANDLE start_gpu_handle = {};
};
struct UniformSetInfo {
struct {
DescriptorsHeap resources;
DescriptorsHeap samplers;
} desc_heaps;
struct StateRequirement {
ResourceInfo *resource = nullptr;
bool is_buffer = false;
D3D12_RESOURCE_STATES states = {};
uint64_t shader_uniform_idx_mask = 0;
};
TightLocalVector<StateRequirement> resource_states;
struct RecentBind {
uint64_t segment_serial = 0;
uint32_t root_signature_crc = 0;
struct {
TightLocalVector<RootDescriptorTable> resources;
TightLocalVector<RootDescriptorTable> samplers;
} root_tables;
int uses = 0;
} recent_binds[4]; // A better amount may be empirically found.
#ifdef DEV_ENABLED
// Filthy, but useful for dev.
struct ResourceDescInfo {
D3D12_DESCRIPTOR_RANGE_TYPE type;
D3D12_SRV_DIMENSION srv_dimension;
};
TightLocalVector<ResourceDescInfo> resources_desc_info;
#endif
};
public:
virtual UniformSetID uniform_set_create(VectorView<BoundUniform> p_uniforms, ShaderID p_shader, uint32_t p_set_index) override final;
virtual void uniform_set_free(UniformSetID p_uniform_set) override final;
// ----- COMMANDS -----
virtual void command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
private:
void _command_bind_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index, bool p_for_compute);
public:
/******************/
/**** TRANSFER ****/
/******************/
virtual void command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) override final;
virtual void command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView<BufferCopyRegion> p_regions) override final;
virtual void command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<TextureCopyRegion> p_regions) override final;
virtual void command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) override final;
virtual void command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) override final;
virtual void command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<BufferTextureCopyRegion> p_regions) override final;
virtual void command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView<BufferTextureCopyRegion> p_regions) override final;
/******************/
/**** PIPELINE ****/
/******************/
virtual void pipeline_free(PipelineID p_pipeline) override final;
private:
HashMap<ID3D12PipelineState *, const ShaderInfo *> pipelines_shaders;
public:
// ----- BINDING -----
virtual void command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_dst_first_index, VectorView<uint32_t> p_data) override final;
// ----- CACHE -----
virtual bool pipeline_cache_create(const Vector<uint8_t> &p_data) override final;
virtual void pipeline_cache_free() override final;
virtual size_t pipeline_cache_query_size() override final;
virtual Vector<uint8_t> pipeline_cache_serialize() override final;
/*******************/
/**** RENDERING ****/
/*******************/
// ----- SUBPASS -----
private:
struct RenderPassInfo {
TightLocalVector<Attachment> attachments;
TightLocalVector<Subpass> subpasses;
uint32_t view_count = 0;
uint32_t max_supported_sample_count = 0;
};
public:
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) override final;
virtual void render_pass_free(RenderPassID p_render_pass) override final;
// ----- COMMANDS -----
virtual void command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView<RenderPassClearValue> p_clear_values) override final;
private:
void _end_render_pass(CommandBufferID p_cmd_buffer);
public:
virtual void command_end_render_pass(CommandBufferID p_cmd_buffer) override final;
virtual void command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) override final;
virtual void command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_viewports) override final;
virtual void command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_scissors) override final;
virtual void command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView<AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) override final;
// Binding.
virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final;
virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
// Drawing.
virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) override final;
virtual void command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) override final;
virtual void command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final;
// Buffer binding.
virtual void command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) override final;
virtual void command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) override final;
private:
void _bind_vertex_buffers(CommandBufferInfo *p_cmd_buf_info);
public:
// Dynamic state.
virtual void command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) override final;
virtual void command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) override final;
// ----- PIPELINE -----
private:
struct RenderPipelineExtraInfo {
struct {
D3D12_PRIMITIVE_TOPOLOGY primitive_topology = {};
Color blend_constant;
float depth_bounds_min = 0.0f;
float depth_bounds_max = 0.0f;
uint32_t stencil_reference = 0;
} dyn_params;
const VertexFormatInfo *vf_info = nullptr;
};
HashMap<ID3D12PipelineState *, RenderPipelineExtraInfo> render_psos_extra_info;
public:
virtual PipelineID render_pipeline_create(
ShaderID p_shader,
VertexFormatID p_vertex_format,
RenderPrimitive p_render_primitive,
PipelineRasterizationState p_rasterization_state,
PipelineMultisampleState p_multisample_state,
PipelineDepthStencilState p_depth_stencil_state,
PipelineColorBlendState p_blend_state,
VectorView<int32_t> p_color_attachments,
BitField<PipelineDynamicStateFlags> p_dynamic_state,
RenderPassID p_render_pass,
uint32_t p_render_subpass,
VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;
/*****************/
/**** COMPUTE ****/
/*****************/
// ----- COMMANDS -----
// Binding.
virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final;
virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
// Dispatching.
virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) override final;
virtual void command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) override final;
// ----- PIPELINE -----
virtual PipelineID compute_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;
/*****************/
/**** QUERIES ****/
/*****************/
// ----- TIMESTAMP -----
private:
struct TimestampQueryPoolInfo {
ComPtr<ID3D12QueryHeap> query_heap;
uint32_t query_count = 0;
ComPtr<D3D12MA::Allocation> results_buffer_allocation;
};
public:
// Basic.
virtual QueryPoolID timestamp_query_pool_create(uint32_t p_query_count) override final;
virtual void timestamp_query_pool_free(QueryPoolID p_pool_id) override final;
virtual void timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) override final;
virtual uint64_t timestamp_query_result_to_time(uint64_t p_result) override final;
// Commands.
virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) override final;
virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) override final;
/****************/
/**** SCREEN ****/
/****************/
virtual DataFormat screen_get_format() override final;
/********************/
/**** SUBMISSION ****/
/********************/
private:
struct FrameInfo {
struct {
DescriptorsHeap resources;
DescriptorsHeap samplers;
DescriptorsHeap aux;
DescriptorsHeap rtv;
} desc_heaps;
struct {
DescriptorsHeap::Walker resources;
DescriptorsHeap::Walker samplers;
DescriptorsHeap::Walker aux;
DescriptorsHeap::Walker rtv;
} desc_heap_walkers;
struct {
bool resources = false;
bool samplers = false;
bool aux = false;
bool rtv = false;
} desc_heaps_exhausted_reported;
CD3DX12_CPU_DESCRIPTOR_HANDLE null_rtv_handle = {}; // For [[MANUAL_SUBPASSES]].
ComPtr<D3D12MA::Allocation> aux_resource;
uint32_t segment_serial = 0;
#ifdef DEV_ENABLED
uint32_t uniform_set_reused = 0;
#endif
};
TightLocalVector<FrameInfo> frames;
uint32_t frame_idx = 0;
uint32_t frames_drawn = 0;
uint32_t segment_serial = 0;
bool segment_begun = false;
public:
virtual void begin_segment(CommandBufferID p_cmd_buffer, uint32_t p_frame_index, uint32_t p_frames_drawn) override final;
virtual void end_segment() override final;
/**************/
/**** MISC ****/
/**************/
virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) override final;
virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) override final;
virtual uint64_t get_total_memory_used() override final;
virtual uint64_t limit_get(Limit p_limit) override final;
virtual uint64_t api_trait_get(ApiTrait p_trait) override final;
virtual bool has_feature(Features p_feature) override final;
virtual const MultiviewCapabilities &get_multiview_capabilities() override final;
private:
/*********************/
/**** BOOKKEEPING ****/
/*********************/
using VersatileResource = VersatileResourceTemplate<
BufferInfo,
TextureInfo,
TextureInfo,
TextureInfo,
VertexFormatInfo,
CommandBufferInfo,
FramebufferInfo,
ShaderInfo,
UniformSetInfo,
RenderPassInfo,
TimestampQueryPoolInfo>;
PagedAllocator<VersatileResource> resources_allocator;
/******************/
public:
RenderingDeviceDriverD3D12(D3D12Context *p_context, ID3D12Device *p_device, uint32_t p_frame_count);
virtual ~RenderingDeviceDriverD3D12();
};
#endif // RENDERING_DEVICE_DRIVER_D3D12_H

View File

@ -2,6 +2,8 @@
Import("env")
env.Append(CPPDEFINES=["RD_ENABLED"])
thirdparty_obj = []
thirdparty_dir = "#thirdparty/vulkan"
thirdparty_volk_dir = "#thirdparty/volk"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,482 @@
/**************************************************************************/
/* rendering_device_driver_vulkan.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. */
/**************************************************************************/
#ifndef RENDERING_DEVICE_DRIVER_VULKAN_H
#define RENDERING_DEVICE_DRIVER_VULKAN_H
#include "core/templates/hash_map.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device_driver.h"
#ifdef DEBUG_ENABLED
#ifndef _MSC_VER
#define _DEBUG
#endif
#endif
#include "thirdparty/vulkan/vk_mem_alloc.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
class VulkanContext;
// Design principles:
// - Vulkan structs are zero-initialized and fields not requiring a non-zero value are omitted (except in cases where expresivity reasons apply).
class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
/*****************/
/**** GENERIC ****/
/*****************/
VulkanContext *context = nullptr;
VkDevice vk_device = VK_NULL_HANDLE; // Owned by the context.
/****************/
/**** MEMORY ****/
/****************/
VmaAllocator allocator = nullptr;
HashMap<uint32_t, VmaPool> small_allocs_pools;
VmaPool _find_or_create_small_allocs_pool(uint32_t p_mem_type_index);
/*****************/
/**** BUFFERS ****/
/*****************/
private:
struct BufferInfo {
VkBuffer vk_buffer = VK_NULL_HANDLE;
struct {
VmaAllocation handle = nullptr;
uint64_t size = UINT64_MAX;
} allocation;
uint64_t size = 0;
VkBufferView vk_view = VK_NULL_HANDLE; // For texel buffers.
};
public:
virtual BufferID buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type) override final;
virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) override final;
virtual void buffer_free(BufferID p_buffer) override final;
virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) override final;
virtual uint8_t *buffer_map(BufferID p_buffer) override final;
virtual void buffer_unmap(BufferID p_buffer) override final;
/*****************/
/**** TEXTURE ****/
/*****************/
struct TextureInfo {
VkImageView vk_view = VK_NULL_HANDLE;
DataFormat rd_format = DATA_FORMAT_MAX;
VkImageCreateInfo vk_create_info = {};
VkImageViewCreateInfo vk_view_create_info = {};
struct {
VmaAllocation handle = nullptr;
VmaAllocationInfo info = {};
} allocation; // All 0/null if just a view.
};
VkSampleCountFlagBits _ensure_supported_sample_count(TextureSamples p_requested_sample_count);
public:
virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) override final;
virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) override final;
virtual TextureID texture_create_shared(TextureID p_original_texture, const TextureView &p_view) override final;
virtual TextureID texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) override final;
virtual void texture_free(TextureID p_texture) override final;
virtual uint64_t texture_get_allocation_size(TextureID p_texture) override final;
virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) override final;
virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) override final;
virtual void texture_unmap(TextureID p_texture) override final;
virtual BitField<TextureUsageBits> texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) override final;
/*****************/
/**** SAMPLER ****/
/*****************/
public:
virtual SamplerID sampler_create(const SamplerState &p_state) final override;
virtual void sampler_free(SamplerID p_sampler) final override;
virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) override final;
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
private:
struct VertexFormatInfo {
TightLocalVector<VkVertexInputBindingDescription> vk_bindings;
TightLocalVector<VkVertexInputAttributeDescription> vk_attributes;
VkPipelineVertexInputStateCreateInfo vk_create_info = {};
};
public:
virtual VertexFormatID vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) override final;
virtual void vertex_format_free(VertexFormatID p_vertex_format) override final;
/******************/
/**** BARRIERS ****/
/******************/
virtual void command_pipeline_barrier(
CommandBufferID p_cmd_buffer,
BitField<PipelineStageBits> p_src_stages,
BitField<PipelineStageBits> p_dst_stages,
VectorView<MemoryBarrier> p_memory_barriers,
VectorView<BufferBarrier> p_buffer_barriers,
VectorView<TextureBarrier> p_texture_barriers) override final;
/*************************/
/**** COMMAND BUFFERS ****/
/*************************/
private:
#ifdef DEBUG_ENABLED
// Vulkan doesn't need to know if the command buffers created in a pool
// will be primary or secondary, but RDD works like that, so we will enforce.
HashSet<CommandPoolID> secondary_cmd_pools;
HashSet<CommandBufferID> secondary_cmd_buffers;
#endif
public:
// ----- POOL -----
virtual CommandPoolID command_pool_create(CommandBufferType p_cmd_buffer_type) override final;
virtual void command_pool_free(CommandPoolID p_cmd_pool) override final;
// ----- BUFFER -----
virtual CommandBufferID command_buffer_create(CommandBufferType p_cmd_buffer_type, CommandPoolID p_cmd_pool) override final;
virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) override final;
virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) override final;
virtual void command_buffer_end(CommandBufferID p_cmd_buffer) override final;
virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) override final;
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) override final;
virtual void framebuffer_free(FramebufferID p_framebuffer) override final;
/****************/
/**** SHADER ****/
/****************/
private:
struct ShaderBinary {
// Version 1: initial.
// Version 2: Added shader name.
// Version 3: Added writable.
// Version 4: 64-bit vertex input mask.
static const uint32_t VERSION = 4;
struct DataBinding {
uint32_t type = 0;
uint32_t binding = 0;
uint32_t stages = 0;
uint32_t length = 0; // Size of arrays (in total elements), or UBOs (in bytes * total elements).
uint32_t writable = 0;
};
struct SpecializationConstant {
uint32_t type = 0;
uint32_t constant_id = 0;
uint32_t int_value = 0;
uint32_t stage_flags = 0;
};
struct Data {
uint64_t vertex_input_mask = 0;
uint32_t fragment_output_mask = 0;
uint32_t specialization_constants_count = 0;
uint32_t is_compute = 0;
uint32_t compute_local_size[3] = {};
uint32_t set_count = 0;
uint32_t push_constant_size = 0;
uint32_t vk_push_constant_stages_mask = 0;
uint32_t stage_count = 0;
uint32_t shader_name_len = 0;
};
};
struct ShaderInfo {
VkShaderStageFlags vk_push_constant_stages = 0;
TightLocalVector<VkPipelineShaderStageCreateInfo> vk_stages_create_info;
TightLocalVector<VkDescriptorSetLayout> vk_descriptor_set_layouts;
VkPipelineLayout vk_pipeline_layout = VK_NULL_HANDLE;
};
public:
virtual String shader_get_binary_cache_key() override final;
virtual Vector<uint8_t> shader_compile_binary_from_spirv(VectorView<ShaderStageSPIRVData> p_spirv, const String &p_shader_name) override final;
virtual ShaderID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) override final;
virtual void shader_free(ShaderID p_shader) override final;
/*********************/
/**** UNIFORM SET ****/
/*********************/
// Descriptor sets require allocation from a pool.
// The documentation on how to use pools properly
// is scarce, and the documentation is strange.
//
// Basically, you can mix and match pools as you
// like, but you'll run into fragmentation issues.
// Because of this, the recommended approach is to
// create a pool for every descriptor set type, as
// this prevents fragmentation.
//
// This is implemented here as a having a list of
// pools (each can contain up to 64 sets) for each
// set layout. The amount of sets for each type
// is used as the key.
private:
static const uint32_t MAX_UNIFORM_POOL_ELEMENT = 65535;
struct DescriptorSetPoolKey {
uint16_t uniform_type[UNIFORM_TYPE_MAX] = {};
bool operator<(const DescriptorSetPoolKey &p_other) const {
return memcmp(uniform_type, p_other.uniform_type, sizeof(uniform_type)) < 0;
}
};
using DescriptorSetPools = RBMap<DescriptorSetPoolKey, HashMap<VkDescriptorPool, uint32_t>>;
DescriptorSetPools descriptor_set_pools;
uint32_t max_descriptor_sets_per_pool = 0;
VkDescriptorPool _descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it);
void _descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool);
struct UniformSetInfo {
VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE;
VkDescriptorPool vk_descriptor_pool = VK_NULL_HANDLE;
DescriptorSetPools::Iterator pool_sets_it = {};
};
public:
virtual UniformSetID uniform_set_create(VectorView<BoundUniform> p_uniforms, ShaderID p_shader, uint32_t p_set_index) override final;
virtual void uniform_set_free(UniformSetID p_uniform_set) override final;
// ----- COMMANDS -----
virtual void command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
/******************/
/**** TRANSFER ****/
/******************/
virtual void command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) override final;
virtual void command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView<BufferCopyRegion> p_regions) override final;
virtual void command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<TextureCopyRegion> p_regions) override final;
virtual void command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) override final;
virtual void command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) override final;
virtual void command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<BufferTextureCopyRegion> p_regions) override final;
virtual void command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView<BufferTextureCopyRegion> p_regions) override final;
/******************/
/**** PIPELINE ****/
/******************/
private:
struct PipelineCacheHeader {
uint32_t magic = 0;
uint32_t data_size = 0;
uint64_t data_hash = 0;
uint32_t vendor_id = 0;
uint32_t device_id = 0;
uint32_t driver_version = 0;
uint8_t uuid[VK_UUID_SIZE] = {};
uint8_t driver_abi = 0;
};
struct PipelineCache {
String file_path;
size_t current_size = 0;
Vector<uint8_t> buffer; // Header then data.
VkPipelineCache vk_cache = VK_NULL_HANDLE;
};
static int caching_instance_count;
PipelineCache pipelines_cache;
public:
virtual void pipeline_free(PipelineID p_pipeline) override final;
// ----- BINDING -----
virtual void command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_first_index, VectorView<uint32_t> p_data) override final;
// ----- CACHE -----
virtual bool pipeline_cache_create(const Vector<uint8_t> &p_data) override final;
virtual void pipeline_cache_free() override final;
virtual size_t pipeline_cache_query_size() override final;
virtual Vector<uint8_t> pipeline_cache_serialize() override final;
/*******************/
/**** RENDERING ****/
/*******************/
// ----- SUBPASS -----
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) override final;
virtual void render_pass_free(RenderPassID p_render_pass) override final;
// ----- COMMANDS -----
virtual void command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView<RenderPassClearValue> p_clear_values) override final;
virtual void command_end_render_pass(CommandBufferID p_cmd_buffer) override final;
virtual void command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) override final;
virtual void command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_viewports) override final;
virtual void command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_scissors) override final;
virtual void command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView<AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) override final;
// Binding.
virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final;
virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
// Drawing.
virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) override final;
virtual void command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) override final;
virtual void command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) override final;
virtual void command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) override final;
// Buffer binding.
virtual void command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) override final;
virtual void command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) override final;
// Dynamic state.
virtual void command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) override final;
virtual void command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) override final;
// ----- PIPELINE -----
virtual PipelineID render_pipeline_create(
ShaderID p_shader,
VertexFormatID p_vertex_format,
RenderPrimitive p_render_primitive,
PipelineRasterizationState p_rasterization_state,
PipelineMultisampleState p_multisample_state,
PipelineDepthStencilState p_depth_stencil_state,
PipelineColorBlendState p_blend_state,
VectorView<int32_t> p_color_attachments,
BitField<PipelineDynamicStateFlags> p_dynamic_state,
RenderPassID p_render_pass,
uint32_t p_render_subpass,
VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;
/*****************/
/**** COMPUTE ****/
/*****************/
// ----- COMMANDS -----
// Binding.
virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) override final;
virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) override final;
// Dispatching.
virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) override final;
virtual void command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) override final;
// ----- PIPELINE -----
virtual PipelineID compute_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) override final;
/*****************/
/**** QUERIES ****/
/*****************/
// ----- TIMESTAMP -----
// Basic.
virtual QueryPoolID timestamp_query_pool_create(uint32_t p_query_count) override final;
virtual void timestamp_query_pool_free(QueryPoolID p_pool_id) override final;
virtual void timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) override final;
virtual uint64_t timestamp_query_result_to_time(uint64_t p_result) override final;
// Commands.
virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) override final;
virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) override final;
/****************/
/**** SCREEN ****/
/****************/
virtual DataFormat screen_get_format() override final;
/********************/
/**** SUBMISSION ****/
/********************/
virtual void begin_segment(CommandBufferID p_cmd_buffer, uint32_t p_frame_index, uint32_t p_frames_drawn) override final;
virtual void end_segment() override final;
/**************/
/**** MISC ****/
/**************/
VkPhysicalDeviceLimits limits = {};
virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) override final;
virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) override final;
virtual uint64_t get_total_memory_used() override final;
virtual uint64_t limit_get(Limit p_limit) override final;
virtual uint64_t api_trait_get(ApiTrait p_trait) override final;
virtual bool has_feature(Features p_feature) override final;
virtual const MultiviewCapabilities &get_multiview_capabilities() override final;
private:
/*********************/
/**** BOOKKEEPING ****/
/*********************/
using VersatileResource = VersatileResourceTemplate<
BufferInfo,
TextureInfo,
VertexFormatInfo,
ShaderInfo,
UniformSetInfo>;
PagedAllocator<VersatileResource> resources_allocator;
/******************/
public:
RenderingDeviceDriverVulkan(VulkanContext *p_context, VkDevice p_vk_device);
virtual ~RenderingDeviceDriverVulkan();
};
#endif // RENDERING_DEVICE_DRIVER_VULKAN_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -412,7 +412,9 @@ Error VulkanContext::_initialize_instance_extensions() {
// Make sure our core extensions are here
register_requested_instance_extension(VK_KHR_SURFACE_EXTENSION_NAME, true);
register_requested_instance_extension(_get_platform_surface_extension(), true);
if (_get_platform_surface_extension()) {
register_requested_instance_extension(_get_platform_surface_extension(), true);
}
if (_use_validation_layers()) {
register_requested_instance_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, false);
@ -1232,21 +1234,24 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
bool present_supported = false;
uint32_t device_queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
for (uint32_t j = 0; j < device_queue_family_count; j++) {
if ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
VkBool32 supports;
err = vkGetPhysicalDeviceSurfaceSupportKHR(
physical_devices[i], j, p_surface, &supports);
if (err == VK_SUCCESS && supports) {
present_supported = true;
} else {
continue;
if (p_surface) {
uint32_t device_queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
for (uint32_t j = 0; j < device_queue_family_count; j++) {
if ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
VkBool32 supports;
err = vkGetPhysicalDeviceSurfaceSupportKHR(
physical_devices[i], j, p_surface, &supports);
if (err == VK_SUCCESS && supports) {
present_supported = true;
} else {
continue;
}
}
}
free(device_queue_props);
}
String name = String::utf8(props.deviceName);
String vendor = "Unknown";
@ -1276,10 +1281,9 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
}
vendor_idx++;
}
free(device_queue_props);
print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
if (present_supported || !p_surface) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
switch (props.deviceType) {
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
if (type_selected < 4) {
@ -1509,7 +1513,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
return OK;
}
Error VulkanContext::_create_device() {
Error VulkanContext::_create_device(VkDevice &r_vk_device) {
VkResult err;
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
@ -1624,11 +1628,11 @@ Error VulkanContext::_create_device() {
}
if (vulkan_hooks) {
if (!vulkan_hooks->create_vulkan_device(&sdevice, &device)) {
if (!vulkan_hooks->create_vulkan_device(&sdevice, &r_vk_device)) {
return ERR_CANT_CREATE;
}
} else {
err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
err = vkCreateDevice(gpu, &sdevice, nullptr, &r_vk_device);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
}
@ -1637,9 +1641,13 @@ Error VulkanContext::_create_device() {
Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
// Iterate over each queue to learn whether it supports presenting:
VkBool32 *supportsPresent = (VkBool32 *)malloc(queue_family_count * sizeof(VkBool32));
for (uint32_t i = 0; i < queue_family_count; i++) {
fpGetPhysicalDeviceSurfaceSupportKHR(gpu, i, p_surface, &supportsPresent[i]);
VkBool32 *supportsPresent = nullptr;
if (p_surface) {
supportsPresent = (VkBool32 *)malloc(queue_family_count * sizeof(VkBool32));
for (uint32_t i = 0; i < queue_family_count; i++) {
fpGetPhysicalDeviceSurfaceSupportKHR(gpu, i, p_surface, &supportsPresent[i]);
}
}
// Search for a graphics and a present queue in the array of queue
@ -1652,7 +1660,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
graphicsQueueFamilyIndex = i;
}
if (supportsPresent[i] == VK_TRUE) {
if (p_surface && supportsPresent[i] == VK_TRUE) {
graphicsQueueFamilyIndex = i;
presentQueueFamilyIndex = i;
break;
@ -1660,7 +1668,7 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
}
}
if (presentQueueFamilyIndex == UINT32_MAX) {
if (p_surface && presentQueueFamilyIndex == UINT32_MAX) {
// If didn't find a queue that supports both graphics and present, then
// find a separate present queue.
for (uint32_t i = 0; i < queue_family_count; ++i) {
@ -1671,17 +1679,22 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
}
}
free(supportsPresent);
if (p_surface) {
free(supportsPresent);
// Generate error if could not find both a graphics and a present queue.
ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE,
"Could not find both graphics and present queues\n");
// Generate error if could not find both a graphics and a present queue.
ERR_FAIL_COND_V_MSG(graphicsQueueFamilyIndex == UINT32_MAX || presentQueueFamilyIndex == UINT32_MAX, ERR_CANT_CREATE,
"Could not find both graphics and present queues\n");
graphics_queue_family_index = graphicsQueueFamilyIndex;
present_queue_family_index = presentQueueFamilyIndex;
separate_present_queue = (graphics_queue_family_index != present_queue_family_index);
graphics_queue_family_index = graphicsQueueFamilyIndex;
present_queue_family_index = presentQueueFamilyIndex;
separate_present_queue = (graphics_queue_family_index != present_queue_family_index);
} else {
graphics_queue_family_index = graphicsQueueFamilyIndex;
}
_create_device();
_create_device(device);
driver = memnew(RenderingDeviceDriverVulkan(this, device));
static PFN_vkGetDeviceProcAddr g_gdpa = nullptr;
#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
@ -1705,61 +1718,63 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR p_surface) {
vkGetDeviceQueue(device, graphics_queue_family_index, 0, &graphics_queue);
if (!separate_present_queue) {
present_queue = graphics_queue;
} else {
vkGetDeviceQueue(device, present_queue_family_index, 0, &present_queue);
}
// Get the list of VkFormat's that are supported:
uint32_t formatCount;
VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, p_surface, &formatCount, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, p_surface, &formatCount, surfFormats);
if (err) {
free(surfFormats);
ERR_FAIL_V(ERR_CANT_CREATE);
}
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format. Otherwise, at least one
// supported format will be returned.
if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
format = VK_FORMAT_B8G8R8A8_UNORM;
color_space = surfFormats[0].colorSpace;
} else {
// These should be ordered with the ones we want to use on top and fallback modes further down
// we want a 32bit RGBA unsigned normalized buffer or similar.
const VkFormat allowed_formats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM
};
uint32_t allowed_formats_count = sizeof(allowed_formats) / sizeof(VkFormat);
if (formatCount < 1) {
free(surfFormats);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
if (p_surface) {
if (!separate_present_queue) {
present_queue = graphics_queue;
} else {
vkGetDeviceQueue(device, present_queue_family_index, 0, &present_queue);
}
// Find the first format that we support.
format = VK_FORMAT_UNDEFINED;
for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
if (surfFormats[sf].format == allowed_formats[af]) {
format = surfFormats[sf].format;
color_space = surfFormats[sf].colorSpace;
// Get the list of VkFormat's that are supported:
uint32_t formatCount;
VkResult err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, p_surface, &formatCount, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
err = fpGetPhysicalDeviceSurfaceFormatsKHR(gpu, p_surface, &formatCount, surfFormats);
if (err) {
free(surfFormats);
ERR_FAIL_V(ERR_CANT_CREATE);
}
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format. Otherwise, at least one
// supported format will be returned.
if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
format = VK_FORMAT_B8G8R8A8_UNORM;
color_space = surfFormats[0].colorSpace;
} else {
// These should be ordered with the ones we want to use on top and fallback modes further down
// we want a 32bit RGBA unsigned normalized buffer or similar.
const VkFormat allowed_formats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM
};
uint32_t allowed_formats_count = sizeof(allowed_formats) / sizeof(VkFormat);
if (formatCount < 1) {
free(surfFormats);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
}
// Find the first format that we support.
format = VK_FORMAT_UNDEFINED;
for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
if (surfFormats[sf].format == allowed_formats[af]) {
format = surfFormats[sf].format;
color_space = surfFormats[sf].colorSpace;
}
}
}
if (format == VK_FORMAT_UNDEFINED) {
free(surfFormats);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "No usable surface format found.");
}
}
if (format == VK_FORMAT_UNDEFINED) {
free(surfFormats);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "No usable surface format found.");
}
free(surfFormats);
}
free(surfFormats);
Error serr = _create_semaphores();
if (serr) {
return serr;
@ -1830,6 +1845,8 @@ VkExtent2D VulkanContext::_compute_swapchain_extent(const VkSurfaceCapabilitiesK
}
Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height) {
ERR_FAIL_NULL_V_MSG(_get_platform_surface_extension(), ERR_UNAVAILABLE, "This Vulkan context is headless.");
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
if (!device_initialized) {
@ -1880,22 +1897,20 @@ bool VulkanContext::window_is_valid_swapchain(DisplayServer::WindowID p_window)
return w->swapchain_image_resources != VK_NULL_HANDLE;
}
VkRenderPass VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
RDD::RenderPassID VulkanContext::window_get_render_pass(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), RDD::RenderPassID());
Window *w = &windows[p_window];
// Vulkan use of currentbuffer.
return w->render_pass;
return (RDD::RenderPassID)w->render_pass;
}
VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), VK_NULL_HANDLE);
ERR_FAIL_COND_V(!buffers_prepared, VK_NULL_HANDLE);
RDD::FramebufferID VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_window) {
ERR_FAIL_COND_V(!windows.has(p_window), RDD::FramebufferID());
ERR_FAIL_COND_V(!buffers_prepared, RDD::FramebufferID());
Window *w = &windows[p_window];
// Vulkan use of currentbuffer.
if (w->swapchain_image_resources != VK_NULL_HANDLE) {
return w->swapchain_image_resources[w->current_buffer].framebuffer;
return (RDD::FramebufferID)w->swapchain_image_resources[w->current_buffer].framebuffer;
} else {
return VK_NULL_HANDLE;
return RDD::FramebufferID();
}
}
@ -2235,7 +2250,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pPreserveAttachments*/ nullptr,
};
const VkRenderPassCreateInfo2KHR rp_info = {
const VkRenderPassCreateInfo2KHR pass_info = {
/*sType*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR,
/*pNext*/ nullptr,
/*flags*/ 0,
@ -2249,7 +2264,7 @@ Error VulkanContext::_update_swap_chain(Window *window) {
/*pCorrelatedViewMasks*/ nullptr,
};
err = vkCreateRenderPass2KHR(device, &rp_info, nullptr, &window->render_pass);
err = vkCreateRenderPass2KHR(device, &pass_info, nullptr, &window->render_pass);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
for (uint32_t i = 0; i < swapchainImageCount; i++) {
@ -2351,19 +2366,32 @@ Error VulkanContext::initialize() {
return err;
}
// Headless? Complete setup now.
if (!_get_platform_surface_extension()) {
err = _create_physical_device(VK_NULL_HANDLE);
if (err != OK) {
return err;
}
err = _initialize_queues(VK_NULL_HANDLE);
if (err != OK) {
return err;
}
}
return OK;
}
void VulkanContext::set_setup_buffer(VkCommandBuffer p_command_buffer) {
command_buffer_queue.write[0] = p_command_buffer;
void VulkanContext::set_setup_buffer(RDD::CommandBufferID p_command_buffer) {
command_buffer_queue[0] = (VkCommandBuffer)p_command_buffer.id;
}
void VulkanContext::append_command_buffer(VkCommandBuffer p_command_buffer) {
void VulkanContext::append_command_buffer(RDD::CommandBufferID p_command_buffer) {
if (command_buffer_queue.size() <= command_buffer_count) {
command_buffer_queue.resize(command_buffer_count + 1);
}
command_buffer_queue.write[command_buffer_count] = p_command_buffer;
command_buffer_queue[command_buffer_count] = (VkCommandBuffer)p_command_buffer.id;
command_buffer_count++;
}
@ -2389,7 +2417,7 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
submit_info.signalSemaphoreCount = pending_flushable ? 1 : 0;
submit_info.pSignalSemaphores = pending_flushable ? &draw_complete_semaphores[frame_index] : nullptr;
VkResult err = vkQueueSubmit(graphics_queue, 1, &submit_info, VK_NULL_HANDLE);
command_buffer_queue.write[0] = nullptr;
command_buffer_queue[0] = nullptr;
ERR_FAIL_COND(err);
}
@ -2415,7 +2443,7 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
vkDeviceWaitIdle(device);
}
Error VulkanContext::prepare_buffers() {
Error VulkanContext::prepare_buffers(RDD::CommandBufferID p_command_buffer) {
if (!queues_initialized) {
return OK;
}
@ -2468,6 +2496,9 @@ Error VulkanContext::prepare_buffers() {
return OK;
}
void VulkanContext::postpare_buffers(RDD::CommandBufferID p_command_buffer) {
}
Error VulkanContext::swap_buffers() {
if (!queues_initialized) {
return OK;
@ -2535,7 +2566,7 @@ Error VulkanContext::swap_buffers() {
err = vkQueueSubmit(graphics_queue, 1, &submit_info, fences[frame_index]);
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Vulkan: Cannot submit graphics queue. Error code: " + String(string_VkResult(err)));
command_buffer_queue.write[0] = nullptr;
command_buffer_queue[0] = nullptr;
command_buffer_count = 1;
if (separate_present_queue) {
@ -2690,6 +2721,14 @@ Error VulkanContext::swap_buffers() {
void VulkanContext::resize_notify() {
}
RenderingDevice::Capabilities VulkanContext::get_device_capabilities() const {
RenderingDevice::Capabilities c;
c.device_family = RenderingDevice::DEVICE_VULKAN;
c.version_major = VK_API_VERSION_MAJOR(device_api_version);
c.version_minor = VK_API_VERSION_MINOR(device_api_version);
return c;
}
VkDevice VulkanContext::get_device() {
return device;
}
@ -2714,61 +2753,27 @@ VkFormat VulkanContext::get_screen_format() const {
return format;
}
VkPhysicalDeviceLimits VulkanContext::get_device_limits() const {
const VkPhysicalDeviceLimits &VulkanContext::get_device_limits() const {
return gpu_props.limits;
}
RID VulkanContext::local_device_create() {
LocalDevice ld;
{ // Create device.
VkResult err;
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queues[0].pNext = nullptr;
queues[0].queueFamilyIndex = graphics_queue_family_index;
queues[0].queueCount = 1;
queues[0].pQueuePriorities = queue_priorities;
queues[0].flags = 0;
uint32_t enabled_extension_count = 0;
const char *enabled_extension_names[MAX_EXTENSIONS];
ERR_FAIL_COND_V(enabled_device_extension_names.size() > MAX_EXTENSIONS, RID());
for (const CharString &extension_name : enabled_device_extension_names) {
enabled_extension_names[enabled_extension_count++] = extension_name.ptr();
}
VkDeviceCreateInfo sdevice = {
/*sType =*/VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
/*pNext */ nullptr,
/*flags */ 0,
/*queueCreateInfoCount */ 1,
/*pQueueCreateInfos */ queues,
/*enabledLayerCount */ 0,
/*ppEnabledLayerNames */ nullptr,
/*enabledExtensionCount */ enabled_extension_count,
/*ppEnabledExtensionNames */ (const char *const *)enabled_extension_names,
/*pEnabledFeatures */ &physical_device_features, // If specific features are required, pass them in here.
};
err = vkCreateDevice(gpu, &sdevice, nullptr, &ld.device);
ERR_FAIL_COND_V(err, RID());
}
Error err = _create_device(ld.device);
ERR_FAIL_COND_V(err, RID());
{ // Create graphics queue.
vkGetDeviceQueue(ld.device, graphics_queue_family_index, 0, &ld.queue);
}
ld.driver = memnew(RenderingDeviceDriverVulkan(this, ld.device));
return local_device_owner.make_rid(ld);
}
VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
return ld->device;
}
void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) {
void VulkanContext::local_device_push_command_buffers(RID p_local_device, const RDD::CommandBufferID *p_buffers, int p_count) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
ERR_FAIL_COND(ld->waiting);
@ -2779,7 +2784,7 @@ void VulkanContext::local_device_push_command_buffers(RID p_local_device, const
submit_info.waitSemaphoreCount = 0;
submit_info.pWaitSemaphores = nullptr;
submit_info.commandBufferCount = p_count;
submit_info.pCommandBuffers = p_buffers;
submit_info.pCommandBuffers = (const VkCommandBuffer *)p_buffers;
submit_info.signalSemaphoreCount = 0;
submit_info.pSignalSemaphores = nullptr;
@ -2808,11 +2813,12 @@ void VulkanContext::local_device_sync(RID p_local_device) {
void VulkanContext::local_device_free(RID p_local_device) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
memdelete(ld->driver);
vkDestroyDevice(ld->device, nullptr);
local_device_owner.free(p_local_device);
}
void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) {
void VulkanContext::command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
return;
}
@ -2826,10 +2832,10 @@ void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String
label.color[1] = p_color[1];
label.color[2] = p_color[2];
label.color[3] = p_color[3];
CmdBeginDebugUtilsLabelEXT(p_command_buffer, &label);
CmdBeginDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id, &label);
}
void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color) {
void VulkanContext::command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) {
if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
return;
}
@ -2842,14 +2848,14 @@ void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, Strin
label.color[1] = p_color[1];
label.color[2] = p_color[2];
label.color[3] = p_color[3];
CmdInsertDebugUtilsLabelEXT(p_command_buffer, &label);
CmdInsertDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id, &label);
}
void VulkanContext::command_end_label(VkCommandBuffer p_command_buffer) {
void VulkanContext::command_end_label(RDD::CommandBufferID p_command_buffer) {
if (!is_instance_extension_enabled(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
return;
}
CmdEndDebugUtilsLabelEXT(p_command_buffer);
CmdEndDebugUtilsLabelEXT((VkCommandBuffer)p_command_buffer.id);
}
void VulkanContext::set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) {
@ -2897,12 +2903,25 @@ void VulkanContext::set_vsync_mode(DisplayServer::WindowID p_window, DisplayServ
_update_swap_chain(&windows[p_window]);
}
RenderingDeviceDriver *VulkanContext::get_driver(RID p_local_device) {
if (p_local_device.is_valid()) {
LocalDevice *ld = local_device_owner.get_or_null(p_local_device);
ERR_FAIL_NULL_V(ld, nullptr);
return ld->driver;
} else {
return driver;
}
}
VulkanContext::VulkanContext() {
command_buffer_queue.resize(1); // First one is always the setup command.
command_buffer_queue.write[0] = nullptr;
command_buffer_queue[0] = nullptr;
}
VulkanContext::~VulkanContext() {
if (driver) {
memdelete(driver);
}
if (queue_props) {
free(queue_props);
}

View File

@ -37,8 +37,9 @@
#include "core/templates/hash_map.h"
#include "core/templates/rb_map.h"
#include "core/templates/rid_owner.h"
#include "rendering_device_driver_vulkan.h"
#include "servers/display_server.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/renderer_rd/api_context_rd.h"
#ifdef USE_VOLK
#include <volk.h>
@ -48,7 +49,7 @@
#include "vulkan_hooks.h"
class VulkanContext {
class VulkanContext : public ApiContextRD {
public:
struct SubgroupCapabilities {
uint32_t size;
@ -65,14 +66,6 @@ public:
String supported_operations_desc() const;
};
struct MultiviewCapabilities {
bool is_supported;
bool geometry_shader_is_supported;
bool tessellation_shader_is_supported;
uint32_t max_view_count;
uint32_t max_instance_count;
};
struct VRSCapabilities {
bool pipeline_vrs_supported; // We can specify our fragment rate on a pipeline level.
bool primitive_vrs_supported; // We can specify our fragment rate on each drawcall.
@ -115,7 +108,7 @@ private:
uint32_t instance_api_version = VK_API_VERSION_1_0;
SubgroupCapabilities subgroup_capabilities;
MultiviewCapabilities multiview_capabilities;
RDD::MultiviewCapabilities multiview_capabilities;
VRSCapabilities vrs_capabilities;
ShaderCapabilities shader_capabilities;
StorageBufferCapabilities storage_buffer_capabilities;
@ -171,10 +164,13 @@ private:
bool waiting = false;
VkDevice device = VK_NULL_HANDLE;
VkQueue queue = VK_NULL_HANDLE;
RenderingDeviceDriverVulkan *driver = nullptr;
};
RID_Owner<LocalDevice, true> local_device_owner;
RenderingDeviceDriverVulkan *driver = nullptr;
HashMap<DisplayServer::WindowID, Window> windows;
uint32_t swapchainImageCount = 0;
@ -182,8 +178,8 @@ private:
bool prepared = false;
Vector<VkCommandBuffer> command_buffer_queue;
int command_buffer_count = 1;
LocalVector<VkCommandBuffer> command_buffer_queue;
uint32_t command_buffer_count = 1;
// Extensions.
static bool instance_extensions_initialized;
@ -250,7 +246,7 @@ private:
Error _initialize_queues(VkSurfaceKHR p_surface);
Error _create_device();
Error _create_device(VkDevice &r_vk_device);
Error _clean_up_swap_chain(Window *window);
@ -262,7 +258,7 @@ private:
Vector<VkAttachmentReference> _convert_VkAttachmentReference2(uint32_t p_count, const VkAttachmentReference2 *p_refs);
protected:
virtual const char *_get_platform_surface_extension() const = 0;
virtual const char *_get_platform_surface_extension() const { return nullptr; }
virtual Error _window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, VkSurfaceKHR p_surface, int p_width, int p_height);
@ -277,10 +273,10 @@ public:
bool supports_renderpass2() const { return is_device_extension_enabled(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME); }
VkResult vkCreateRenderPass2KHR(VkDevice p_device, const VkRenderPassCreateInfo2 *p_create_info, const VkAllocationCallbacks *p_allocator, VkRenderPass *p_render_pass);
uint32_t get_vulkan_major() const { return VK_API_VERSION_MAJOR(device_api_version); };
uint32_t get_vulkan_minor() const { return VK_API_VERSION_MINOR(device_api_version); };
virtual const char *get_api_name() const override final { return "Vulkan"; };
virtual RenderingDevice::Capabilities get_device_capabilities() const override final;
const SubgroupCapabilities &get_subgroup_capabilities() const { return subgroup_capabilities; };
const MultiviewCapabilities &get_multiview_capabilities() const { return multiview_capabilities; };
virtual const RDD::MultiviewCapabilities &get_multiview_capabilities() const override final { return multiview_capabilities; };
const VRSCapabilities &get_vrs_capabilities() const { return vrs_capabilities; };
const ShaderCapabilities &get_shader_capabilities() const { return shader_capabilities; };
const StorageBufferCapabilities &get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
@ -290,7 +286,7 @@ public:
VkDevice get_device();
VkPhysicalDevice get_physical_device();
VkInstance get_instance() { return inst; }
int get_swapchain_image_count() const;
virtual int get_swapchain_image_count() const override final;
VkQueue get_graphics_queue() const;
uint32_t get_graphics_queue_family_index() const;
@ -306,44 +302,46 @@ public:
return enabled_device_extension_names.has(extension_name);
}
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);
int window_get_height(DisplayServer::WindowID p_window = 0);
bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0);
void window_destroy(DisplayServer::WindowID p_window_id);
VkFramebuffer window_get_framebuffer(DisplayServer::WindowID p_window = 0);
VkRenderPass window_get_render_pass(DisplayServer::WindowID p_window = 0);
virtual void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) override final;
virtual int window_get_width(DisplayServer::WindowID p_window = 0) override final;
virtual int window_get_height(DisplayServer::WindowID p_window = 0) override final;
virtual bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0) override final;
virtual void window_destroy(DisplayServer::WindowID p_window_id) override final;
virtual RDD::RenderPassID window_get_render_pass(DisplayServer::WindowID p_window = 0) override final;
virtual RDD::FramebufferID window_get_framebuffer(DisplayServer::WindowID p_window = 0) override final;
RID local_device_create();
VkDevice local_device_get_vk_device(RID p_local_device);
void local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count);
void local_device_sync(RID p_local_device);
void local_device_free(RID p_local_device);
virtual RID local_device_create() override final;
virtual void local_device_push_command_buffers(RID p_local_device, const RDD::CommandBufferID *p_buffers, int p_count) override final;
virtual void local_device_sync(RID p_local_device) override final;
virtual void local_device_free(RID p_local_device) override final;
VkFormat get_screen_format() const;
VkPhysicalDeviceLimits get_device_limits() const;
const VkPhysicalDeviceLimits &get_device_limits() const;
void set_setup_buffer(VkCommandBuffer p_command_buffer);
void append_command_buffer(VkCommandBuffer p_command_buffer);
virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) override final;
virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) override final;
void resize_notify();
void flush(bool p_flush_setup = false, bool p_flush_pending = false);
Error prepare_buffers();
Error swap_buffers();
Error initialize();
virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) override final;
virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) override final;
virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) override final;
virtual Error swap_buffers() override final;
virtual Error initialize() override final;
void command_begin_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color);
void command_insert_label(VkCommandBuffer p_command_buffer, String p_label_name, const Color p_color);
void command_end_label(VkCommandBuffer p_command_buffer);
virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) override final;
virtual void command_end_label(RDD::CommandBufferID p_command_buffer) override final;
void set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name);
String get_device_vendor_name() const;
String get_device_name() const;
RenderingDevice::DeviceType get_device_type() const;
String get_device_api_version() const;
String get_device_pipeline_cache_uuid() const;
virtual String get_device_vendor_name() const override final;
virtual String get_device_name() const override final;
virtual RDD::DeviceType get_device_type() const override final;
virtual String get_device_api_version() const override final;
virtual String get_device_pipeline_cache_uuid() const override final;
void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode);
DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const;
virtual void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) override final;
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const override final;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) override final;
VulkanContext();
virtual ~VulkanContext();

View File

@ -1844,8 +1844,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::ARRAY, "rendering/gl_compatibility/force_angle_on_devices", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::DICTIONARY, PROPERTY_HINT_NONE, String())), device_blocklist);
}
// Start with RenderingDevice-based backends. Should be included if any RD driver present.
#if defined(VULKAN_ENABLED) || defined(D3D12_ENABLED)
// Start with RenderingDevice-based backends.
#ifdef RD_ENABLED
renderer_hints = "forward_plus,mobile";
default_renderer_mobile = "mobile";
#endif

View File

@ -37,11 +37,13 @@
#include "core/config/project_settings.h"
#if defined(RD_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#include "vulkan_context_android.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
#endif
#ifdef GLES3_ENABLED
@ -486,9 +488,6 @@ Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
#ifdef GLES3_ENABLED
drivers.push_back("opengl3");
#endif
#ifdef D3D12_ENABLED
drivers.push_back("d3d12");
#endif
#ifdef VULKAN_ENABLED
drivers.push_back("vulkan");
#endif
@ -518,20 +517,30 @@ void DisplayServerAndroid::register_android_driver() {
}
void DisplayServerAndroid::reset_window() {
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
ERR_FAIL_NULL(native_window);
ERR_FAIL_NULL(context_vulkan);
VSyncMode last_vsync_mode = context_vulkan->get_vsync_mode(MAIN_WINDOW_ID);
context_vulkan->window_destroy(MAIN_WINDOW_ID);
#if defined(RD_ENABLED)
if (context_rd) {
VSyncMode last_vsync_mode = context_rd->get_vsync_mode(MAIN_WINDOW_ID);
context_rd->window_destroy(MAIN_WINDOW_ID);
Size2i display_size = OS_Android::get_singleton()->get_display_size();
if (context_vulkan->window_create(native_window, last_vsync_mode, display_size.width, display_size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to reset Vulkan window.");
union {
#ifdef VULKAN_ENABLED
VulkanContextAndroid::WindowPlatformData vulkan;
#endif
} wpd;
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
ERR_FAIL_NULL(native_window);
wpd.vulkan.window = native_window;
}
#endif
if (context_rd->window_create(MAIN_WINDOW_ID, last_vsync_mode, display_size.width, display_size.height, &wpd) != OK) {
memdelete(context_rd);
context_rd = nullptr;
ERR_FAIL_MSG(vformat("Failed to reset %s window.", context_rd->get_api_name()));
}
}
#endif
@ -554,30 +563,46 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
#endif
#if defined(RD_ENABLED)
context_rd = nullptr;
rendering_device = nullptr;
#if defined(VULKAN_ENABLED)
context_vulkan = nullptr;
rendering_device_vulkan = nullptr;
if (rendering_driver == "vulkan") {
ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
ERR_FAIL_NULL(native_window);
context_rd = memnew(VulkanContextAndroid);
}
#endif
context_vulkan = memnew(VulkanContextAndroid);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to initialize Vulkan context");
if (context_rd) {
if (context_rd->initialize() != OK) {
memdelete(context_rd);
context_rd = nullptr;
ERR_FAIL_MSG(vformat("Failed to initialize %s context", context_rd->get_api_name()));
}
Size2i display_size = OS_Android::get_singleton()->get_display_size();
if (context_vulkan->window_create(native_window, p_vsync_mode, display_size.width, display_size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to create Vulkan window.");
union {
#ifdef VULKAN_ENABLED
VulkanContextAndroid::WindowPlatformData vulkan;
#endif
} wpd;
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
ERR_FAIL_NULL(native_window);
wpd.vulkan.window = native_window;
}
#endif
if (context_rd->window_create(MAIN_WINDOW_ID, p_vsync_mode, display_size.width, display_size.height, &wpd) != OK) {
memdelete(context_rd);
context_rd = nullptr;
ERR_FAIL_MSG(vformat("Failed to create %s window.", context_rd->get_api_name()));
}
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
rendering_device = memnew(RenderingDevice);
rendering_device->initialize(context_rd);
RendererCompositorRD::make_current();
}
@ -590,16 +615,13 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
DisplayServerAndroid::~DisplayServerAndroid() {
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
}
if (context_vulkan) {
memdelete(context_vulkan);
}
#if defined(RD_ENABLED)
if (rendering_device) {
rendering_device->finalize();
memdelete(rendering_device);
}
if (context_rd) {
memdelete(context_rd);
}
#endif
}
@ -690,17 +712,17 @@ void DisplayServerAndroid::cursor_set_custom_image(const Ref<Resource> &p_cursor
}
void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
}
DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_window) const {
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
return context_vulkan->get_vsync_mode(p_window);
#if defined(RD_ENABLED)
if (context_rd) {
return context_rd->get_vsync_mode(p_window);
}
#endif
return DisplayServer::VSYNC_ENABLED;

View File

@ -33,9 +33,9 @@
#include "servers/display_server.h"
#if defined(VULKAN_ENABLED)
class VulkanContextAndroid;
class RenderingDeviceVulkan;
#if defined(RD_ENABLED)
class ApiContextRD;
class RenderingDevice;
#endif
class DisplayServerAndroid : public DisplayServer {
@ -72,9 +72,9 @@ class DisplayServerAndroid : public DisplayServer {
CursorShape cursor_shape = CursorShape::CURSOR_ARROW;
#if defined(VULKAN_ENABLED)
VulkanContextAndroid *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
ApiContextRD *context_rd = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
ObjectID window_attached_instance_id;

View File

@ -42,14 +42,14 @@ const char *VulkanContextAndroid::_get_platform_surface_extension() const {
return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
}
Error VulkanContextAndroid::window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height) {
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.window = p_window;
Error VulkanContextAndroid::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data;
VkSurfaceKHR surface;
VkAndroidSurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.window = wpd->window;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult err = vkCreateAndroidSurfaceKHR(get_instance(), &createInfo, nullptr, &surface);
if (err != VK_SUCCESS) {
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "vkCreateAndroidSurfaceKHR failed with error " + itos(err));

View File

@ -38,10 +38,13 @@
struct ANativeWindow;
class VulkanContextAndroid : public VulkanContext {
virtual const char *_get_platform_surface_extension() const override;
virtual const char *_get_platform_surface_extension() const override final;
public:
Error window_create(ANativeWindow *p_window, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height);
struct WindowPlatformData {
ANativeWindow *window;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
VulkanContextAndroid() = default;
~VulkanContextAndroid() override = default;

View File

@ -34,18 +34,20 @@
#include "core/input/input.h"
#include "servers/display_server.h"
#if defined(RD_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#import "vulkan_context_ios.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
#include "drivers/gles3/rasterizer_gles3.h"
@ -59,9 +61,9 @@ class DisplayServerIOS : public DisplayServer {
_THREAD_SAFE_CLASS_
#if defined(VULKAN_ENABLED)
VulkanContextIOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
ApiContextRD *context_rd = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
id tts = nullptr;

View File

@ -62,34 +62,46 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
tts = [[TTS_IOS alloc] init];
}
#if defined(RD_ENABLED)
context_rd = nullptr;
rendering_device = nullptr;
CALayer *layer = nullptr;
union {
#ifdef VULKAN_ENABLED
VulkanContextIOS::WindowPlatformData vulkan;
#endif
} wpd;
#if defined(VULKAN_ENABLED)
context_vulkan = nullptr;
rendering_device_vulkan = nullptr;
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextIOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
ERR_FAIL_MSG("Failed to initialize Vulkan context");
}
CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
if (!layer) {
ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer.");
}
wpd.vulkan.layer_ptr = &layer;
context_rd = memnew(VulkanContextIOS);
}
#endif
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Failed to create Vulkan window.");
if (context_rd) {
if (context_rd->initialize() != OK) {
memdelete(context_rd);
context_rd = nullptr;
ERR_FAIL_MSG(vformat("Failed to initialize %s context", context_rd->get_api_name()));
}
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
if (context_rd->window_create(MAIN_WINDOW_ID, p_vsync_mode, size.width, size.height, &wpd) != OK) {
memdelete(context_rd);
context_rd = nullptr;
r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG(vformat("Failed to create %s window.", context_rd->get_api_name()));
}
rendering_device = memnew(RenderingDevice);
rendering_device->initialize(context_rd);
RendererCompositorRD::make_current();
}
@ -116,17 +128,17 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
}
DisplayServerIOS::~DisplayServerIOS() {
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
if (rendering_device) {
rendering_device->finalize();
memdelete(rendering_device);
rendering_device = nullptr;
}
if (context_vulkan) {
context_vulkan->window_destroy(MAIN_WINDOW_ID);
memdelete(context_vulkan);
context_vulkan = nullptr;
if (context_rd) {
context_rd->window_destroy(MAIN_WINDOW_ID);
memdelete(context_rd);
context_rd = nullptr;
}
#endif
}
@ -697,9 +709,9 @@ bool DisplayServerIOS::screen_is_kept_on() const {
void DisplayServerIOS::resize_window(CGSize viewSize) {
Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale();
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(MAIN_WINDOW_ID, size.x, size.y);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_resize(MAIN_WINDOW_ID, size.x, size.y);
}
#endif
@ -709,18 +721,18 @@ void DisplayServerIOS::resize_window(CGSize viewSize) {
void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
}
DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
return context_vulkan->get_vsync_mode(p_window);
#if defined(RD_ENABLED)
if (context_rd) {
return context_rd->get_vsync_mode(p_window);
}
#endif
return DisplayServer::VSYNC_ENABLED;

View File

@ -41,10 +41,12 @@
#include "servers/audio_server.h"
#include "servers/rendering/renderer_compositor.h"
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#import "vulkan_context_ios.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#endif
#endif
class OS_IOS : public OS_Unix {

View File

@ -50,15 +50,17 @@
#import <dlfcn.h>
#include <sys/sysctl.h>
#if defined(VULKAN_ENABLED)
#if defined(RD_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#import <QuartzCore/CAMetalLayer.h>
#if defined(VULKAN_ENABLED)
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
#endif // VULKAN_ENABLED
#endif
// Initialization order between compilation units is not guaranteed,

View File

@ -38,10 +38,13 @@
#import <UIKit/UIKit.h>
class VulkanContextIOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
virtual const char *_get_platform_surface_extension() const override final;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height);
struct WindowPlatformData {
CALayer *const *layer_ptr;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
VulkanContextIOS();
~VulkanContextIOS();

View File

@ -42,16 +42,15 @@ const char *VulkanContextIOS::_get_platform_surface_extension() const {
return VK_MVK_IOS_SURFACE_EXTENSION_NAME;
}
Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) {
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.pView = (__bridge const void *)p_metal_layer;
Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data;
VkSurfaceKHR surface;
VkResult err =
vkCreateIOSSurfaceMVK(get_instance(), &createInfo, nullptr, &surface);
VkIOSSurfaceCreateInfoMVK createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pView = (__bridge const void *)(*wpd->layer_ptr);
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult err = vkCreateIOSSurfaceMVK(get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);

View File

@ -1707,9 +1707,9 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
window_set_transient(p_id, INVALID_WINDOW_ID);
}
#ifdef VULKAN_ENABLED
if (context_vulkan) {
context_vulkan->window_destroy(p_id);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_destroy(p_id);
}
#endif
#ifdef GLES3_ENABLED
@ -2233,9 +2233,9 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
}
// Keep rendering context window size in sync
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(p_window, xwa.width, xwa.height);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_resize(p_window, xwa.width, xwa.height);
}
#endif
#if defined(GLES3_ENABLED)
@ -3945,9 +3945,9 @@ void DisplayServerX11::_window_changed(XEvent *event) {
wd.position = new_rect.position;
wd.size = new_rect.size;
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(window_id, wd.size.width, wd.size.height);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_resize(window_id, wd.size.width, wd.size.height);
}
#endif
#if defined(GLES3_ENABLED)
@ -5244,9 +5244,9 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
@ -5262,9 +5262,9 @@ void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo
DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
return context_vulkan->get_vsync_mode(p_window);
#if defined(RD_ENABLED)
if (context_rd) {
return context_rd->get_vsync_mode(p_window);
}
#endif
#if defined(GLES3_ENABLED)
@ -5606,10 +5606,21 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
_update_size_hints(id);
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, win_rect.size.width, win_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window");
#if defined(RD_ENABLED)
if (context_rd) {
union {
#ifdef VULKAN_ENABLED
VulkanContextX11::WindowPlatformData vulkan;
#endif
} wpd;
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
wpd.vulkan.window = wd.x11_window;
wpd.vulkan.display = x11_display;
}
#endif
Error err = context_rd->window_create(id, p_vsync_mode, win_rect.size.width, win_rect.size.height, &wpd);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, vformat("Can't create a %s window", context_rd->get_api_name()));
}
#endif
#ifdef GLES3_ENABLED
@ -6008,14 +6019,19 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
rendering_driver = p_rendering_driver;
bool driver_found = false;
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextX11);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
context_rd = memnew(VulkanContextX11);
}
#endif
if (context_rd) {
if (context_rd->initialize() != OK) {
memdelete(context_rd);
context_rd = nullptr;
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize Vulkan");
ERR_FAIL_MSG(vformat("Could not initialize %s", context_rd->get_api_name()));
}
driver_found = true;
}
@ -6123,11 +6139,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
show_window(main_window);
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
//temporary
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
#if defined(RD_ENABLED)
if (context_rd) {
rendering_device = memnew(RenderingDevice);
rendering_device->initialize(context_rd);
RendererCompositorRD::make_current();
}
@ -6301,9 +6316,9 @@ DisplayServerX11::~DisplayServerX11() {
//destroy all windows
for (KeyValue<WindowID, WindowData> &E : windows) {
#ifdef VULKAN_ENABLED
if (context_vulkan) {
context_vulkan->window_destroy(E.key);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_destroy(E.key);
}
#endif
#ifdef GLES3_ENABLED
@ -6345,16 +6360,16 @@ DisplayServerX11::~DisplayServerX11() {
#endif
//destroy drivers
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
if (rendering_device) {
rendering_device->finalize();
memdelete(rendering_device);
rendering_device = nullptr;
}
if (context_vulkan) {
memdelete(context_vulkan);
context_vulkan = nullptr;
if (context_rd) {
memdelete(context_rd);
context_rd = nullptr;
}
#endif

View File

@ -57,10 +57,12 @@
#include "x11/gl_manager_x11_egl.h"
#endif
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#include "x11/vulkan_context_x11.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#endif
#endif
#if defined(DBUS_ENABLED)
@ -141,9 +143,9 @@ class DisplayServerX11 : public DisplayServer {
GLManager_X11 *gl_manager = nullptr;
GLManagerEGL_X11 *gl_manager_egl = nullptr;
#endif
#if defined(VULKAN_ENABLED)
VulkanContextX11 *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
ApiContextRD *context_rd = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
#if defined(DBUS_ENABLED)

View File

@ -42,15 +42,15 @@ const char *VulkanContextX11::_get_platform_surface_extension() const {
return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
}
Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height) {
VkXlibSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.dpy = p_display;
createInfo.window = p_window;
Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data;
VkSurfaceKHR surface;
VkXlibSurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.dpy = wpd->display;
createInfo.window = wpd->window;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult err = vkCreateXlibSurfaceKHR(get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);

View File

@ -38,10 +38,14 @@
#include <X11/Xlib.h>
class VulkanContextX11 : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
virtual const char *_get_platform_surface_extension() const override final;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height);
struct WindowPlatformData {
::Window window;
Display *display;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
VulkanContextX11();
~VulkanContextX11();

View File

@ -39,11 +39,13 @@
#include "gl_manager_macos_legacy.h"
#endif // GLES3_ENABLED
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#include "vulkan_context_macos.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#endif // VULKAN_ENABLED
#endif // RD_ENABLED
#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
@ -133,9 +135,9 @@ private:
GLManagerLegacy_MacOS *gl_manager_legacy = nullptr;
GLManagerANGLE_MacOS *gl_manager_angle = nullptr;
#endif
#if defined(VULKAN_ENABLED)
VulkanContextMacOS *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
ApiContextRD *context_rd = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
String rendering_driver;

View File

@ -53,7 +53,7 @@
#include "drivers/gles3/rasterizer_gles3.h"
#endif
#if defined(VULKAN_ENABLED)
#if defined(RD_ENABLED)
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#endif
@ -179,10 +179,20 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
[layer setBackgroundColor:bg_color.CGColor];
}
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context");
#if defined(RD_ENABLED)
if (context_rd) {
union {
#ifdef VULKAN_ENABLED
VulkanContextMacOS::WindowPlatformData vulkan;
#endif
} wpd;
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
wpd.vulkan.view_ptr = &wd.window_view;
}
#endif
Error err = context_rd->window_create(window_id_counter, p_vsync_mode, p_rect.size.width, p_rect.size.height, &wpd);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, vformat("Can't create a %s context", context_rd->get_api_name()));
}
#endif
#if defined(GLES3_ENABLED)
@ -232,9 +242,9 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
gl_manager_angle->window_resize(id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(id, wd.size.width, wd.size.height);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_resize(id, wd.size.width, wd.size.height);
}
#endif
@ -763,9 +773,9 @@ void DisplayServerMacOS::window_destroy(WindowID p_window) {
gl_manager_legacy->window_destroy(p_window);
}
#endif
#ifdef VULKAN_ENABLED
if (context_vulkan) {
context_vulkan->window_destroy(p_window);
#ifdef RD_ENABLED
if (context_rd) {
context_rd->window_destroy(p_window);
}
#endif
windows.erase(p_window);
@ -782,8 +792,8 @@ void DisplayServerMacOS::window_resize(WindowID p_window, int p_width, int p_hei
}
#endif
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(p_window, p_width, p_height);
if (context_rd) {
context_rd->window_resize(p_window, p_width, p_height);
}
#endif
}
@ -3765,8 +3775,8 @@ void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_
}
#endif
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
if (context_rd) {
context_rd->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
}
@ -3782,8 +3792,8 @@ DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_wi
}
#endif
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
return context_vulkan->get_vsync_mode(p_window);
if (context_rd) {
return context_rd->get_vsync_mode(p_window);
}
#endif
return DisplayServer::VSYNC_ENABLED;
@ -4545,12 +4555,17 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
}
}
#endif
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextMacOS);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
context_rd = memnew(VulkanContextMacOS);
}
#endif
if (context_rd) {
if (context_rd->initialize() != OK) {
memdelete(context_rd);
context_rd = nullptr;
r_error = ERR_CANT_CREATE;
ERR_FAIL_MSG("Could not initialize Vulkan");
}
@ -4585,10 +4600,10 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
RasterizerGLES3::make_current(false);
}
#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
#if defined(RD_ENABLED)
if (context_rd) {
rendering_device = memnew(RenderingDevice);
rendering_device->initialize(context_rd);
RendererCompositorRD::make_current();
}
@ -4622,16 +4637,16 @@ DisplayServerMacOS::~DisplayServerMacOS() {
gl_manager_angle = nullptr;
}
#endif
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
rendering_device_vulkan = nullptr;
#if defined(RD_ENABLED)
if (rendering_device) {
rendering_device->finalize();
memdelete(rendering_device);
rendering_device = nullptr;
}
if (context_vulkan) {
memdelete(context_vulkan);
context_vulkan = nullptr;
if (context_rd) {
memdelete(context_rd);
context_rd = nullptr;
}
#endif

View File

@ -38,10 +38,13 @@
#import <AppKit/AppKit.h>
class VulkanContextMacOS : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
virtual const char *_get_platform_surface_extension() const override final;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height);
struct WindowPlatformData {
const id *view_ptr;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
VulkanContextMacOS();
~VulkanContextMacOS();

View File

@ -42,14 +42,14 @@ const char *VulkanContextMacOS::_get_platform_surface_extension() const {
return VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
}
Error VulkanContextMacOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) {
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.pView = (__bridge const void *)p_window;
Error VulkanContextMacOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data;
VkSurfaceKHR surface;
VkMacOSSurfaceCreateInfoMVK createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pView = (__bridge const void *)(*wpd->view_ptr);
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult err = vkCreateMacOSSurfaceMVK(get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);

View File

@ -191,7 +191,11 @@ def get_opts():
("mesa_libs", "Path to the MESA/NIR static libraries (required for D3D12)", ""),
("dxc_path", "Path to the DirectX Shader Compiler distribution (required for D3D12)", ""),
("agility_sdk_path", "Path to the Agility SDK distribution (optional for D3D12)", ""),
("agility_sdk_multiarch", "Whether the Agility SDK DLLs will be stored in arch-specific subdirectories", False),
BoolVariable(
"agility_sdk_multiarch",
"Whether the Agility SDK DLLs will be stored in arch-specific subdirectories",
False,
),
("pix_path", "Path to the PIX runtime distribution (optional for D3D12)", ""),
]
@ -660,14 +664,13 @@ def configure_mingw(env):
if env["d3d12"]:
env.AppendUnique(CPPDEFINES=["D3D12_ENABLED"])
env.Append(LIBS=["d3d12", "dxgi", "dxguid"])
env.Append(LIBS=["version"]) # Mesa dependency.
arch_subdir = "arm64" if env["arch"] == "arm64" else "x64"
# PIX
if env["pix_path"] != "":
print("PIX runtime is not supported with MinGW.")
sys.exit(255)
env.Append(LIBPATH=[env["pix_path"] + "/bin/" + arch_subdir])
env.Append(LIBS=["WinPixEventRuntime"])
# Mesa
if env["mesa_libs"] == "":
@ -676,6 +679,7 @@ def configure_mingw(env):
env.Append(LIBPATH=[env["mesa_libs"] + "/bin"])
env.Append(LIBS=["libNIR.windows." + env["arch"]])
env.Append(LIBS=["version"]) # Mesa dependency.
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES3_ENABLED"])

View File

@ -1102,14 +1102,9 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
window_set_transient(p_window, INVALID_WINDOW_ID);
}
#ifdef VULKAN_ENABLED
if (context_vulkan) {
context_vulkan->window_destroy(p_window);
}
#endif
#ifdef D3D12_ENABLED
if (context_d3d12) {
context_d3d12->window_destroy(p_window);
#ifdef RD_ENABLED
if (context_rd) {
context_rd->window_destroy(p_window);
}
#endif
#ifdef GLES3_ENABLED
@ -1539,14 +1534,9 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
wd.width = w;
wd.height = h;
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(p_window, w, h);
}
#endif
#if defined(D3D12_ENABLED)
if (context_d3d12) {
context_d3d12->window_resize(p_window, w, h);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->window_resize(p_window, w, h);
}
#endif
#if defined(GLES3_ENABLED)
@ -2594,15 +2584,9 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
#if defined(D3D12_ENABLED)
if (context_d3d12) {
context_d3d12->set_vsync_mode(p_window, p_vsync_mode);
#if defined(RD_ENABLED)
if (context_rd) {
context_rd->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
@ -2618,15 +2602,9 @@ void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn
DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
return context_vulkan->get_vsync_mode(p_window);
}
#endif
#if defined(D3D12_ENABLED)
if (context_d3d12) {
return context_d3d12->get_vsync_mode(p_window);
#if defined(RD_ENABLED)
if (context_rd) {
return context_rd->get_vsync_mode(p_window);
}
#endif
@ -3788,19 +3766,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
rect_changed = true;
}
// Note: Trigger resize event to update swapchains when window is minimized/restored, even if size is not changed.
if (window_created && window.context_created) {
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
context_vulkan->window_resize(window_id, window.width, window.height);
}
#endif
#if defined(D3D12_ENABLED)
if (context_d3d12) {
context_d3d12->window_resize(window_id, window.width, window.height);
}
#endif
#if defined(RD_ENABLED)
if (context_rd && window.context_created) {
// Note: Trigger resize event to update swapchains when window is minimized/restored, even if size is not changed.
context_rd->window_resize(window_id, window.width, window.height);
}
#endif
}
if (!window.minimized && (!(window_pos_params->flags & SWP_NOMOVE) || window_pos_params->flags & SWP_FRAMECHANGED)) {
@ -3826,7 +3797,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Return here to prevent WM_MOVE and WM_SIZE from being sent
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-windowposchanged#remarks
return 0;
} break;
case WM_ENTERSIZEMOVE: {
@ -4352,25 +4322,32 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
::DwmSetWindowAttribute(wd.hWnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
}
#ifdef RD_ENABLED
if (context_rd) {
union {
#ifdef VULKAN_ENABLED
if (context_vulkan) {
if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create Vulkan Window.");
}
wd.context_created = true;
}
VulkanContextWindows::WindowPlatformData vulkan;
#endif
#ifdef D3D12_ENABLED
if (context_d3d12) {
if (context_d3d12->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) != OK) {
memdelete(context_d3d12);
context_d3d12 = nullptr;
D3D12Context::WindowPlatformData d3d12;
#endif
} wpd;
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
wpd.vulkan.window = wd.hWnd;
wpd.vulkan.instance = hInstance;
}
#endif
#ifdef D3D12_ENABLED
if (rendering_driver == "d3d12") {
wpd.d3d12.window = wd.hWnd;
}
#endif
if (context_rd->window_create(id, p_vsync_mode, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, &wpd) != OK) {
memdelete(context_rd);
context_rd = nullptr;
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create D3D12 Window.");
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, vformat("Failed to create %s Window.", context_rd->get_api_name()));
}
wd.context_created = true;
}
@ -4673,29 +4650,28 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
_register_raw_input_devices(INVALID_WINDOW_ID);
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
context_vulkan = memnew(VulkanContextWindows);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
r_error = ERR_UNAVAILABLE;
return;
}
context_rd = memnew(VulkanContextWindows);
}
#endif
#if defined(D3D12_ENABLED)
if (rendering_driver == "d3d12") {
context_d3d12 = memnew(D3D12Context);
if (context_d3d12->initialize() != OK) {
memdelete(context_d3d12);
context_d3d12 = nullptr;
context_rd = memnew(D3D12Context);
}
#endif
if (context_rd) {
if (context_rd->initialize() != OK) {
memdelete(context_rd);
context_rd = nullptr;
r_error = ERR_UNAVAILABLE;
return;
}
}
#endif
// Init context and rendering device
// Init context and rendering device
#if defined(GLES3_ENABLED)
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64)
@ -4777,18 +4753,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
show_window(MAIN_WINDOW_ID);
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
RendererCompositorRD::make_current();
}
#endif
#if defined(D3D12_ENABLED)
if (rendering_driver == "d3d12") {
rendering_device_d3d12 = memnew(RenderingDeviceD3D12);
rendering_device_d3d12->initialize(context_d3d12);
#if defined(RD_ENABLED)
if (context_rd) {
rendering_device = memnew(RenderingDevice);
rendering_device->initialize(context_rd);
RendererCompositorRD::make_current();
}
@ -4851,6 +4819,16 @@ DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_drive
"If you have recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize Vulkan video driver");
} else if (p_rendering_driver == "d3d12") {
String executable_name = OS::get_singleton()->get_executable_path().get_file();
OS::get_singleton()->alert(
vformat("Your video card drivers seem not to support the required DirectX 12 version.\n\n"
"If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
"You can enable the OpenGL 3 driver by starting the engine from the\n"
"command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
"If you have recently updated your video card drivers, try rebooting.",
executable_name),
"Unable to initialize DirectX 12 video driver");
} else {
OS::get_singleton()->alert(
"Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
@ -4889,14 +4867,9 @@ DisplayServerWindows::~DisplayServerWindows() {
#endif
if (windows.has(MAIN_WINDOW_ID)) {
#ifdef VULKAN_ENABLED
if (context_vulkan) {
context_vulkan->window_destroy(MAIN_WINDOW_ID);
}
#endif
#ifdef D3D12_ENABLED
if (context_d3d12) {
context_d3d12->window_destroy(MAIN_WINDOW_ID);
#ifdef RD_ENABLED
if (context_rd) {
context_rd->window_destroy(MAIN_WINDOW_ID);
}
#endif
if (wintab_available && windows[MAIN_WINDOW_ID].wtctx) {
@ -4906,29 +4879,16 @@ DisplayServerWindows::~DisplayServerWindows() {
DestroyWindow(windows[MAIN_WINDOW_ID].hWnd);
}
#if defined(VULKAN_ENABLED)
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
rendering_device_vulkan = nullptr;
#ifdef RD_ENABLED
if (rendering_device) {
rendering_device->finalize();
memdelete(rendering_device);
rendering_device = nullptr;
}
if (context_vulkan) {
memdelete(context_vulkan);
context_vulkan = nullptr;
}
#endif
#if defined(D3D12_ENABLED)
if (rendering_device_d3d12) {
rendering_device_d3d12->finalize();
memdelete(rendering_device_d3d12);
rendering_device_d3d12 = nullptr;
}
if (context_d3d12) {
memdelete(context_d3d12);
context_d3d12 = nullptr;
if (context_rd) {
memdelete(context_rd);
context_rd = nullptr;
}
#endif

View File

@ -52,14 +52,15 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#endif
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#include "vulkan_context_win.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#endif
#if defined(D3D12_ENABLED)
#include "drivers/d3d12/rendering_device_d3d12.h"
#include "drivers/d3d12/d3d12_context.h"
#endif
#endif
#if defined(GLES3_ENABLED)
@ -346,14 +347,9 @@ class DisplayServerWindows : public DisplayServer {
GLManagerNative_Windows *gl_manager_native = nullptr;
#endif
#if defined(VULKAN_ENABLED)
VulkanContextWindows *context_vulkan = nullptr;
RenderingDeviceVulkan *rendering_device_vulkan = nullptr;
#endif
#if defined(D3D12_ENABLED)
D3D12Context *context_d3d12 = nullptr;
RenderingDeviceD3D12 *rendering_device_d3d12 = nullptr;
#if defined(RD_ENABLED)
ApiContextRD *context_rd = nullptr;
RenderingDevice *rendering_device = nullptr;
#endif
RBMap<int, Vector2> touch_state;

View File

@ -46,14 +46,15 @@
#include "drivers/xaudio2/audio_driver_xaudio2.h"
#endif
#if defined(RD_ENABLED)
#include "servers/rendering/rendering_device.h"
#if defined(VULKAN_ENABLED)
#include "vulkan_context_win.h"
#include "drivers/vulkan/rendering_device_vulkan.h"
#endif
#if defined(D3D12_ENABLED)
#include "drivers/d3d12/rendering_device_d3d12.h"
#include "drivers/d3d12/d3d12_context.h"
#endif
#endif
#include <io.h>

View File

@ -42,14 +42,15 @@ const char *VulkanContextWindows::_get_platform_surface_extension() const {
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
}
Error VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
VkWin32SurfaceCreateInfoKHR createInfo;
Error VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) {
const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data;
VkWin32SurfaceCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.hinstance = p_instance;
createInfo.hwnd = p_window;
VkSurfaceKHR surface;
createInfo.hinstance = wpd->instance;
createInfo.hwnd = wpd->window;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkResult err = vkCreateWin32SurfaceKHR(get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);

View File

@ -42,7 +42,11 @@ class VulkanContextWindows : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, HWND p_window, HINSTANCE p_instance, int p_width, int p_height);
struct WindowPlatformData {
HWND window;
HINSTANCE instance;
};
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final;
VulkanContextWindows();
~VulkanContextWindows();

View File

@ -0,0 +1,33 @@
/**************************************************************************/
/* api_context_rd.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 "api_context_rd.h"
ApiContextRD::~ApiContextRD() {}

View File

@ -0,0 +1,85 @@
/**************************************************************************/
/* api_context_rd.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. */
/**************************************************************************/
#ifndef API_CONTEXT_RD_H
#define API_CONTEXT_RD_H
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_device_driver.h"
class ApiContextRD {
public:
virtual const char *get_api_name() const = 0;
virtual RenderingDevice::Capabilities get_device_capabilities() const = 0;
virtual const RDD::MultiviewCapabilities &get_multiview_capabilities() const = 0;
virtual int get_swapchain_image_count() const = 0;
virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) = 0;
virtual void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) = 0;
virtual int window_get_width(DisplayServer::WindowID p_window = 0) = 0;
virtual int window_get_height(DisplayServer::WindowID p_window = 0) = 0;
virtual bool window_is_valid_swapchain(DisplayServer::WindowID p_window = 0) = 0;
virtual void window_destroy(DisplayServer::WindowID p_window_id) = 0;
virtual RDD::RenderPassID window_get_render_pass(DisplayServer::WindowID p_window = 0) = 0;
virtual RDD::FramebufferID window_get_framebuffer(DisplayServer::WindowID p_window = 0) = 0;
virtual RID local_device_create() = 0;
virtual void local_device_push_command_buffers(RID p_local_device, const RDD::CommandBufferID *p_buffers, int p_count) = 0;
virtual void local_device_sync(RID p_local_device) = 0;
virtual void local_device_free(RID p_local_device) = 0;
virtual void set_setup_buffer(RDD::CommandBufferID p_command_buffer) = 0;
virtual void append_command_buffer(RDD::CommandBufferID p_command_buffer) = 0;
virtual void flush(bool p_flush_setup = false, bool p_flush_pending = false) = 0;
virtual Error prepare_buffers(RDD::CommandBufferID p_command_buffer) = 0;
virtual void postpare_buffers(RDD::CommandBufferID p_command_buffer) = 0;
virtual Error swap_buffers() = 0;
virtual Error initialize() = 0;
virtual void command_begin_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) = 0;
virtual void command_insert_label(RDD::CommandBufferID p_command_buffer, String p_label_name, const Color &p_color) = 0;
virtual void command_end_label(RDD::CommandBufferID p_command_buffer) = 0;
virtual String get_device_vendor_name() const = 0;
virtual String get_device_name() const = 0;
virtual RDD::DeviceType get_device_type() const = 0;
virtual String get_device_api_version() const = 0;
virtual String get_device_pipeline_cache_uuid() const = 0;
virtual void set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_mode) = 0;
virtual DisplayServer::VSyncMode get_vsync_mode(DisplayServer::WindowID p_window = 0) const = 0;
virtual RenderingDeviceDriver *get_driver(RID p_local_device = RID()) = 0;
virtual ~ApiContextRD();
};
#endif // API_CONTEXT_RD_H

View File

@ -242,8 +242,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
current_source = builder.as_string();
RD::ShaderStageSPIRVData stage;
stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_VERTEX, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spir_v.size() == 0) {
stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_VERTEX, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spirv.size() == 0) {
build_ok = false;
} else {
stage.shader_stage = RD::SHADER_STAGE_VERTEX;
@ -260,8 +260,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
current_source = builder.as_string();
RD::ShaderStageSPIRVData stage;
stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_FRAGMENT, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spir_v.size() == 0) {
stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_FRAGMENT, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spirv.size() == 0) {
build_ok = false;
} else {
stage.shader_stage = RD::SHADER_STAGE_FRAGMENT;
@ -279,8 +279,8 @@ void ShaderRD::_compile_variant(uint32_t p_variant, const CompileData *p_data) {
current_source = builder.as_string();
RD::ShaderStageSPIRVData stage;
stage.spir_v = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_COMPUTE, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spir_v.size() == 0) {
stage.spirv = RD::get_singleton()->shader_compile_spirv_from_source(RD::SHADER_STAGE_COMPUTE, current_source, RD::SHADER_LANGUAGE_GLSL, &error);
if (stage.spirv.size() == 0) {
build_ok = false;
} else {
stage.shader_stage = RD::SHADER_STAGE_COMPUTE;

View File

@ -1557,9 +1557,9 @@ uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) c
ERR_FAIL_NULL_V(tex, 0);
if (p_srgb && tex->rd_texture_srgb.is_valid()) {
return RD::get_singleton()->texture_get_native_handle(tex->rd_texture_srgb);
return RD::get_singleton()->get_driver_resource(RD::DRIVER_RESOURCE_TEXTURE, tex->rd_texture_srgb);
} else {
return RD::get_singleton()->texture_get_native_handle(tex->rd_texture);
return RD::get_singleton()->get_driver_resource(RD::DRIVER_RESOURCE_TEXTURE, tex->rd_texture);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -289,7 +289,7 @@ public:
if (bytecode[i].size()) {
RD::ShaderStageSPIRVData stage;
stage.shader_stage = RD::ShaderStage(i);
stage.spir_v = bytecode[i];
stage.spirv = bytecode[i];
stages.push_back(stage);
}
}

View File

@ -0,0 +1,912 @@
/**************************************************************************/
/* rendering_device_commons.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 "rendering_device_commons.h"
/*****************/
/**** GENERIC ****/
/*****************/
const char *const RenderingDeviceCommons::FORMAT_NAMES[DATA_FORMAT_MAX] = {
"R4G4_Unorm_Pack8",
"R4G4B4A4_Unorm_Pack16",
"B4G4R4A4_Unorm_Pack16",
"R5G6B5_Unorm_Pack16",
"B5G6R5_Unorm_Pack16",
"R5G5B5A1_Unorm_Pack16",
"B5G5R5A1_Unorm_Pack16",
"A1R5G5B5_Unorm_Pack16",
"R8_Unorm",
"R8_Snorm",
"R8_Uscaled",
"R8_Sscaled",
"R8_Uint",
"R8_Sint",
"R8_Srgb",
"R8G8_Unorm",
"R8G8_Snorm",
"R8G8_Uscaled",
"R8G8_Sscaled",
"R8G8_Uint",
"R8G8_Sint",
"R8G8_Srgb",
"R8G8B8_Unorm",
"R8G8B8_Snorm",
"R8G8B8_Uscaled",
"R8G8B8_Sscaled",
"R8G8B8_Uint",
"R8G8B8_Sint",
"R8G8B8_Srgb",
"B8G8R8_Unorm",
"B8G8R8_Snorm",
"B8G8R8_Uscaled",
"B8G8R8_Sscaled",
"B8G8R8_Uint",
"B8G8R8_Sint",
"B8G8R8_Srgb",
"R8G8B8A8_Unorm",
"R8G8B8A8_Snorm",
"R8G8B8A8_Uscaled",
"R8G8B8A8_Sscaled",
"R8G8B8A8_Uint",
"R8G8B8A8_Sint",
"R8G8B8A8_Srgb",
"B8G8R8A8_Unorm",
"B8G8R8A8_Snorm",
"B8G8R8A8_Uscaled",
"B8G8R8A8_Sscaled",
"B8G8R8A8_Uint",
"B8G8R8A8_Sint",
"B8G8R8A8_Srgb",
"A8B8G8R8_Unorm_Pack32",
"A8B8G8R8_Snorm_Pack32",
"A8B8G8R8_Uscaled_Pack32",
"A8B8G8R8_Sscaled_Pack32",
"A8B8G8R8_Uint_Pack32",
"A8B8G8R8_Sint_Pack32",
"A8B8G8R8_Srgb_Pack32",
"A2R10G10B10_Unorm_Pack32",
"A2R10G10B10_Snorm_Pack32",
"A2R10G10B10_Uscaled_Pack32",
"A2R10G10B10_Sscaled_Pack32",
"A2R10G10B10_Uint_Pack32",
"A2R10G10B10_Sint_Pack32",
"A2B10G10R10_Unorm_Pack32",
"A2B10G10R10_Snorm_Pack32",
"A2B10G10R10_Uscaled_Pack32",
"A2B10G10R10_Sscaled_Pack32",
"A2B10G10R10_Uint_Pack32",
"A2B10G10R10_Sint_Pack32",
"R16_Unorm",
"R16_Snorm",
"R16_Uscaled",
"R16_Sscaled",
"R16_Uint",
"R16_Sint",
"R16_Sfloat",
"R16G16_Unorm",
"R16G16_Snorm",
"R16G16_Uscaled",
"R16G16_Sscaled",
"R16G16_Uint",
"R16G16_Sint",
"R16G16_Sfloat",
"R16G16B16_Unorm",
"R16G16B16_Snorm",
"R16G16B16_Uscaled",
"R16G16B16_Sscaled",
"R16G16B16_Uint",
"R16G16B16_Sint",
"R16G16B16_Sfloat",
"R16G16B16A16_Unorm",
"R16G16B16A16_Snorm",
"R16G16B16A16_Uscaled",
"R16G16B16A16_Sscaled",
"R16G16B16A16_Uint",
"R16G16B16A16_Sint",
"R16G16B16A16_Sfloat",
"R32_Uint",
"R32_Sint",
"R32_Sfloat",
"R32G32_Uint",
"R32G32_Sint",
"R32G32_Sfloat",
"R32G32B32_Uint",
"R32G32B32_Sint",
"R32G32B32_Sfloat",
"R32G32B32A32_Uint",
"R32G32B32A32_Sint",
"R32G32B32A32_Sfloat",
"R64_Uint",
"R64_Sint",
"R64_Sfloat",
"R64G64_Uint",
"R64G64_Sint",
"R64G64_Sfloat",
"R64G64B64_Uint",
"R64G64B64_Sint",
"R64G64B64_Sfloat",
"R64G64B64A64_Uint",
"R64G64B64A64_Sint",
"R64G64B64A64_Sfloat",
"B10G11R11_Ufloat_Pack32",
"E5B9G9R9_Ufloat_Pack32",
"D16_Unorm",
"X8_D24_Unorm_Pack32",
"D32_Sfloat",
"S8_Uint",
"D16_Unorm_S8_Uint",
"D24_Unorm_S8_Uint",
"D32_Sfloat_S8_Uint",
"Bc1_Rgb_Unorm_Block",
"Bc1_Rgb_Srgb_Block",
"Bc1_Rgba_Unorm_Block",
"Bc1_Rgba_Srgb_Block",
"Bc2_Unorm_Block",
"Bc2_Srgb_Block",
"Bc3_Unorm_Block",
"Bc3_Srgb_Block",
"Bc4_Unorm_Block",
"Bc4_Snorm_Block",
"Bc5_Unorm_Block",
"Bc5_Snorm_Block",
"Bc6H_Ufloat_Block",
"Bc6H_Sfloat_Block",
"Bc7_Unorm_Block",
"Bc7_Srgb_Block",
"Etc2_R8G8B8_Unorm_Block",
"Etc2_R8G8B8_Srgb_Block",
"Etc2_R8G8B8A1_Unorm_Block",
"Etc2_R8G8B8A1_Srgb_Block",
"Etc2_R8G8B8A8_Unorm_Block",
"Etc2_R8G8B8A8_Srgb_Block",
"Eac_R11_Unorm_Block",
"Eac_R11_Snorm_Block",
"Eac_R11G11_Unorm_Block",
"Eac_R11G11_Snorm_Block",
"Astc_4X4_Unorm_Block",
"Astc_4X4_Srgb_Block",
"Astc_5X4_Unorm_Block",
"Astc_5X4_Srgb_Block",
"Astc_5X5_Unorm_Block",
"Astc_5X5_Srgb_Block",
"Astc_6X5_Unorm_Block",
"Astc_6X5_Srgb_Block",
"Astc_6X6_Unorm_Block",
"Astc_6X6_Srgb_Block",
"Astc_8X5_Unorm_Block",
"Astc_8X5_Srgb_Block",
"Astc_8X6_Unorm_Block",
"Astc_8X6_Srgb_Block",
"Astc_8X8_Unorm_Block",
"Astc_8X8_Srgb_Block",
"Astc_10X5_Unorm_Block",
"Astc_10X5_Srgb_Block",
"Astc_10X6_Unorm_Block",
"Astc_10X6_Srgb_Block",
"Astc_10X8_Unorm_Block",
"Astc_10X8_Srgb_Block",
"Astc_10X10_Unorm_Block",
"Astc_10X10_Srgb_Block",
"Astc_12X10_Unorm_Block",
"Astc_12X10_Srgb_Block",
"Astc_12X12_Unorm_Block",
"Astc_12X12_Srgb_Block",
"G8B8G8R8_422_Unorm",
"B8G8R8G8_422_Unorm",
"G8_B8_R8_3Plane_420_Unorm",
"G8_B8R8_2Plane_420_Unorm",
"G8_B8_R8_3Plane_422_Unorm",
"G8_B8R8_2Plane_422_Unorm",
"G8_B8_R8_3Plane_444_Unorm",
"R10X6_Unorm_Pack16",
"R10X6G10X6_Unorm_2Pack16",
"R10X6G10X6B10X6A10X6_Unorm_4Pack16",
"G10X6B10X6G10X6R10X6_422_Unorm_4Pack16",
"B10X6G10X6R10X6G10X6_422_Unorm_4Pack16",
"G10X6_B10X6_R10X6_3Plane_420_Unorm_3Pack16",
"G10X6_B10X6R10X6_2Plane_420_Unorm_3Pack16",
"G10X6_B10X6_R10X6_3Plane_422_Unorm_3Pack16",
"G10X6_B10X6R10X6_2Plane_422_Unorm_3Pack16",
"G10X6_B10X6_R10X6_3Plane_444_Unorm_3Pack16",
"R12X4_Unorm_Pack16",
"R12X4G12X4_Unorm_2Pack16",
"R12X4G12X4B12X4A12X4_Unorm_4Pack16",
"G12X4B12X4G12X4R12X4_422_Unorm_4Pack16",
"B12X4G12X4R12X4G12X4_422_Unorm_4Pack16",
"G12X4_B12X4_R12X4_3Plane_420_Unorm_3Pack16",
"G12X4_B12X4R12X4_2Plane_420_Unorm_3Pack16",
"G12X4_B12X4_R12X4_3Plane_422_Unorm_3Pack16",
"G12X4_B12X4R12X4_2Plane_422_Unorm_3Pack16",
"G12X4_B12X4_R12X4_3Plane_444_Unorm_3Pack16",
"G16B16G16R16_422_Unorm",
"B16G16R16G16_422_Unorm",
"G16_B16_R16_3Plane_420_Unorm",
"G16_B16R16_2Plane_420_Unorm",
"G16_B16_R16_3Plane_422_Unorm",
"G16_B16R16_2Plane_422_Unorm",
"G16_B16_R16_3Plane_444_Unorm",
};
/*****************/
/**** TEXTURE ****/
/*****************/
const uint32_t RenderingDeviceCommons::TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX] = { 1, 2, 4, 8, 16, 32, 64 };
uint32_t RenderingDeviceCommons::get_image_format_pixel_size(DataFormat p_format) {
switch (p_format) {
case DATA_FORMAT_R4G4_UNORM_PACK8:
return 1;
case DATA_FORMAT_R4G4B4A4_UNORM_PACK16:
case DATA_FORMAT_B4G4R4A4_UNORM_PACK16:
case DATA_FORMAT_R5G6B5_UNORM_PACK16:
case DATA_FORMAT_B5G6R5_UNORM_PACK16:
case DATA_FORMAT_R5G5B5A1_UNORM_PACK16:
case DATA_FORMAT_B5G5R5A1_UNORM_PACK16:
case DATA_FORMAT_A1R5G5B5_UNORM_PACK16:
return 2;
case DATA_FORMAT_R8_UNORM:
case DATA_FORMAT_R8_SNORM:
case DATA_FORMAT_R8_USCALED:
case DATA_FORMAT_R8_SSCALED:
case DATA_FORMAT_R8_UINT:
case DATA_FORMAT_R8_SINT:
case DATA_FORMAT_R8_SRGB:
return 1;
case DATA_FORMAT_R8G8_UNORM:
case DATA_FORMAT_R8G8_SNORM:
case DATA_FORMAT_R8G8_USCALED:
case DATA_FORMAT_R8G8_SSCALED:
case DATA_FORMAT_R8G8_UINT:
case DATA_FORMAT_R8G8_SINT:
case DATA_FORMAT_R8G8_SRGB:
return 2;
case DATA_FORMAT_R8G8B8_UNORM:
case DATA_FORMAT_R8G8B8_SNORM:
case DATA_FORMAT_R8G8B8_USCALED:
case DATA_FORMAT_R8G8B8_SSCALED:
case DATA_FORMAT_R8G8B8_UINT:
case DATA_FORMAT_R8G8B8_SINT:
case DATA_FORMAT_R8G8B8_SRGB:
case DATA_FORMAT_B8G8R8_UNORM:
case DATA_FORMAT_B8G8R8_SNORM:
case DATA_FORMAT_B8G8R8_USCALED:
case DATA_FORMAT_B8G8R8_SSCALED:
case DATA_FORMAT_B8G8R8_UINT:
case DATA_FORMAT_B8G8R8_SINT:
case DATA_FORMAT_B8G8R8_SRGB:
return 3;
case DATA_FORMAT_R8G8B8A8_UNORM:
case DATA_FORMAT_R8G8B8A8_SNORM:
case DATA_FORMAT_R8G8B8A8_USCALED:
case DATA_FORMAT_R8G8B8A8_SSCALED:
case DATA_FORMAT_R8G8B8A8_UINT:
case DATA_FORMAT_R8G8B8A8_SINT:
case DATA_FORMAT_R8G8B8A8_SRGB:
case DATA_FORMAT_B8G8R8A8_UNORM:
case DATA_FORMAT_B8G8R8A8_SNORM:
case DATA_FORMAT_B8G8R8A8_USCALED:
case DATA_FORMAT_B8G8R8A8_SSCALED:
case DATA_FORMAT_B8G8R8A8_UINT:
case DATA_FORMAT_B8G8R8A8_SINT:
case DATA_FORMAT_B8G8R8A8_SRGB:
return 4;
case DATA_FORMAT_A8B8G8R8_UNORM_PACK32:
case DATA_FORMAT_A8B8G8R8_SNORM_PACK32:
case DATA_FORMAT_A8B8G8R8_USCALED_PACK32:
case DATA_FORMAT_A8B8G8R8_SSCALED_PACK32:
case DATA_FORMAT_A8B8G8R8_UINT_PACK32:
case DATA_FORMAT_A8B8G8R8_SINT_PACK32:
case DATA_FORMAT_A8B8G8R8_SRGB_PACK32:
case DATA_FORMAT_A2R10G10B10_UNORM_PACK32:
case DATA_FORMAT_A2R10G10B10_SNORM_PACK32:
case DATA_FORMAT_A2R10G10B10_USCALED_PACK32:
case DATA_FORMAT_A2R10G10B10_SSCALED_PACK32:
case DATA_FORMAT_A2R10G10B10_UINT_PACK32:
case DATA_FORMAT_A2R10G10B10_SINT_PACK32:
case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
case DATA_FORMAT_A2B10G10R10_SNORM_PACK32:
case DATA_FORMAT_A2B10G10R10_USCALED_PACK32:
case DATA_FORMAT_A2B10G10R10_SSCALED_PACK32:
case DATA_FORMAT_A2B10G10R10_UINT_PACK32:
case DATA_FORMAT_A2B10G10R10_SINT_PACK32:
return 4;
case DATA_FORMAT_R16_UNORM:
case DATA_FORMAT_R16_SNORM:
case DATA_FORMAT_R16_USCALED:
case DATA_FORMAT_R16_SSCALED:
case DATA_FORMAT_R16_UINT:
case DATA_FORMAT_R16_SINT:
case DATA_FORMAT_R16_SFLOAT:
return 2;
case DATA_FORMAT_R16G16_UNORM:
case DATA_FORMAT_R16G16_SNORM:
case DATA_FORMAT_R16G16_USCALED:
case DATA_FORMAT_R16G16_SSCALED:
case DATA_FORMAT_R16G16_UINT:
case DATA_FORMAT_R16G16_SINT:
case DATA_FORMAT_R16G16_SFLOAT:
return 4;
case DATA_FORMAT_R16G16B16_UNORM:
case DATA_FORMAT_R16G16B16_SNORM:
case DATA_FORMAT_R16G16B16_USCALED:
case DATA_FORMAT_R16G16B16_SSCALED:
case DATA_FORMAT_R16G16B16_UINT:
case DATA_FORMAT_R16G16B16_SINT:
case DATA_FORMAT_R16G16B16_SFLOAT:
return 6;
case DATA_FORMAT_R16G16B16A16_UNORM:
case DATA_FORMAT_R16G16B16A16_SNORM:
case DATA_FORMAT_R16G16B16A16_USCALED:
case DATA_FORMAT_R16G16B16A16_SSCALED:
case DATA_FORMAT_R16G16B16A16_UINT:
case DATA_FORMAT_R16G16B16A16_SINT:
case DATA_FORMAT_R16G16B16A16_SFLOAT:
return 8;
case DATA_FORMAT_R32_UINT:
case DATA_FORMAT_R32_SINT:
case DATA_FORMAT_R32_SFLOAT:
return 4;
case DATA_FORMAT_R32G32_UINT:
case DATA_FORMAT_R32G32_SINT:
case DATA_FORMAT_R32G32_SFLOAT:
return 8;
case DATA_FORMAT_R32G32B32_UINT:
case DATA_FORMAT_R32G32B32_SINT:
case DATA_FORMAT_R32G32B32_SFLOAT:
return 12;
case DATA_FORMAT_R32G32B32A32_UINT:
case DATA_FORMAT_R32G32B32A32_SINT:
case DATA_FORMAT_R32G32B32A32_SFLOAT:
return 16;
case DATA_FORMAT_R64_UINT:
case DATA_FORMAT_R64_SINT:
case DATA_FORMAT_R64_SFLOAT:
return 8;
case DATA_FORMAT_R64G64_UINT:
case DATA_FORMAT_R64G64_SINT:
case DATA_FORMAT_R64G64_SFLOAT:
return 16;
case DATA_FORMAT_R64G64B64_UINT:
case DATA_FORMAT_R64G64B64_SINT:
case DATA_FORMAT_R64G64B64_SFLOAT:
return 24;
case DATA_FORMAT_R64G64B64A64_UINT:
case DATA_FORMAT_R64G64B64A64_SINT:
case DATA_FORMAT_R64G64B64A64_SFLOAT:
return 32;
case DATA_FORMAT_B10G11R11_UFLOAT_PACK32:
case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32:
return 4;
case DATA_FORMAT_D16_UNORM:
return 2;
case DATA_FORMAT_X8_D24_UNORM_PACK32:
return 4;
case DATA_FORMAT_D32_SFLOAT:
return 4;
case DATA_FORMAT_S8_UINT:
return 1;
case DATA_FORMAT_D16_UNORM_S8_UINT:
return 4;
case DATA_FORMAT_D24_UNORM_S8_UINT:
return 4;
case DATA_FORMAT_D32_SFLOAT_S8_UINT:
return 5; // ?
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
case DATA_FORMAT_BC2_UNORM_BLOCK:
case DATA_FORMAT_BC2_SRGB_BLOCK:
case DATA_FORMAT_BC3_UNORM_BLOCK:
case DATA_FORMAT_BC3_SRGB_BLOCK:
case DATA_FORMAT_BC4_UNORM_BLOCK:
case DATA_FORMAT_BC4_SNORM_BLOCK:
case DATA_FORMAT_BC5_UNORM_BLOCK:
case DATA_FORMAT_BC5_SNORM_BLOCK:
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
case DATA_FORMAT_BC7_UNORM_BLOCK:
case DATA_FORMAT_BC7_SRGB_BLOCK:
return 1;
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return 1;
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
return 1;
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK:
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
return 1;
case DATA_FORMAT_G8B8G8R8_422_UNORM:
case DATA_FORMAT_B8G8R8G8_422_UNORM:
return 4;
case DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM:
case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
return 4;
case DATA_FORMAT_R10X6_UNORM_PACK16:
case DATA_FORMAT_R10X6G10X6_UNORM_2PACK16:
case DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
case DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
case DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
case DATA_FORMAT_R12X4_UNORM_PACK16:
case DATA_FORMAT_R12X4G12X4_UNORM_2PACK16:
case DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
case DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
case DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
return 2;
case DATA_FORMAT_G16B16G16R16_422_UNORM:
case DATA_FORMAT_B16G16R16G16_422_UNORM:
case DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM:
case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
return 8;
default: {
ERR_PRINT("Format not handled, bug");
}
}
return 1;
}
// https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.pdf
void RenderingDeviceCommons::get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h) {
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
case DATA_FORMAT_BC2_UNORM_BLOCK:
case DATA_FORMAT_BC2_SRGB_BLOCK:
case DATA_FORMAT_BC3_UNORM_BLOCK:
case DATA_FORMAT_BC3_SRGB_BLOCK:
case DATA_FORMAT_BC4_UNORM_BLOCK:
case DATA_FORMAT_BC4_SNORM_BLOCK:
case DATA_FORMAT_BC5_UNORM_BLOCK:
case DATA_FORMAT_BC5_SNORM_BLOCK:
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
case DATA_FORMAT_BC7_UNORM_BLOCK:
case DATA_FORMAT_BC7_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK: {
r_w = 4;
r_h = 4;
} break;
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: // Unsupported
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK: {
r_w = 4;
r_h = 4;
} break;
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK: {
r_w = 8;
r_h = 8;
} break;
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK: // Unsupported
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
r_w = 4;
r_h = 4;
return;
default: {
r_w = 1;
r_h = 1;
}
}
}
uint32_t RenderingDeviceCommons::get_compressed_image_format_block_byte_size(DataFormat p_format) {
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
return 8;
case DATA_FORMAT_BC2_UNORM_BLOCK:
case DATA_FORMAT_BC2_SRGB_BLOCK:
return 16;
case DATA_FORMAT_BC3_UNORM_BLOCK:
case DATA_FORMAT_BC3_SRGB_BLOCK:
return 16;
case DATA_FORMAT_BC4_UNORM_BLOCK:
case DATA_FORMAT_BC4_SNORM_BLOCK:
return 8;
case DATA_FORMAT_BC5_UNORM_BLOCK:
case DATA_FORMAT_BC5_SNORM_BLOCK:
return 16;
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
return 16;
case DATA_FORMAT_BC7_UNORM_BLOCK:
case DATA_FORMAT_BC7_SRGB_BLOCK:
return 16;
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return 8;
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
return 8;
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
return 16;
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
return 8;
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
return 16;
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
return 16;
default: {
}
}
return 1;
}
uint32_t RenderingDeviceCommons::get_compressed_image_format_pixel_rshift(DataFormat p_format) {
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: // These formats are half byte size, so rshift is 1.
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
case DATA_FORMAT_BC4_UNORM_BLOCK:
case DATA_FORMAT_BC4_SNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
return 1;
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK: {
return 2;
}
default: {
}
}
return 0;
}
uint32_t RenderingDeviceCommons::get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw, uint32_t *r_blockh, uint32_t *r_depth) {
ERR_FAIL_COND_V(p_mipmaps == 0, 0);
uint32_t w = p_width;
uint32_t h = p_height;
uint32_t d = p_depth;
uint32_t size = 0;
uint32_t pixel_size = get_image_format_pixel_size(p_format);
uint32_t pixel_rshift = get_compressed_image_format_pixel_rshift(p_format);
uint32_t blockw, blockh;
get_compressed_image_format_block_dimensions(p_format, blockw, blockh);
for (uint32_t i = 0; i < p_mipmaps; i++) {
uint32_t bw = w % blockw != 0 ? w + (blockw - w % blockw) : w;
uint32_t bh = h % blockh != 0 ? h + (blockh - h % blockh) : h;
uint32_t s = bw * bh;
s *= pixel_size;
s >>= pixel_rshift;
size += s * d;
if (r_blockw) {
*r_blockw = bw;
}
if (r_blockh) {
*r_blockh = bh;
}
if (r_depth) {
*r_depth = d;
}
w = MAX(blockw, w >> 1);
h = MAX(blockh, h >> 1);
d = MAX(1u, d >> 1);
}
return size;
}
uint32_t RenderingDeviceCommons::get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
// Formats and block size don't really matter here since they can all go down to 1px (even if block is larger).
uint32_t w = p_width;
uint32_t h = p_height;
uint32_t d = p_depth;
uint32_t mipmaps = 1;
while (true) {
if (w == 1 && h == 1 && d == 1) {
break;
}
w = MAX(1u, w >> 1);
h = MAX(1u, h >> 1);
d = MAX(1u, d >> 1);
mipmaps++;
}
return mipmaps;
}
bool RenderingDeviceCommons::format_has_stencil(DataFormat p_format) {
switch (p_format) {
case DATA_FORMAT_S8_UINT:
case DATA_FORMAT_D16_UNORM_S8_UINT:
case DATA_FORMAT_D24_UNORM_S8_UINT:
case DATA_FORMAT_D32_SFLOAT_S8_UINT: {
return true;
}
default: {
}
}
return false;
}
uint32_t RenderingDeviceCommons::format_get_plane_count(DataFormat p_format) {
uint32_t planes = 1;
switch (p_format) {
case DATA_FORMAT_D16_UNORM_S8_UINT:
case DATA_FORMAT_D24_UNORM_S8_UINT:
case DATA_FORMAT_D32_SFLOAT_S8_UINT: {
planes = 2;
break;
}
default: {
}
}
DEV_ASSERT(planes <= MAX_IMAGE_FORMAT_PLANES);
return planes;
}
/*****************/
/**** SAMPLER ****/
/*****************/
const Color RenderingDeviceCommons::SAMPLER_BORDER_COLOR_VALUE[SAMPLER_BORDER_COLOR_MAX] = {
Color(0, 0, 0, 0),
Color(0, 0, 0, 0),
Color(0, 0, 0, 1),
Color(0, 0, 0, 1),
Color(1, 1, 1, 1),
Color(1, 1, 1, 1),
};
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
uint32_t RenderingDeviceCommons::get_format_vertex_size(DataFormat p_format) {
switch (p_format) {
case DATA_FORMAT_R8_UNORM:
case DATA_FORMAT_R8_SNORM:
case DATA_FORMAT_R8_UINT:
case DATA_FORMAT_R8_SINT:
case DATA_FORMAT_R8G8_UNORM:
case DATA_FORMAT_R8G8_SNORM:
case DATA_FORMAT_R8G8_UINT:
case DATA_FORMAT_R8G8_SINT:
case DATA_FORMAT_R8G8B8_UNORM:
case DATA_FORMAT_R8G8B8_SNORM:
case DATA_FORMAT_R8G8B8_UINT:
case DATA_FORMAT_R8G8B8_SINT:
case DATA_FORMAT_B8G8R8_UNORM:
case DATA_FORMAT_B8G8R8_SNORM:
case DATA_FORMAT_B8G8R8_UINT:
case DATA_FORMAT_B8G8R8_SINT:
case DATA_FORMAT_R8G8B8A8_UNORM:
case DATA_FORMAT_R8G8B8A8_SNORM:
case DATA_FORMAT_R8G8B8A8_UINT:
case DATA_FORMAT_R8G8B8A8_SINT:
case DATA_FORMAT_B8G8R8A8_UNORM:
case DATA_FORMAT_B8G8R8A8_SNORM:
case DATA_FORMAT_B8G8R8A8_UINT:
case DATA_FORMAT_B8G8R8A8_SINT:
case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
return 4;
case DATA_FORMAT_R16_UNORM:
case DATA_FORMAT_R16_SNORM:
case DATA_FORMAT_R16_UINT:
case DATA_FORMAT_R16_SINT:
case DATA_FORMAT_R16_SFLOAT:
return 4;
case DATA_FORMAT_R16G16_UNORM:
case DATA_FORMAT_R16G16_SNORM:
case DATA_FORMAT_R16G16_UINT:
case DATA_FORMAT_R16G16_SINT:
case DATA_FORMAT_R16G16_SFLOAT:
return 4;
case DATA_FORMAT_R16G16B16_UNORM:
case DATA_FORMAT_R16G16B16_SNORM:
case DATA_FORMAT_R16G16B16_UINT:
case DATA_FORMAT_R16G16B16_SINT:
case DATA_FORMAT_R16G16B16_SFLOAT:
return 8;
case DATA_FORMAT_R16G16B16A16_UNORM:
case DATA_FORMAT_R16G16B16A16_SNORM:
case DATA_FORMAT_R16G16B16A16_UINT:
case DATA_FORMAT_R16G16B16A16_SINT:
case DATA_FORMAT_R16G16B16A16_SFLOAT:
return 8;
case DATA_FORMAT_R32_UINT:
case DATA_FORMAT_R32_SINT:
case DATA_FORMAT_R32_SFLOAT:
return 4;
case DATA_FORMAT_R32G32_UINT:
case DATA_FORMAT_R32G32_SINT:
case DATA_FORMAT_R32G32_SFLOAT:
return 8;
case DATA_FORMAT_R32G32B32_UINT:
case DATA_FORMAT_R32G32B32_SINT:
case DATA_FORMAT_R32G32B32_SFLOAT:
return 12;
case DATA_FORMAT_R32G32B32A32_UINT:
case DATA_FORMAT_R32G32B32A32_SINT:
case DATA_FORMAT_R32G32B32A32_SFLOAT:
return 16;
case DATA_FORMAT_R64_UINT:
case DATA_FORMAT_R64_SINT:
case DATA_FORMAT_R64_SFLOAT:
return 8;
case DATA_FORMAT_R64G64_UINT:
case DATA_FORMAT_R64G64_SINT:
case DATA_FORMAT_R64G64_SFLOAT:
return 16;
case DATA_FORMAT_R64G64B64_UINT:
case DATA_FORMAT_R64G64B64_SINT:
case DATA_FORMAT_R64G64B64_SFLOAT:
return 24;
case DATA_FORMAT_R64G64B64A64_UINT:
case DATA_FORMAT_R64G64B64A64_SINT:
case DATA_FORMAT_R64G64B64A64_SFLOAT:
return 32;
default:
return 0;
}
}
/****************/
/**** SHADER ****/
/****************/
const char *RenderingDeviceCommons::SHADER_STAGE_NAMES[SHADER_STAGE_MAX] = {
"Vertex",
"Fragment",
"TesselationControl",
"TesselationEvaluation",
"Compute",
};

View File

@ -0,0 +1,921 @@
/**************************************************************************/
/* rendering_device_commons.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. */
/**************************************************************************/
#ifndef RENDERING_DEVICE_COMMONS_H
#define RENDERING_DEVICE_COMMONS_H
#include "core/object/object.h"
#include "core/variant/type_info.h"
#define STEPIFY(m_number, m_alignment) ((((m_number) + ((m_alignment)-1)) / (m_alignment)) * (m_alignment))
class RenderingDeviceCommons : public Object {
////////////////////////////////////////////
// PUBLIC STUFF
// Exposed by RenderingDevice, and shared
// with RenderingDeviceDriver.
////////////////////////////////////////////
public:
/*****************/
/**** GENERIC ****/
/*****************/
static const int INVALID_ID = -1;
enum DataFormat {
DATA_FORMAT_R4G4_UNORM_PACK8,
DATA_FORMAT_R4G4B4A4_UNORM_PACK16,
DATA_FORMAT_B4G4R4A4_UNORM_PACK16,
DATA_FORMAT_R5G6B5_UNORM_PACK16,
DATA_FORMAT_B5G6R5_UNORM_PACK16,
DATA_FORMAT_R5G5B5A1_UNORM_PACK16,
DATA_FORMAT_B5G5R5A1_UNORM_PACK16,
DATA_FORMAT_A1R5G5B5_UNORM_PACK16,
DATA_FORMAT_R8_UNORM,
DATA_FORMAT_R8_SNORM,
DATA_FORMAT_R8_USCALED,
DATA_FORMAT_R8_SSCALED,
DATA_FORMAT_R8_UINT,
DATA_FORMAT_R8_SINT,
DATA_FORMAT_R8_SRGB,
DATA_FORMAT_R8G8_UNORM,
DATA_FORMAT_R8G8_SNORM,
DATA_FORMAT_R8G8_USCALED,
DATA_FORMAT_R8G8_SSCALED,
DATA_FORMAT_R8G8_UINT,
DATA_FORMAT_R8G8_SINT,
DATA_FORMAT_R8G8_SRGB,
DATA_FORMAT_R8G8B8_UNORM,
DATA_FORMAT_R8G8B8_SNORM,
DATA_FORMAT_R8G8B8_USCALED,
DATA_FORMAT_R8G8B8_SSCALED,
DATA_FORMAT_R8G8B8_UINT,
DATA_FORMAT_R8G8B8_SINT,
DATA_FORMAT_R8G8B8_SRGB,
DATA_FORMAT_B8G8R8_UNORM,
DATA_FORMAT_B8G8R8_SNORM,
DATA_FORMAT_B8G8R8_USCALED,
DATA_FORMAT_B8G8R8_SSCALED,
DATA_FORMAT_B8G8R8_UINT,
DATA_FORMAT_B8G8R8_SINT,
DATA_FORMAT_B8G8R8_SRGB,
DATA_FORMAT_R8G8B8A8_UNORM,
DATA_FORMAT_R8G8B8A8_SNORM,
DATA_FORMAT_R8G8B8A8_USCALED,
DATA_FORMAT_R8G8B8A8_SSCALED,
DATA_FORMAT_R8G8B8A8_UINT,
DATA_FORMAT_R8G8B8A8_SINT,
DATA_FORMAT_R8G8B8A8_SRGB,
DATA_FORMAT_B8G8R8A8_UNORM,
DATA_FORMAT_B8G8R8A8_SNORM,
DATA_FORMAT_B8G8R8A8_USCALED,
DATA_FORMAT_B8G8R8A8_SSCALED,
DATA_FORMAT_B8G8R8A8_UINT,
DATA_FORMAT_B8G8R8A8_SINT,
DATA_FORMAT_B8G8R8A8_SRGB,
DATA_FORMAT_A8B8G8R8_UNORM_PACK32,
DATA_FORMAT_A8B8G8R8_SNORM_PACK32,
DATA_FORMAT_A8B8G8R8_USCALED_PACK32,
DATA_FORMAT_A8B8G8R8_SSCALED_PACK32,
DATA_FORMAT_A8B8G8R8_UINT_PACK32,
DATA_FORMAT_A8B8G8R8_SINT_PACK32,
DATA_FORMAT_A8B8G8R8_SRGB_PACK32,
DATA_FORMAT_A2R10G10B10_UNORM_PACK32,
DATA_FORMAT_A2R10G10B10_SNORM_PACK32,
DATA_FORMAT_A2R10G10B10_USCALED_PACK32,
DATA_FORMAT_A2R10G10B10_SSCALED_PACK32,
DATA_FORMAT_A2R10G10B10_UINT_PACK32,
DATA_FORMAT_A2R10G10B10_SINT_PACK32,
DATA_FORMAT_A2B10G10R10_UNORM_PACK32,
DATA_FORMAT_A2B10G10R10_SNORM_PACK32,
DATA_FORMAT_A2B10G10R10_USCALED_PACK32,
DATA_FORMAT_A2B10G10R10_SSCALED_PACK32,
DATA_FORMAT_A2B10G10R10_UINT_PACK32,
DATA_FORMAT_A2B10G10R10_SINT_PACK32,
DATA_FORMAT_R16_UNORM,
DATA_FORMAT_R16_SNORM,
DATA_FORMAT_R16_USCALED,
DATA_FORMAT_R16_SSCALED,
DATA_FORMAT_R16_UINT,
DATA_FORMAT_R16_SINT,
DATA_FORMAT_R16_SFLOAT,
DATA_FORMAT_R16G16_UNORM,
DATA_FORMAT_R16G16_SNORM,
DATA_FORMAT_R16G16_USCALED,
DATA_FORMAT_R16G16_SSCALED,
DATA_FORMAT_R16G16_UINT,
DATA_FORMAT_R16G16_SINT,
DATA_FORMAT_R16G16_SFLOAT,
DATA_FORMAT_R16G16B16_UNORM,
DATA_FORMAT_R16G16B16_SNORM,
DATA_FORMAT_R16G16B16_USCALED,
DATA_FORMAT_R16G16B16_SSCALED,
DATA_FORMAT_R16G16B16_UINT,
DATA_FORMAT_R16G16B16_SINT,
DATA_FORMAT_R16G16B16_SFLOAT,
DATA_FORMAT_R16G16B16A16_UNORM,
DATA_FORMAT_R16G16B16A16_SNORM,
DATA_FORMAT_R16G16B16A16_USCALED,
DATA_FORMAT_R16G16B16A16_SSCALED,
DATA_FORMAT_R16G16B16A16_UINT,
DATA_FORMAT_R16G16B16A16_SINT,
DATA_FORMAT_R16G16B16A16_SFLOAT,
DATA_FORMAT_R32_UINT,
DATA_FORMAT_R32_SINT,
DATA_FORMAT_R32_SFLOAT,
DATA_FORMAT_R32G32_UINT,
DATA_FORMAT_R32G32_SINT,
DATA_FORMAT_R32G32_SFLOAT,
DATA_FORMAT_R32G32B32_UINT,
DATA_FORMAT_R32G32B32_SINT,
DATA_FORMAT_R32G32B32_SFLOAT,
DATA_FORMAT_R32G32B32A32_UINT,
DATA_FORMAT_R32G32B32A32_SINT,
DATA_FORMAT_R32G32B32A32_SFLOAT,
DATA_FORMAT_R64_UINT,
DATA_FORMAT_R64_SINT,
DATA_FORMAT_R64_SFLOAT,
DATA_FORMAT_R64G64_UINT,
DATA_FORMAT_R64G64_SINT,
DATA_FORMAT_R64G64_SFLOAT,
DATA_FORMAT_R64G64B64_UINT,
DATA_FORMAT_R64G64B64_SINT,
DATA_FORMAT_R64G64B64_SFLOAT,
DATA_FORMAT_R64G64B64A64_UINT,
DATA_FORMAT_R64G64B64A64_SINT,
DATA_FORMAT_R64G64B64A64_SFLOAT,
DATA_FORMAT_B10G11R11_UFLOAT_PACK32,
DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32,
DATA_FORMAT_D16_UNORM,
DATA_FORMAT_X8_D24_UNORM_PACK32,
DATA_FORMAT_D32_SFLOAT,
DATA_FORMAT_S8_UINT,
DATA_FORMAT_D16_UNORM_S8_UINT,
DATA_FORMAT_D24_UNORM_S8_UINT,
DATA_FORMAT_D32_SFLOAT_S8_UINT,
DATA_FORMAT_BC1_RGB_UNORM_BLOCK,
DATA_FORMAT_BC1_RGB_SRGB_BLOCK,
DATA_FORMAT_BC1_RGBA_UNORM_BLOCK,
DATA_FORMAT_BC1_RGBA_SRGB_BLOCK,
DATA_FORMAT_BC2_UNORM_BLOCK,
DATA_FORMAT_BC2_SRGB_BLOCK,
DATA_FORMAT_BC3_UNORM_BLOCK,
DATA_FORMAT_BC3_SRGB_BLOCK,
DATA_FORMAT_BC4_UNORM_BLOCK,
DATA_FORMAT_BC4_SNORM_BLOCK,
DATA_FORMAT_BC5_UNORM_BLOCK,
DATA_FORMAT_BC5_SNORM_BLOCK,
DATA_FORMAT_BC6H_UFLOAT_BLOCK,
DATA_FORMAT_BC6H_SFLOAT_BLOCK,
DATA_FORMAT_BC7_UNORM_BLOCK,
DATA_FORMAT_BC7_SRGB_BLOCK,
DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
DATA_FORMAT_EAC_R11_UNORM_BLOCK,
DATA_FORMAT_EAC_R11_SNORM_BLOCK,
DATA_FORMAT_EAC_R11G11_UNORM_BLOCK,
DATA_FORMAT_EAC_R11G11_SNORM_BLOCK,
DATA_FORMAT_ASTC_4x4_UNORM_BLOCK,
DATA_FORMAT_ASTC_4x4_SRGB_BLOCK,
DATA_FORMAT_ASTC_5x4_UNORM_BLOCK,
DATA_FORMAT_ASTC_5x4_SRGB_BLOCK,
DATA_FORMAT_ASTC_5x5_UNORM_BLOCK,
DATA_FORMAT_ASTC_5x5_SRGB_BLOCK,
DATA_FORMAT_ASTC_6x5_UNORM_BLOCK,
DATA_FORMAT_ASTC_6x5_SRGB_BLOCK,
DATA_FORMAT_ASTC_6x6_UNORM_BLOCK,
DATA_FORMAT_ASTC_6x6_SRGB_BLOCK,
DATA_FORMAT_ASTC_8x5_UNORM_BLOCK,
DATA_FORMAT_ASTC_8x5_SRGB_BLOCK,
DATA_FORMAT_ASTC_8x6_UNORM_BLOCK,
DATA_FORMAT_ASTC_8x6_SRGB_BLOCK,
DATA_FORMAT_ASTC_8x8_UNORM_BLOCK,
DATA_FORMAT_ASTC_8x8_SRGB_BLOCK,
DATA_FORMAT_ASTC_10x5_UNORM_BLOCK,
DATA_FORMAT_ASTC_10x5_SRGB_BLOCK,
DATA_FORMAT_ASTC_10x6_UNORM_BLOCK,
DATA_FORMAT_ASTC_10x6_SRGB_BLOCK,
DATA_FORMAT_ASTC_10x8_UNORM_BLOCK,
DATA_FORMAT_ASTC_10x8_SRGB_BLOCK,
DATA_FORMAT_ASTC_10x10_UNORM_BLOCK,
DATA_FORMAT_ASTC_10x10_SRGB_BLOCK,
DATA_FORMAT_ASTC_12x10_UNORM_BLOCK,
DATA_FORMAT_ASTC_12x10_SRGB_BLOCK,
DATA_FORMAT_ASTC_12x12_UNORM_BLOCK,
DATA_FORMAT_ASTC_12x12_SRGB_BLOCK,
DATA_FORMAT_G8B8G8R8_422_UNORM,
DATA_FORMAT_B8G8R8G8_422_UNORM,
DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM,
DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM,
DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
DATA_FORMAT_R10X6_UNORM_PACK16,
DATA_FORMAT_R10X6G10X6_UNORM_2PACK16,
DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
DATA_FORMAT_R12X4_UNORM_PACK16,
DATA_FORMAT_R12X4G12X4_UNORM_2PACK16,
DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
DATA_FORMAT_G16B16G16R16_422_UNORM,
DATA_FORMAT_B16G16R16G16_422_UNORM,
DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM,
DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM,
DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
DATA_FORMAT_MAX,
};
enum CompareOperator {
COMPARE_OP_NEVER,
COMPARE_OP_LESS,
COMPARE_OP_EQUAL,
COMPARE_OP_LESS_OR_EQUAL,
COMPARE_OP_GREATER,
COMPARE_OP_NOT_EQUAL,
COMPARE_OP_GREATER_OR_EQUAL,
COMPARE_OP_ALWAYS,
COMPARE_OP_MAX
};
/*****************/
/**** TEXTURE ****/
/*****************/
enum TextureType {
TEXTURE_TYPE_1D,
TEXTURE_TYPE_2D,
TEXTURE_TYPE_3D,
TEXTURE_TYPE_CUBE,
TEXTURE_TYPE_1D_ARRAY,
TEXTURE_TYPE_2D_ARRAY,
TEXTURE_TYPE_CUBE_ARRAY,
TEXTURE_TYPE_MAX,
};
enum TextureSamples {
TEXTURE_SAMPLES_1,
TEXTURE_SAMPLES_2,
TEXTURE_SAMPLES_4,
TEXTURE_SAMPLES_8,
TEXTURE_SAMPLES_16,
TEXTURE_SAMPLES_32,
TEXTURE_SAMPLES_64,
TEXTURE_SAMPLES_MAX,
};
enum TextureUsageBits {
TEXTURE_USAGE_SAMPLING_BIT = (1 << 0),
TEXTURE_USAGE_COLOR_ATTACHMENT_BIT = (1 << 1),
TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = (1 << 2),
TEXTURE_USAGE_STORAGE_BIT = (1 << 3),
TEXTURE_USAGE_STORAGE_ATOMIC_BIT = (1 << 4),
TEXTURE_USAGE_CPU_READ_BIT = (1 << 5),
TEXTURE_USAGE_CAN_UPDATE_BIT = (1 << 6),
TEXTURE_USAGE_CAN_COPY_FROM_BIT = (1 << 7),
TEXTURE_USAGE_CAN_COPY_TO_BIT = (1 << 8),
TEXTURE_USAGE_INPUT_ATTACHMENT_BIT = (1 << 9),
TEXTURE_USAGE_VRS_ATTACHMENT_BIT = (1 << 10),
};
struct TextureFormat {
DataFormat format = DATA_FORMAT_R8_UNORM;
uint32_t width = 1;
uint32_t height = 1;
uint32_t depth = 1;
uint32_t array_layers = 1;
uint32_t mipmaps = 1;
TextureType texture_type = TEXTURE_TYPE_2D;
TextureSamples samples = TEXTURE_SAMPLES_1;
uint32_t usage_bits = 0;
Vector<DataFormat> shareable_formats;
bool is_resolve_buffer = false;
bool operator==(const TextureFormat &b) const {
if (format != b.format) {
return false;
} else if (width != b.width) {
return false;
} else if (height != b.height) {
return false;
} else if (depth != b.depth) {
return false;
} else if (array_layers != b.array_layers) {
return false;
} else if (mipmaps != b.mipmaps) {
return false;
} else if (texture_type != b.texture_type) {
return false;
} else if (samples != b.samples) {
return false;
} else if (usage_bits != b.usage_bits) {
return false;
} else if (shareable_formats != b.shareable_formats) {
return false;
} else {
return true;
}
}
};
enum TextureSwizzle {
TEXTURE_SWIZZLE_IDENTITY,
TEXTURE_SWIZZLE_ZERO,
TEXTURE_SWIZZLE_ONE,
TEXTURE_SWIZZLE_R,
TEXTURE_SWIZZLE_G,
TEXTURE_SWIZZLE_B,
TEXTURE_SWIZZLE_A,
TEXTURE_SWIZZLE_MAX
};
enum TextureSliceType {
TEXTURE_SLICE_2D,
TEXTURE_SLICE_CUBEMAP,
TEXTURE_SLICE_3D,
TEXTURE_SLICE_2D_ARRAY,
};
/*****************/
/**** SAMPLER ****/
/*****************/
enum SamplerFilter {
SAMPLER_FILTER_NEAREST,
SAMPLER_FILTER_LINEAR,
};
enum SamplerRepeatMode {
SAMPLER_REPEAT_MODE_REPEAT,
SAMPLER_REPEAT_MODE_MIRRORED_REPEAT,
SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE,
SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER,
SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE,
SAMPLER_REPEAT_MODE_MAX
};
enum SamplerBorderColor {
SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK,
SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK,
SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE,
SAMPLER_BORDER_COLOR_MAX
};
struct SamplerState {
SamplerFilter mag_filter = SAMPLER_FILTER_NEAREST;
SamplerFilter min_filter = SAMPLER_FILTER_NEAREST;
SamplerFilter mip_filter = SAMPLER_FILTER_NEAREST;
SamplerRepeatMode repeat_u = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
SamplerRepeatMode repeat_v = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
SamplerRepeatMode repeat_w = SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
float lod_bias = 0.0f;
bool use_anisotropy = false;
float anisotropy_max = 1.0f;
bool enable_compare = false;
CompareOperator compare_op = COMPARE_OP_ALWAYS;
float min_lod = 0.0f;
float max_lod = 1e20; // Something very large should do.
SamplerBorderColor border_color = SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
bool unnormalized_uvw = false;
};
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
enum IndexBufferFormat {
INDEX_BUFFER_FORMAT_UINT16,
INDEX_BUFFER_FORMAT_UINT32,
};
enum VertexFrequency {
VERTEX_FREQUENCY_VERTEX,
VERTEX_FREQUENCY_INSTANCE,
};
struct VertexAttribute {
uint32_t location = 0; // Shader location.
uint32_t offset = 0;
DataFormat format = DATA_FORMAT_MAX;
uint32_t stride = 0;
VertexFrequency frequency = VERTEX_FREQUENCY_VERTEX;
};
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
static const int32_t ATTACHMENT_UNUSED = -1;
/****************/
/**** SHADER ****/
/****************/
enum ShaderStage {
SHADER_STAGE_VERTEX,
SHADER_STAGE_FRAGMENT,
SHADER_STAGE_TESSELATION_CONTROL,
SHADER_STAGE_TESSELATION_EVALUATION,
SHADER_STAGE_COMPUTE,
SHADER_STAGE_MAX,
SHADER_STAGE_VERTEX_BIT = (1 << SHADER_STAGE_VERTEX),
SHADER_STAGE_FRAGMENT_BIT = (1 << SHADER_STAGE_FRAGMENT),
SHADER_STAGE_TESSELATION_CONTROL_BIT = (1 << SHADER_STAGE_TESSELATION_CONTROL),
SHADER_STAGE_TESSELATION_EVALUATION_BIT = (1 << SHADER_STAGE_TESSELATION_EVALUATION),
SHADER_STAGE_COMPUTE_BIT = (1 << SHADER_STAGE_COMPUTE),
};
struct ShaderStageSPIRVData {
ShaderStage shader_stage = SHADER_STAGE_MAX;
Vector<uint8_t> spirv;
};
/*********************/
/**** UNIFORM SET ****/
/*********************/
static const uint32_t MAX_UNIFORM_SETS = 16;
enum UniformType {
UNIFORM_TYPE_SAMPLER, // For sampling only (sampler GLSL type).
UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, // For sampling only, but includes a texture, (samplerXX GLSL type), first a sampler then a texture.
UNIFORM_TYPE_TEXTURE, // Only texture, (textureXX GLSL type).
UNIFORM_TYPE_IMAGE, // Storage image (imageXX GLSL type), for compute mostly.
UNIFORM_TYPE_TEXTURE_BUFFER, // Buffer texture (or TBO, textureBuffer type).
UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER, // Buffer texture with a sampler(or TBO, samplerBuffer type).
UNIFORM_TYPE_IMAGE_BUFFER, // Texel buffer, (imageBuffer type), for compute mostly.
UNIFORM_TYPE_UNIFORM_BUFFER, // Regular uniform buffer (or UBO).
UNIFORM_TYPE_STORAGE_BUFFER, // Storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly.
UNIFORM_TYPE_INPUT_ATTACHMENT, // Used for sub-pass read/write, for mobile mostly.
UNIFORM_TYPE_MAX
};
/******************/
/**** PIPELINE ****/
/******************/
enum PipelineSpecializationConstantType {
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL,
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT,
PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT,
};
struct PipelineSpecializationConstant {
PipelineSpecializationConstantType type = {};
uint32_t constant_id = 0xffffffff;
union {
uint32_t int_value = 0;
float float_value;
bool bool_value;
};
};
/*******************/
/**** RENDERING ****/
/*******************/
// ----- PIPELINE -----
enum RenderPrimitive {
RENDER_PRIMITIVE_POINTS,
RENDER_PRIMITIVE_LINES,
RENDER_PRIMITIVE_LINES_WITH_ADJACENCY,
RENDER_PRIMITIVE_LINESTRIPS,
RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY,
RENDER_PRIMITIVE_TRIANGLES,
RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY,
RENDER_PRIMITIVE_TRIANGLE_STRIPS,
RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY,
RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX,
RENDER_PRIMITIVE_TESSELATION_PATCH,
RENDER_PRIMITIVE_MAX
};
enum PolygonCullMode {
POLYGON_CULL_DISABLED,
POLYGON_CULL_FRONT,
POLYGON_CULL_BACK,
POLYGON_CULL_MAX
};
enum PolygonFrontFace {
POLYGON_FRONT_FACE_CLOCKWISE,
POLYGON_FRONT_FACE_COUNTER_CLOCKWISE,
};
enum StencilOperation {
STENCIL_OP_KEEP,
STENCIL_OP_ZERO,
STENCIL_OP_REPLACE,
STENCIL_OP_INCREMENT_AND_CLAMP,
STENCIL_OP_DECREMENT_AND_CLAMP,
STENCIL_OP_INVERT,
STENCIL_OP_INCREMENT_AND_WRAP,
STENCIL_OP_DECREMENT_AND_WRAP,
STENCIL_OP_MAX
};
enum LogicOperation {
LOGIC_OP_CLEAR,
LOGIC_OP_AND,
LOGIC_OP_AND_REVERSE,
LOGIC_OP_COPY,
LOGIC_OP_AND_INVERTED,
LOGIC_OP_NO_OP,
LOGIC_OP_XOR,
LOGIC_OP_OR,
LOGIC_OP_NOR,
LOGIC_OP_EQUIVALENT,
LOGIC_OP_INVERT,
LOGIC_OP_OR_REVERSE,
LOGIC_OP_COPY_INVERTED,
LOGIC_OP_OR_INVERTED,
LOGIC_OP_NAND,
LOGIC_OP_SET,
LOGIC_OP_MAX
};
enum BlendFactor {
BLEND_FACTOR_ZERO,
BLEND_FACTOR_ONE,
BLEND_FACTOR_SRC_COLOR,
BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
BLEND_FACTOR_DST_COLOR,
BLEND_FACTOR_ONE_MINUS_DST_COLOR,
BLEND_FACTOR_SRC_ALPHA,
BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
BLEND_FACTOR_DST_ALPHA,
BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
BLEND_FACTOR_CONSTANT_COLOR,
BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
BLEND_FACTOR_CONSTANT_ALPHA,
BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
BLEND_FACTOR_SRC_ALPHA_SATURATE,
BLEND_FACTOR_SRC1_COLOR,
BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
BLEND_FACTOR_SRC1_ALPHA,
BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA,
BLEND_FACTOR_MAX
};
enum BlendOperation {
BLEND_OP_ADD,
BLEND_OP_SUBTRACT,
BLEND_OP_REVERSE_SUBTRACT,
BLEND_OP_MINIMUM,
BLEND_OP_MAXIMUM, // Yes, this one is an actual operator.
BLEND_OP_MAX
};
struct PipelineRasterizationState {
bool enable_depth_clamp = false;
bool discard_primitives = false;
bool wireframe = false;
PolygonCullMode cull_mode = POLYGON_CULL_DISABLED;
PolygonFrontFace front_face = POLYGON_FRONT_FACE_CLOCKWISE;
bool depth_bias_enabled = false;
float depth_bias_constant_factor = 0.0f;
float depth_bias_clamp = 0.0f;
float depth_bias_slope_factor = 0.0f;
float line_width = 1.0f;
uint32_t patch_control_points = 1;
};
struct PipelineMultisampleState {
TextureSamples sample_count = TEXTURE_SAMPLES_1;
bool enable_sample_shading = false;
float min_sample_shading = 0.0f;
Vector<uint32_t> sample_mask;
bool enable_alpha_to_coverage = false;
bool enable_alpha_to_one = false;
};
struct PipelineDepthStencilState {
bool enable_depth_test = false;
bool enable_depth_write = false;
CompareOperator depth_compare_operator = COMPARE_OP_ALWAYS;
bool enable_depth_range = false;
float depth_range_min = 0;
float depth_range_max = 0;
bool enable_stencil = false;
struct StencilOperationState {
StencilOperation fail = STENCIL_OP_ZERO;
StencilOperation pass = STENCIL_OP_ZERO;
StencilOperation depth_fail = STENCIL_OP_ZERO;
CompareOperator compare = COMPARE_OP_ALWAYS;
uint32_t compare_mask = 0;
uint32_t write_mask = 0;
uint32_t reference = 0;
};
StencilOperationState front_op;
StencilOperationState back_op;
};
struct PipelineColorBlendState {
bool enable_logic_op = false;
LogicOperation logic_op = LOGIC_OP_CLEAR;
struct Attachment {
bool enable_blend = false;
BlendFactor src_color_blend_factor = BLEND_FACTOR_ZERO;
BlendFactor dst_color_blend_factor = BLEND_FACTOR_ZERO;
BlendOperation color_blend_op = BLEND_OP_ADD;
BlendFactor src_alpha_blend_factor = BLEND_FACTOR_ZERO;
BlendFactor dst_alpha_blend_factor = BLEND_FACTOR_ZERO;
BlendOperation alpha_blend_op = BLEND_OP_ADD;
bool write_r = true;
bool write_g = true;
bool write_b = true;
bool write_a = true;
};
static PipelineColorBlendState create_disabled(int p_attachments = 1) {
PipelineColorBlendState bs;
for (int i = 0; i < p_attachments; i++) {
bs.attachments.push_back(Attachment());
}
return bs;
}
static PipelineColorBlendState create_blend(int p_attachments = 1) {
PipelineColorBlendState bs;
for (int i = 0; i < p_attachments; i++) {
Attachment ba;
ba.enable_blend = true;
ba.src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA;
ba.dst_color_blend_factor = BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
ba.src_alpha_blend_factor = BLEND_FACTOR_SRC_ALPHA;
ba.dst_alpha_blend_factor = BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
bs.attachments.push_back(ba);
}
return bs;
}
Vector<Attachment> attachments; // One per render target texture.
Color blend_constant;
};
enum PipelineDynamicStateFlags {
DYNAMIC_STATE_LINE_WIDTH = (1 << 0),
DYNAMIC_STATE_DEPTH_BIAS = (1 << 1),
DYNAMIC_STATE_BLEND_CONSTANTS = (1 << 2),
DYNAMIC_STATE_DEPTH_BOUNDS = (1 << 3),
DYNAMIC_STATE_STENCIL_COMPARE_MASK = (1 << 4),
DYNAMIC_STATE_STENCIL_WRITE_MASK = (1 << 5),
DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6),
};
/**************/
/**** MISC ****/
/**************/
// This enum matches VkPhysicalDeviceType (except for `DEVICE_TYPE_MAX`).
// Unlike VkPhysicalDeviceType, DeviceType is exposed to the scripting API.
enum DeviceType {
DEVICE_TYPE_OTHER,
DEVICE_TYPE_INTEGRATED_GPU,
DEVICE_TYPE_DISCRETE_GPU,
DEVICE_TYPE_VIRTUAL_GPU,
DEVICE_TYPE_CPU,
DEVICE_TYPE_MAX
};
// Defined in an API-agnostic way.
// Some may not make sense for the underlying API; in that case, 0 is returned.
enum DriverResource {
DRIVER_RESOURCE_LOGICAL_DEVICE,
DRIVER_RESOURCE_PHYSICAL_DEVICE,
DRIVER_RESOURCE_TOPMOST_OBJECT,
DRIVER_RESOURCE_COMMAND_QUEUE,
DRIVER_RESOURCE_QUEUE_FAMILY,
DRIVER_RESOURCE_TEXTURE,
DRIVER_RESOURCE_TEXTURE_VIEW,
DRIVER_RESOURCE_TEXTURE_DATA_FORMAT,
DRIVER_RESOURCE_SAMPLER,
DRIVER_RESOURCE_UNIFORM_SET,
DRIVER_RESOURCE_BUFFER,
DRIVER_RESOURCE_COMPUTE_PIPELINE,
DRIVER_RESOURCE_RENDER_PIPELINE,
#ifndef DISABLE_DEPRECATED
DRIVER_RESOURCE_VULKAN_DEVICE = DRIVER_RESOURCE_LOGICAL_DEVICE,
DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE = DRIVER_RESOURCE_PHYSICAL_DEVICE,
DRIVER_RESOURCE_VULKAN_INSTANCE = DRIVER_RESOURCE_TOPMOST_OBJECT,
DRIVER_RESOURCE_VULKAN_QUEUE = DRIVER_RESOURCE_COMMAND_QUEUE,
DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX = DRIVER_RESOURCE_QUEUE_FAMILY,
DRIVER_RESOURCE_VULKAN_IMAGE = DRIVER_RESOURCE_TEXTURE,
DRIVER_RESOURCE_VULKAN_IMAGE_VIEW = DRIVER_RESOURCE_TEXTURE_VIEW,
DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT = DRIVER_RESOURCE_TEXTURE_DATA_FORMAT,
DRIVER_RESOURCE_VULKAN_SAMPLER = DRIVER_RESOURCE_SAMPLER,
DRIVER_RESOURCE_VULKAN_DESCRIPTOR_SET = DRIVER_RESOURCE_UNIFORM_SET,
DRIVER_RESOURCE_VULKAN_BUFFER = DRIVER_RESOURCE_BUFFER,
DRIVER_RESOURCE_VULKAN_COMPUTE_PIPELINE = DRIVER_RESOURCE_COMPUTE_PIPELINE,
DRIVER_RESOURCE_VULKAN_RENDER_PIPELINE = DRIVER_RESOURCE_RENDER_PIPELINE,
#endif
};
enum Limit {
LIMIT_MAX_BOUND_UNIFORM_SETS,
LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS,
LIMIT_MAX_TEXTURES_PER_UNIFORM_SET,
LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET,
LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET,
LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET,
LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET,
LIMIT_MAX_DRAW_INDEXED_INDEX,
LIMIT_MAX_FRAMEBUFFER_HEIGHT,
LIMIT_MAX_FRAMEBUFFER_WIDTH,
LIMIT_MAX_TEXTURE_ARRAY_LAYERS,
LIMIT_MAX_TEXTURE_SIZE_1D,
LIMIT_MAX_TEXTURE_SIZE_2D,
LIMIT_MAX_TEXTURE_SIZE_3D,
LIMIT_MAX_TEXTURE_SIZE_CUBE,
LIMIT_MAX_TEXTURES_PER_SHADER_STAGE,
LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE,
LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE,
LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE,
LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE,
LIMIT_MAX_PUSH_CONSTANT_SIZE,
LIMIT_MAX_UNIFORM_BUFFER_SIZE,
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET,
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES,
LIMIT_MAX_VERTEX_INPUT_BINDINGS,
LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE,
LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE,
LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X,
LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y,
LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z,
LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y,
LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z,
LIMIT_MAX_VIEWPORT_DIMENSIONS_X,
LIMIT_MAX_VIEWPORT_DIMENSIONS_Y,
LIMIT_SUBGROUP_SIZE,
LIMIT_SUBGROUP_MIN_SIZE,
LIMIT_SUBGROUP_MAX_SIZE,
LIMIT_SUBGROUP_IN_SHADERS, // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
LIMIT_SUBGROUP_OPERATIONS,
LIMIT_VRS_TEXEL_WIDTH,
LIMIT_VRS_TEXEL_HEIGHT,
};
enum Features {
SUPPORTS_MULTIVIEW,
SUPPORTS_FSR_HALF_FLOAT,
SUPPORTS_ATTACHMENT_VRS,
// If not supported, a fragment shader with only side effets (i.e., writes to buffers, but doesn't output to attachments), may be optimized down to no-op by the GPU driver.
SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS,
};
////////////////////////////////////////////
// PROTECTED STUFF
// Not exposed by RenderingDevice, but shared
// with RenderingDeviceDriver for convenience.
////////////////////////////////////////////
protected:
/*****************/
/**** GENERIC ****/
/*****************/
static const char *const FORMAT_NAMES[DATA_FORMAT_MAX];
/*****************/
/**** TEXTURE ****/
/*****************/
static const uint32_t MAX_IMAGE_FORMAT_PLANES = 2;
static const uint32_t TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX];
static uint32_t get_image_format_pixel_size(DataFormat p_format);
static void get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h);
uint32_t get_compressed_image_format_block_byte_size(DataFormat p_format);
static uint32_t get_compressed_image_format_pixel_rshift(DataFormat p_format);
static uint32_t get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw = nullptr, uint32_t *r_blockh = nullptr, uint32_t *r_depth = nullptr);
static uint32_t get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth);
static bool format_has_stencil(DataFormat p_format);
static uint32_t format_get_plane_count(DataFormat p_format);
/*****************/
/**** SAMPLER ****/
/*****************/
static const Color SAMPLER_BORDER_COLOR_VALUE[SAMPLER_BORDER_COLOR_MAX];
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
static uint32_t get_format_vertex_size(DataFormat p_format);
/****************/
/**** SHADER ****/
/****************/
static const char *SHADER_STAGE_NAMES[SHADER_STAGE_MAX];
struct ShaderUniform {
UniformType type = UniformType::UNIFORM_TYPE_MAX;
bool writable = false;
uint32_t binding = 0;
BitField<ShaderStage> stages;
uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements).
bool operator!=(const ShaderUniform &p_other) const {
return binding != p_other.binding || type != p_other.type || writable != p_other.writable || stages != p_other.stages || length != p_other.length;
}
bool operator<(const ShaderUniform &p_other) const {
if (binding != p_other.binding) {
return binding < p_other.binding;
}
if (type != p_other.type) {
return type < p_other.type;
}
if (writable != p_other.writable) {
return writable < p_other.writable;
}
if (stages != p_other.stages) {
return stages < p_other.stages;
}
if (length != p_other.length) {
return length < p_other.length;
}
return false;
}
};
struct ShaderSpecializationConstant : public PipelineSpecializationConstant {
BitField<ShaderStage> stages;
};
struct ShaderDescription {
uint64_t vertex_input_mask = 0;
uint32_t fragment_output_mask = 0;
bool is_compute = false;
uint32_t compute_local_size[3] = {};
uint32_t push_constant_size = 0;
Vector<Vector<ShaderUniform>> uniform_sets;
Vector<ShaderSpecializationConstant> specialization_constants;
};
struct ShaderReflection : public ShaderDescription {
BitField<ShaderStage> stages;
BitField<ShaderStage> push_constant_stages;
};
};
#endif // RENDERING_DEVICE_COMMONS_H

View File

@ -0,0 +1,380 @@
/**************************************************************************/
/* rendering_device_driver.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 "rendering_device_driver.h"
#include "thirdparty/spirv-reflect/spirv_reflect.h"
/****************/
/**** SHADER ****/
/****************/
Error RenderingDeviceDriver::_reflect_spirv(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection) {
r_reflection = {};
for (uint32_t i = 0; i < p_spirv.size(); i++) {
ShaderStage stage = p_spirv[i].shader_stage;
ShaderStage stage_flag = (ShaderStage)(1 << p_spirv[i].shader_stage);
if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) {
r_reflection.is_compute = true;
ERR_FAIL_COND_V_MSG(p_spirv.size() != 1, FAILED,
"Compute shaders can only receive one stage, dedicated to compute.");
}
ERR_FAIL_COND_V_MSG(r_reflection.stages.has_flag(stage_flag), FAILED,
"Stage " + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + " submitted more than once.");
{
SpvReflectShaderModule module;
const uint8_t *spirv = p_spirv[i].spirv.ptr();
SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spirv.size(), spirv, &module);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed parsing shader.");
if (r_reflection.is_compute) {
r_reflection.compute_local_size[0] = module.entry_points->local_size.x;
r_reflection.compute_local_size[1] = module.entry_points->local_size.y;
r_reflection.compute_local_size[2] = module.entry_points->local_size.z;
}
uint32_t binding_count = 0;
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings.");
if (binding_count > 0) {
// Parse bindings.
Vector<SpvReflectDescriptorBinding *> bindings;
bindings.resize(binding_count);
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw());
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
for (uint32_t j = 0; j < binding_count; j++) {
const SpvReflectDescriptorBinding &binding = *bindings[j];
ShaderUniform uniform;
bool need_array_dimensions = false;
bool need_block_size = false;
bool may_be_writable = false;
switch (binding.descriptor_type) {
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {
uniform.type = UNIFORM_TYPE_SAMPLER;
need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
uniform.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
uniform.type = UNIFORM_TYPE_TEXTURE;
need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
uniform.type = UNIFORM_TYPE_IMAGE;
need_array_dimensions = true;
may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
uniform.type = UNIFORM_TYPE_TEXTURE_BUFFER;
need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
uniform.type = UNIFORM_TYPE_IMAGE_BUFFER;
need_array_dimensions = true;
may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER;
need_block_size = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
uniform.type = UNIFORM_TYPE_STORAGE_BUFFER;
need_block_size = true;
may_be_writable = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
ERR_PRINT("Dynamic uniform buffer not supported.");
continue;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
ERR_PRINT("Dynamic storage buffer not supported.");
continue;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
uniform.type = UNIFORM_TYPE_INPUT_ATTACHMENT;
need_array_dimensions = true;
} break;
case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
ERR_PRINT("Acceleration structure not supported.");
continue;
} break;
}
if (need_array_dimensions) {
if (binding.array.dims_count == 0) {
uniform.length = 1;
} else {
for (uint32_t k = 0; k < binding.array.dims_count; k++) {
if (k == 0) {
uniform.length = binding.array.dims[0];
} else {
uniform.length *= binding.array.dims[k];
}
}
}
} else if (need_block_size) {
uniform.length = binding.block.size;
} else {
uniform.length = 0;
}
if (may_be_writable) {
uniform.writable = !(binding.type_description->decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
} else {
uniform.writable = false;
}
uniform.binding = binding.binding;
uint32_t set = binding.set;
ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, FAILED,
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").");
if (set < (uint32_t)r_reflection.uniform_sets.size()) {
// Check if this already exists.
bool exists = false;
for (int k = 0; k < r_reflection.uniform_sets[set].size(); k++) {
if (r_reflection.uniform_sets[set][k].binding == uniform.binding) {
// Already exists, verify that it's the same type.
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].type != uniform.type, FAILED,
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform type.");
// Also, verify that it's the same size.
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].length != uniform.length, FAILED,
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform size.");
// Also, verify that it has the same writability.
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].writable != uniform.writable, FAILED,
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different writability.");
// Just append stage mask and return.
r_reflection.uniform_sets.write[set].write[k].stages.set_flag(stage_flag);
exists = true;
break;
}
}
if (exists) {
continue; // Merged.
}
}
uniform.stages.set_flag(stage_flag);
if (set >= (uint32_t)r_reflection.uniform_sets.size()) {
r_reflection.uniform_sets.resize(set + 1);
}
r_reflection.uniform_sets.write[set].push_back(uniform);
}
}
{
// Specialization constants.
uint32_t sc_count = 0;
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants.");
if (sc_count) {
Vector<SpvReflectSpecializationConstant *> spec_constants;
spec_constants.resize(sc_count);
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants.");
for (uint32_t j = 0; j < sc_count; j++) {
int32_t existing = -1;
ShaderSpecializationConstant sconst;
SpvReflectSpecializationConstant *spc = spec_constants[j];
sconst.constant_id = spc->constant_id;
sconst.int_value = 0; // Clear previous value JIC.
switch (spc->constant_type) {
case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
sconst.bool_value = spc->default_value.int_bool_value != 0;
} break;
case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
sconst.int_value = spc->default_value.int_bool_value;
} break;
case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
sconst.float_value = spc->default_value.float_value;
} break;
}
sconst.stages.set_flag(stage_flag);
for (int k = 0; k < r_reflection.specialization_constants.size(); k++) {
if (r_reflection.specialization_constants[k].constant_id == sconst.constant_id) {
ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ.");
ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].int_value != sconst.int_value, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ.");
existing = k;
break;
}
}
if (existing > 0) {
r_reflection.specialization_constants.write[existing].stages.set_flag(stage_flag);
} else {
r_reflection.specialization_constants.push_back(sconst);
}
}
}
}
if (stage == SHADER_STAGE_VERTEX) {
uint32_t iv_count = 0;
result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating input variables.");
if (iv_count) {
Vector<SpvReflectInterfaceVariable *> input_vars;
input_vars.resize(iv_count);
result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw());
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining input variables.");
for (uint32_t j = 0; j < iv_count; j++) {
if (input_vars[j] && input_vars[j]->decoration_flags == 0) { // Regular input.
r_reflection.vertex_input_mask |= (((uint64_t)1) << input_vars[j]->location);
}
}
}
}
if (stage == SHADER_STAGE_FRAGMENT) {
uint32_t ov_count = 0;
result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating output variables.");
if (ov_count) {
Vector<SpvReflectInterfaceVariable *> output_vars;
output_vars.resize(ov_count);
result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw());
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining output variables.");
for (uint32_t j = 0; j < ov_count; j++) {
const SpvReflectInterfaceVariable *refvar = output_vars[j];
if (refvar != nullptr && refvar->built_in != SpvBuiltInFragDepth) {
r_reflection.fragment_output_mask |= 1 << refvar->location;
}
}
}
}
uint32_t pc_count = 0;
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating push constants.");
if (pc_count) {
ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages.");
Vector<SpvReflectBlockVariable *> pconstants;
pconstants.resize(pc_count);
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw());
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining push constants.");
#if 0
if (pconstants[0] == nullptr) {
Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE);
f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t));
}
#endif
ERR_FAIL_COND_V_MSG(r_reflection.push_constant_size && r_reflection.push_constant_size != pconstants[0]->size, FAILED,
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages.");
r_reflection.push_constant_size = pconstants[0]->size;
r_reflection.push_constant_stages.set_flag(stage_flag);
//print_line("Stage: " + String(SHADER_STAGE_NAMES[stage]) + " push constant of size=" + itos(push_constant.push_constant_size));
}
// Destroy the reflection data when no longer required.
spvReflectDestroyShaderModule(&module);
}
r_reflection.stages.set_flag(stage_flag);
}
return OK;
}
/**************/
/**** MISC ****/
/**************/
uint64_t RenderingDeviceDriver::api_trait_get(ApiTrait p_trait) {
// Sensible canonical defaults.
switch (p_trait) {
case API_TRAIT_HONORS_PIPELINE_BARRIERS:
return 1;
case API_TRAIT_SHADER_CHANGE_INVALIDATION:
return SHADER_CHANGE_INVALIDATION_ALL_BOUND_UNIFORM_SETS;
case API_TRAIT_TEXTURE_TRANSFER_ALIGNMENT:
return 1;
case API_TRAIT_TEXTURE_DATA_ROW_PITCH_STEP:
return 1;
case API_TRAIT_SECONDARY_VIEWPORT_SCISSOR:
return 1;
default:
ERR_FAIL_V(0);
}
}
/******************/
RenderingDeviceDriver::~RenderingDeviceDriver() {}

View File

@ -0,0 +1,687 @@
/**************************************************************************/
/* rendering_device_driver.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. */
/**************************************************************************/
#ifndef RENDERING_DEVICE_DRIVER_H
#define RENDERING_DEVICE_DRIVER_H
// ***********************************************************************************
// RenderingDeviceDriver - Design principles
// -----------------------------------------
// - Very little validation is done, and normally only in dev or debug builds.
// - Error reporting is generally simple: returning an id of 0 or a false boolean.
// - Certain enums/constants/structs follow Vulkan values/layout. That makes things easier for RDDVulkan (it asserts compatibility).
// - We allocate as little as possible in functions expected to be quick (a counterexample is loading/saving shaders) and use alloca() whenever suitable.
// - We try to back opaque ids with the native ones or memory addresses.
// - When using bookkeeping structures because the actual API id of a resource is not enough, we use a PagedAllocator.
// - Every struct has default initializers.
// - Using VectorView to take array-like arguments. Vector<uint8_t> is an exception (an indiom for "BLOB").
// - If a driver needs some higher-level information (the kind of info RenderingDevice keeps), it shall store a copy of what it needs.
// There's no backwards communication from the driver to query data from RenderingDevice.
// ***********************************************************************************
#include "core/object/object.h"
#include "core/variant/type_info.h"
#include "servers/display_server.h"
#include "servers/rendering/rendering_device_commons.h"
#include <algorithm>
class ApiContextRD;
// This may one day be used in Godot for interoperability between C arrays, Vector and LocalVector.
// (See https://github.com/godotengine/godot-proposals/issues/5144.)
template <class T>
class VectorView {
const T *_ptr = nullptr;
const uint32_t _size = 0;
public:
const T &operator[](uint32_t p_index) {
DEV_ASSERT(p_index < _size);
return _ptr[p_index];
}
_ALWAYS_INLINE_ const T *ptr() const { return _ptr; }
_ALWAYS_INLINE_ uint32_t size() const { return _size; }
VectorView() = default;
VectorView(const T &p_ptr) :
// With this one you can pass a single element very conveniently!
_ptr(&p_ptr),
_size(1) {}
VectorView(const T *p_ptr, uint32_t p_size) :
_ptr(p_ptr), _size(p_size) {}
VectorView(const Vector<T> &p_lv) :
_ptr(p_lv.ptr()), _size(p_lv.size()) {}
VectorView(const LocalVector<T> &p_lv) :
_ptr(p_lv.ptr()), _size(p_lv.size()) {}
};
// These utilities help drivers avoid allocations.
#define ALLOCA(m_size) ((m_size != 0) ? alloca(m_size) : nullptr)
#define ALLOCA_ARRAY(m_type, m_count) ((m_type *)ALLOCA(sizeof(m_type) * (m_count)))
#define ALLOCA_SINGLE(m_type) ALLOCA_ARRAY(m_type, 1)
// This helps forwarding certain arrays to the API with confidence.
#define ARRAYS_COMPATIBLE(m_type_a, m_type_b) (sizeof(m_type_a) == sizeof(m_type_b) && alignof(m_type_a) == alignof(m_type_b))
// This is used when you also need to ensure structured types are compatible field-by-field.
// TODO: The fieldwise check is unimplemented, but still this one is useful, as a strong annotation about the needs.
#define ARRAYS_COMPATIBLE_FIELDWISE(m_type_a, m_type_b) ARRAYS_COMPATIBLE(m_type_a, m_type_b)
// Another utility, to make it easy to compare members of different enums, which is not fine with some compilers.
#define ENUM_MEMBERS_EQUAL(m_a, m_b) ((int64_t)m_a == (int64_t)m_b)
// This helps using a single paged allocator for many resource types.
template <class... RESOURCE_TYPES>
struct VersatileResourceTemplate {
static constexpr size_t RESOURCE_SIZES[] = { sizeof(RESOURCE_TYPES)... };
static constexpr size_t MAX_RESOURCE_SIZE = std::max_element(RESOURCE_SIZES, RESOURCE_SIZES + sizeof...(RESOURCE_TYPES))[0];
uint8_t data[MAX_RESOURCE_SIZE];
template <class T>
static T *allocate(PagedAllocator<VersatileResourceTemplate> &p_allocator) {
T *obj = (T *)p_allocator.alloc();
*obj = T();
return obj;
}
template <class T>
static void free(PagedAllocator<VersatileResourceTemplate> &p_allocator, T *p_object) {
p_object->~T();
p_allocator.free((VersatileResourceTemplate *)p_object);
}
};
class RenderingDeviceDriver : public RenderingDeviceCommons {
public:
struct ID {
size_t id = 0;
_ALWAYS_INLINE_ ID() = default;
_ALWAYS_INLINE_ ID(size_t p_id) :
id(p_id) {}
};
#define DEFINE_ID(m_name) \
struct m_name##ID : public ID { \
_ALWAYS_INLINE_ operator bool() const { return id != 0; } \
_ALWAYS_INLINE_ m_name##ID &operator=(m_name##ID p_other) { \
id = p_other.id; \
return *this; \
} \
_ALWAYS_INLINE_ bool operator<(const m_name##ID &p_other) const { return id < p_other.id; } \
_ALWAYS_INLINE_ m_name##ID(const m_name##ID &p_other) : ID(p_other.id) {} \
_ALWAYS_INLINE_ explicit m_name##ID(uint64_t p_int) : ID(p_int) {} \
_ALWAYS_INLINE_ explicit m_name##ID(void *p_ptr) : ID((size_t)p_ptr) {} \
_ALWAYS_INLINE_ m_name##ID() = default; \
}; \
/* Ensure type-punnable to pointer. Makes some things easier.*/ \
static_assert(sizeof(m_name##ID) == sizeof(void *));
// Id types declared before anything else to prevent cyclic dependencies between the different concerns.
DEFINE_ID(Buffer);
DEFINE_ID(Texture);
DEFINE_ID(Sampler);
DEFINE_ID(VertexFormat);
DEFINE_ID(CommandPool);
DEFINE_ID(CommandBuffer);
DEFINE_ID(Framebuffer);
DEFINE_ID(Shader);
DEFINE_ID(UniformSet);
DEFINE_ID(Pipeline);
DEFINE_ID(RenderPass);
DEFINE_ID(QueryPool);
/****************/
/**** MEMORY ****/
/****************/
enum MemoryAllocationType {
MEMORY_ALLOCATION_TYPE_CPU, // For images, CPU allocation also means linear, GPU is tiling optimal.
MEMORY_ALLOCATION_TYPE_GPU,
};
/*****************/
/**** BUFFERS ****/
/*****************/
enum BufferUsageBits {
BUFFER_USAGE_TRANSFER_FROM_BIT = (1 << 0),
BUFFER_USAGE_TRANSFER_TO_BIT = (1 << 1),
BUFFER_USAGE_TEXEL_BIT = (1 << 2),
BUFFER_USAGE_UNIFORM_BIT = (1 << 4),
BUFFER_USAGE_STORAGE_BIT = (1 << 5),
BUFFER_USAGE_INDEX_BIT = (1 << 6),
BUFFER_USAGE_VERTEX_BIT = (1 << 7),
BUFFER_USAGE_INDIRECT_BIT = (1 << 8),
};
virtual BufferID buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type) = 0;
// Only for a buffer with BUFFER_USAGE_TEXEL_BIT.
virtual bool buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) = 0;
virtual void buffer_free(BufferID p_buffer) = 0;
virtual uint64_t buffer_get_allocation_size(BufferID p_buffer) = 0;
virtual uint8_t *buffer_map(BufferID p_buffer) = 0;
virtual void buffer_unmap(BufferID p_buffer) = 0;
/*****************/
/**** TEXTURE ****/
/*****************/
struct TextureView {
DataFormat format = DATA_FORMAT_MAX;
TextureSwizzle swizzle_r = TEXTURE_SWIZZLE_R;
TextureSwizzle swizzle_g = TEXTURE_SWIZZLE_G;
TextureSwizzle swizzle_b = TEXTURE_SWIZZLE_B;
TextureSwizzle swizzle_a = TEXTURE_SWIZZLE_A;
};
enum TextureLayout {
TEXTURE_LAYOUT_UNDEFINED,
TEXTURE_LAYOUT_GENERAL,
TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
TEXTURE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
TEXTURE_LAYOUT_TRANSFER_SRC_OPTIMAL,
TEXTURE_LAYOUT_TRANSFER_DST_OPTIMAL,
TEXTURE_LAYOUT_PREINITIALIZED,
TEXTURE_LAYOUT_VRS_ATTACHMENT_OPTIMAL = 1000164003,
};
enum TextureAspect {
TEXTURE_ASPECT_COLOR = 0,
TEXTURE_ASPECT_DEPTH = 1,
TEXTURE_ASPECT_STENCIL = 2,
TEXTURE_ASPECT_MAX
};
enum TextureAspectBits {
TEXTURE_ASPECT_COLOR_BIT = (1 << TEXTURE_ASPECT_COLOR),
TEXTURE_ASPECT_DEPTH_BIT = (1 << TEXTURE_ASPECT_DEPTH),
TEXTURE_ASPECT_STENCIL_BIT = (1 << TEXTURE_ASPECT_STENCIL),
};
struct TextureSubresource {
TextureAspect aspect = TEXTURE_ASPECT_COLOR;
uint32_t layer = 0;
uint32_t mipmap = 0;
};
struct TextureSubresourceLayers {
BitField<TextureAspectBits> aspect;
uint32_t mipmap = 0;
uint32_t base_layer = 0;
uint32_t layer_count = 0;
};
struct TextureSubresourceRange {
BitField<TextureAspectBits> aspect;
uint32_t base_mipmap = 0;
uint32_t mipmap_count = 0;
uint32_t base_layer = 0;
uint32_t layer_count = 0;
};
struct TextureCopyableLayout {
uint64_t offset = 0;
uint64_t size = 0;
uint64_t row_pitch = 0;
uint64_t depth_pitch = 0;
uint64_t layer_pitch = 0;
};
virtual TextureID texture_create(const TextureFormat &p_format, const TextureView &p_view) = 0;
virtual TextureID texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil) = 0;
// texture_create_shared_*() can only use original, non-view textures as original. RenderingDevice is responsible for ensuring that.
virtual TextureID texture_create_shared(TextureID p_original_texture, const TextureView &p_view) = 0;
virtual TextureID texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) = 0;
virtual void texture_free(TextureID p_texture) = 0;
virtual uint64_t texture_get_allocation_size(TextureID p_texture) = 0;
virtual void texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) = 0;
virtual uint8_t *texture_map(TextureID p_texture, const TextureSubresource &p_subresource) = 0;
virtual void texture_unmap(TextureID p_texture) = 0;
virtual BitField<TextureUsageBits> texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) = 0;
/*****************/
/**** SAMPLER ****/
/*****************/
virtual SamplerID sampler_create(const SamplerState &p_state) = 0;
virtual void sampler_free(SamplerID p_sampler) = 0;
virtual bool sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) = 0;
/**********************/
/**** VERTEX ARRAY ****/
/**********************/
virtual VertexFormatID vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) = 0;
virtual void vertex_format_free(VertexFormatID p_vertex_format) = 0;
/******************/
/**** BARRIERS ****/
/******************/
enum PipelineStageBits {
PIPELINE_STAGE_TOP_OF_PIPE_BIT = (1 << 0),
PIPELINE_STAGE_DRAW_INDIRECT_BIT = (1 << 1),
PIPELINE_STAGE_VERTEX_INPUT_BIT = (1 << 2),
PIPELINE_STAGE_VERTEX_SHADER_BIT = (1 << 3),
PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = (1 << 4),
PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = (1 << 5),
PIPELINE_STAGE_GEOMETRY_SHADER_BIT = (1 << 6),
PIPELINE_STAGE_FRAGMENT_SHADER_BIT = (1 << 7),
PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = (1 << 8),
PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = (1 << 9),
PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = (1 << 10),
PIPELINE_STAGE_COMPUTE_SHADER_BIT = (1 << 11),
PIPELINE_STAGE_TRANSFER_BIT = (1 << 12),
PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = (1 << 13),
PIPELINE_STAGE_ALL_GRAPHICS_BIT = (1 << 15),
PIPELINE_STAGE_ALL_COMMANDS_BIT = (1 << 16),
};
enum BarrierAccessBits {
BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT = (1 << 0),
BARRIER_ACCESS_INDEX_READ_BIT = (1 << 1),
BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = (1 << 2),
BARRIER_ACCESS_UNIFORM_READ_BIT = (1 << 3),
BARRIER_ACCESS_INPUT_ATTACHMENT_READ_BIT = (1 << 4),
BARRIER_ACCESS_SHADER_READ_BIT = (1 << 5),
BARRIER_ACCESS_SHADER_WRITE_BIT = (1 << 6),
BARRIER_ACCESS_COLOR_ATTACHMENT_READ_BIT = (1 << 7),
BARRIER_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = (1 << 8),
BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = (1 << 9),
BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = (1 << 10),
BARRIER_ACCESS_TRANSFER_READ_BIT = (1 << 11),
BARRIER_ACCESS_TRANSFER_WRITE_BIT = (1 << 12),
BARRIER_ACCESS_HOST_READ_BIT = (1 << 13),
BARRIER_ACCESS_HOST_WRITE_BIT = (1 << 14),
BARRIER_ACCESS_MEMORY_READ_BIT = (1 << 15),
BARRIER_ACCESS_MEMORY_WRITE_BIT = (1 << 16),
BARRIER_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT = (1 << 23),
};
struct MemoryBarrier {
BitField<BarrierAccessBits> src_access;
BitField<BarrierAccessBits> dst_access;
};
struct BufferBarrier {
BufferID buffer;
BitField<BarrierAccessBits> src_access;
BitField<BarrierAccessBits> dst_access;
uint64_t offset = 0;
uint64_t size = 0;
};
struct TextureBarrier {
TextureID texture;
BitField<BarrierAccessBits> src_access;
BitField<BarrierAccessBits> dst_access;
TextureLayout prev_layout = TEXTURE_LAYOUT_UNDEFINED;
TextureLayout next_layout = TEXTURE_LAYOUT_UNDEFINED;
TextureSubresourceRange subresources;
};
virtual void command_pipeline_barrier(
CommandBufferID p_cmd_buffer,
BitField<PipelineStageBits> p_src_stages,
BitField<PipelineStageBits> p_dst_stages,
VectorView<MemoryBarrier> p_memory_barriers,
VectorView<BufferBarrier> p_buffer_barriers,
VectorView<TextureBarrier> p_texture_barriers) = 0;
/*************************/
/**** COMMAND BUFFERS ****/
/*************************/
// ----- POOL -----
enum CommandBufferType {
COMMAND_BUFFER_TYPE_PRIMARY,
COMMAND_BUFFER_TYPE_SECONDARY,
};
virtual CommandPoolID command_pool_create(CommandBufferType p_cmd_buffer_type) = 0;
virtual void command_pool_free(CommandPoolID p_cmd_pool) = 0;
// ----- BUFFER -----
virtual CommandBufferID command_buffer_create(CommandBufferType p_cmd_buffer_type, CommandPoolID p_cmd_pool) = 0;
virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) = 0;
virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) = 0;
virtual void command_buffer_end(CommandBufferID p_cmd_buffer) = 0;
virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) = 0;
/*********************/
/**** FRAMEBUFFER ****/
/*********************/
virtual FramebufferID framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) = 0;
virtual void framebuffer_free(FramebufferID p_framebuffer) = 0;
/****************/
/**** SHADER ****/
/****************/
virtual String shader_get_binary_cache_key() = 0;
virtual Vector<uint8_t> shader_compile_binary_from_spirv(VectorView<ShaderStageSPIRVData> p_spirv, const String &p_shader_name) = 0;
virtual ShaderID shader_create_from_bytecode(const Vector<uint8_t> &p_shader_binary, ShaderDescription &r_shader_desc, String &r_name) = 0;
// Only meaningful if API_TRAIT_SHADER_CHANGE_INVALIDATION is SHADER_CHANGE_INVALIDATION_ALL_OR_NONE_ACCORDING_TO_LAYOUT_HASH.
virtual uint32_t shader_get_layout_hash(ShaderID p_shader) { return 0; }
virtual void shader_free(ShaderID p_shader) = 0;
protected:
// An optional service to implementations.
Error _reflect_spirv(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection);
public:
/*********************/
/**** UNIFORM SET ****/
/*********************/
struct BoundUniform {
UniformType type = UNIFORM_TYPE_MAX;
uint32_t binding = 0xffffffff; // Binding index as specified in shader.
LocalVector<ID> ids;
};
virtual UniformSetID uniform_set_create(VectorView<BoundUniform> p_uniforms, ShaderID p_shader, uint32_t p_set_index) = 0;
virtual void uniform_set_free(UniformSetID p_uniform_set) = 0;
// ----- COMMANDS -----
virtual void command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
/******************/
/**** TRANSFER ****/
/******************/
struct BufferCopyRegion {
uint64_t src_offset = 0;
uint64_t dst_offset = 0;
uint64_t size = 0;
};
struct TextureCopyRegion {
TextureSubresourceLayers src_subresources;
Vector3i src_offset;
TextureSubresourceLayers dst_subresources;
Vector3i dst_offset;
Vector3i size;
};
struct BufferTextureCopyRegion {
uint64_t buffer_offset = 0;
TextureSubresourceLayers texture_subresources;
Vector3i texture_offset;
Vector3i texture_region_size;
};
virtual void command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) = 0;
virtual void command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView<BufferCopyRegion> p_regions) = 0;
virtual void command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<TextureCopyRegion> p_regions) = 0;
virtual void command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) = 0;
virtual void command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) = 0;
virtual void command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<BufferTextureCopyRegion> p_regions) = 0;
virtual void command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView<BufferTextureCopyRegion> p_regions) = 0;
/******************/
/**** PIPELINE ****/
/******************/
virtual void pipeline_free(PipelineID p_pipeline) = 0;
// ----- BINDING -----
virtual void command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_first_index, VectorView<uint32_t> p_data) = 0;
// ----- CACHE -----
virtual bool pipeline_cache_create(const Vector<uint8_t> &p_data) = 0;
virtual void pipeline_cache_free() = 0;
virtual size_t pipeline_cache_query_size() = 0;
virtual Vector<uint8_t> pipeline_cache_serialize() = 0;
/*******************/
/**** RENDERING ****/
/*******************/
// ----- SUBPASS -----
enum AttachmentLoadOp {
ATTACHMENT_LOAD_OP_LOAD = 0,
ATTACHMENT_LOAD_OP_CLEAR = 1,
ATTACHMENT_LOAD_OP_DONT_CARE = 2,
};
enum AttachmentStoreOp {
ATTACHMENT_STORE_OP_STORE = 0,
ATTACHMENT_STORE_OP_DONT_CARE = 1,
};
struct Attachment {
DataFormat format = DATA_FORMAT_MAX;
TextureSamples samples = TEXTURE_SAMPLES_MAX;
AttachmentLoadOp load_op = ATTACHMENT_LOAD_OP_DONT_CARE;
AttachmentStoreOp store_op = ATTACHMENT_STORE_OP_DONT_CARE;
AttachmentLoadOp stencil_load_op = ATTACHMENT_LOAD_OP_DONT_CARE;
AttachmentStoreOp stencil_store_op = ATTACHMENT_STORE_OP_DONT_CARE;
TextureLayout initial_layout = TEXTURE_LAYOUT_UNDEFINED;
TextureLayout final_layout = TEXTURE_LAYOUT_UNDEFINED;
};
struct AttachmentReference {
static const uint32_t UNUSED = 0xffffffff;
uint32_t attachment = UNUSED;
TextureLayout layout = TEXTURE_LAYOUT_UNDEFINED;
BitField<TextureAspectBits> aspect;
};
struct Subpass {
LocalVector<AttachmentReference> input_references;
LocalVector<AttachmentReference> color_references;
AttachmentReference depth_stencil_reference;
LocalVector<AttachmentReference> resolve_references;
LocalVector<uint32_t> preserve_attachments;
AttachmentReference vrs_reference;
};
struct SubpassDependency {
uint32_t src_subpass = 0xffffffff;
uint32_t dst_subpass = 0xffffffff;
BitField<PipelineStageBits> src_stages;
BitField<PipelineStageBits> dst_stages;
BitField<BarrierAccessBits> src_access;
BitField<BarrierAccessBits> dst_access;
};
virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count) = 0;
virtual void render_pass_free(RenderPassID p_render_pass) = 0;
// ----- COMMANDS -----
union RenderPassClearValue {
Color color = {};
struct {
float depth;
uint32_t stencil;
};
};
struct AttachmentClear {
BitField<TextureAspectBits> aspect;
uint32_t color_attachment = 0xffffffff;
RenderPassClearValue value;
};
virtual void command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView<RenderPassClearValue> p_clear_values) = 0;
virtual void command_end_render_pass(CommandBufferID p_cmd_buffer) = 0;
virtual void command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) = 0;
virtual void command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_viewports) = 0;
virtual void command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_scissors) = 0;
virtual void command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView<AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) = 0;
// Binding.
virtual void command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0;
virtual void command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
// Drawing.
virtual void command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) = 0;
virtual void command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) = 0;
virtual void command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) = 0;
virtual void command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) = 0;
virtual void command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) = 0;
virtual void command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) = 0;
// Buffer binding.
virtual void command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) = 0;
virtual void command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) = 0;
// Dynamic state.
virtual void command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) = 0;
virtual void command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) = 0;
// ----- PIPELINE -----
virtual PipelineID render_pipeline_create(
ShaderID p_shader,
VertexFormatID p_vertex_format,
RenderPrimitive p_render_primitive,
PipelineRasterizationState p_rasterization_state,
PipelineMultisampleState p_multisample_state,
PipelineDepthStencilState p_depth_stencil_state,
PipelineColorBlendState p_blend_state,
VectorView<int32_t> p_color_attachments,
BitField<PipelineDynamicStateFlags> p_dynamic_state,
RenderPassID p_render_pass,
uint32_t p_render_subpass,
VectorView<PipelineSpecializationConstant> p_specialization_constants) = 0;
/*****************/
/**** COMPUTE ****/
/*****************/
// ----- COMMANDS -----
// Binding.
virtual void command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) = 0;
virtual void command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) = 0;
// Dispatching.
virtual void command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0;
virtual void command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) = 0;
// ----- PIPELINE -----
virtual PipelineID compute_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) = 0;
/*****************/
/**** QUERIES ****/
/*****************/
// ----- TIMESTAMP -----
// Basic.
virtual QueryPoolID timestamp_query_pool_create(uint32_t p_query_count) = 0;
virtual void timestamp_query_pool_free(QueryPoolID p_pool_id) = 0;
virtual void timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) = 0;
virtual uint64_t timestamp_query_result_to_time(uint64_t p_result) = 0;
// Commands.
virtual void command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) = 0;
virtual void command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) = 0;
/****************/
/**** SCREEN ****/
/****************/
virtual DataFormat screen_get_format() = 0;
/********************/
/**** SUBMISSION ****/
/********************/
virtual void begin_segment(CommandBufferID p_cmd_buffer, uint32_t p_frame_index, uint32_t p_frames_drawn) = 0;
virtual void end_segment() = 0;
/**************/
/**** MISC ****/
/**************/
enum ObjectType {
OBJECT_TYPE_TEXTURE,
OBJECT_TYPE_SAMPLER,
OBJECT_TYPE_BUFFER,
OBJECT_TYPE_SHADER,
OBJECT_TYPE_UNIFORM_SET,
OBJECT_TYPE_PIPELINE,
};
struct MultiviewCapabilities {
bool is_supported = false;
bool geometry_shader_is_supported = false;
bool tessellation_shader_is_supported = false;
uint32_t max_view_count = 0;
uint32_t max_instance_count = 0;
};
enum ApiTrait {
API_TRAIT_HONORS_PIPELINE_BARRIERS,
API_TRAIT_SHADER_CHANGE_INVALIDATION,
API_TRAIT_TEXTURE_TRANSFER_ALIGNMENT,
API_TRAIT_TEXTURE_DATA_ROW_PITCH_STEP,
API_TRAIT_SECONDARY_VIEWPORT_SCISSOR,
};
enum ShaderChangeInvalidation {
SHADER_CHANGE_INVALIDATION_ALL_BOUND_UNIFORM_SETS,
// What Vulkan does.
SHADER_CHANGE_INVALIDATION_INCOMPATIBLE_SETS_PLUS_CASCADE,
// What D3D12 does.
SHADER_CHANGE_INVALIDATION_ALL_OR_NONE_ACCORDING_TO_LAYOUT_HASH,
};
virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) = 0;
virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) = 0;
virtual uint64_t get_total_memory_used() = 0;
virtual uint64_t limit_get(Limit p_limit) = 0;
virtual uint64_t api_trait_get(ApiTrait p_trait);
virtual bool has_feature(Features p_feature) = 0;
virtual const MultiviewCapabilities &get_multiview_capabilities() = 0;
/******************/
virtual ~RenderingDeviceDriver();
};
using RDD = RenderingDeviceDriver;
#endif // RENDERING_DEVICE_DRIVER_H

11
thirdparty/README.md vendored
View File

@ -132,18 +132,27 @@ Files extracted from upstream source:
- `include/D3D12MemAlloc.h`
- `LICENSE.txt`, `NOTICES.txt`
Important: Some files have Godot-made changes for use with MinGW.
They are marked with `/* GODOT start */` and `/* GODOT end */`
comments.
## directx_headers
- Upstream: https://github.com/microsoft/DirectX-Headers
- Version: 1.606.3 (fd329244e62201bf959331d28514928fc1d45005, 2022)
- Version: 1.611.1 (48f23952bc08a6dce0727339c07cedbc4797356c, 2023)
- License: MIT
Files extracted from upstream source:
- `include/directx/*.h`
- `include/dxguids/*.h`
- `LICENSE`
Important: Some files have Godot-made changes for use with MinGW.
They are marked with `/* GODOT start */` and `/* GODOT end */`
comments.
## doctest

View File

@ -33,6 +33,14 @@
#include <shared_mutex>
#endif
/* GODOT start */
#if !defined(_MSC_VER)
#include <guiddef.h>
#include <dxguids.h>
#endif
/* GODOT end */
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
@ -8178,7 +8186,15 @@ HRESULT AllocatorPimpl::UpdateD3D12Budget()
D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC& resourceDesc) const
{
/* GODOT start */
#if defined(_MSC_VER) || !defined(_WIN32)
return m_Device->GetResourceAllocationInfo(0, 1, &resourceDesc);
#else
D3D12_RESOURCE_ALLOCATION_INFO ret;
m_Device->GetResourceAllocationInfo(&ret, 0, 1, &resourceDesc);
return ret;
#endif
/* GODOT end */
}
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
@ -8186,7 +8202,15 @@ D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(c
{
D3D12MA_ASSERT(m_Device8 != NULL);
D3D12_RESOURCE_ALLOCATION_INFO1 info1Unused;
/* GODOT start */
#if defined(_MSC_VER) || !defined(_WIN32)
return m_Device8->GetResourceAllocationInfo2(0, 1, &resourceDesc, &info1Unused);
#else
D3D12_RESOURCE_ALLOCATION_INFO ret;
m_Device8->GetResourceAllocationInfo2(&ret, 0, 1, &resourceDesc, &info1Unused);
return ret;
#endif
/* GODOT end */
}
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -171,6 +171,13 @@ typedef interface ID3D12SharingContract ID3D12SharingContract;
#endif /* __ID3D12SharingContract_FWD_DEFINED__ */
#ifndef __ID3D12ManualWriteTrackingResource_FWD_DEFINED__
#define __ID3D12ManualWriteTrackingResource_FWD_DEFINED__
typedef interface ID3D12ManualWriteTrackingResource ID3D12ManualWriteTrackingResource;
#endif /* __ID3D12ManualWriteTrackingResource_FWD_DEFINED__ */
#ifndef __ID3D12InfoQueue_FWD_DEFINED__
#define __ID3D12InfoQueue_FWD_DEFINED__
typedef interface ID3D12InfoQueue ID3D12InfoQueue;
@ -2237,7 +2244,92 @@ EXTERN_C const IID IID_ID3D12SharingContract;
#endif /* __ID3D12SharingContract_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_d3d12sdklayers_0000_0017 */
#ifndef __ID3D12ManualWriteTrackingResource_INTERFACE_DEFINED__
#define __ID3D12ManualWriteTrackingResource_INTERFACE_DEFINED__
/* interface ID3D12ManualWriteTrackingResource */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_ID3D12ManualWriteTrackingResource;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("86ca3b85-49ad-4b6e-aed5-eddb18540f41")
ID3D12ManualWriteTrackingResource : public IUnknown
{
public:
virtual void STDMETHODCALLTYPE TrackWrite(
UINT Subresource,
_In_opt_ const D3D12_RANGE *pWrittenRange) = 0;
};
#else /* C style interface */
typedef struct ID3D12ManualWriteTrackingResourceVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ID3D12ManualWriteTrackingResource * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ID3D12ManualWriteTrackingResource * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ID3D12ManualWriteTrackingResource * This);
DECLSPEC_XFGVIRT(ID3D12ManualWriteTrackingResource, TrackWrite)
void ( STDMETHODCALLTYPE *TrackWrite )(
ID3D12ManualWriteTrackingResource * This,
UINT Subresource,
_In_opt_ const D3D12_RANGE *pWrittenRange);
END_INTERFACE
} ID3D12ManualWriteTrackingResourceVtbl;
interface ID3D12ManualWriteTrackingResource
{
CONST_VTBL struct ID3D12ManualWriteTrackingResourceVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define ID3D12ManualWriteTrackingResource_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define ID3D12ManualWriteTrackingResource_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define ID3D12ManualWriteTrackingResource_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define ID3D12ManualWriteTrackingResource_TrackWrite(This,Subresource,pWrittenRange) \
( (This)->lpVtbl -> TrackWrite(This,Subresource,pWrittenRange) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __ID3D12ManualWriteTrackingResource_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_d3d12sdklayers_0000_0018 */
/* [local] */
typedef
@ -2375,6 +2467,9 @@ enum D3D12_MESSAGE_ID
D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = 115,
D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA = 116,
D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = 117,
D3D12_MESSAGE_ID_GET_PROGRAM_IDENTIFIER_ERROR = 118,
D3D12_MESSAGE_ID_GET_WORK_GRAPH_PROPERTIES_ERROR = 119,
D3D12_MESSAGE_ID_SET_PROGRAM_ERROR = 120,
D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID = 135,
D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_NOT_SET = 200,
D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_MISMATCH = 201,
@ -3176,8 +3271,6 @@ enum D3D12_MESSAGE_ID
D3D12_MESSAGE_ID_UNSUPPORTED_BARRIER_LAYOUT = 1341,
D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALID_PARAMETERS = 1342,
D3D12_MESSAGE_ID_ENHANCED_BARRIERS_NOT_SUPPORTED = 1343,
D3D12_MESSAGE_ID_CAST_TARGET_TEXEL_SIZE_MISMATCH = 1344,
D3D12_MESSAGE_ID_CAST_TO_PLANAR_NOT_SUPORTED = 1345,
D3D12_MESSAGE_ID_LEGACY_BARRIER_VALIDATION_FORCED_ON = 1346,
D3D12_MESSAGE_ID_EMPTY_ROOT_DESCRIPTOR_TABLE = 1347,
D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ELEMENT_OFFSET_UNALIGNED = 1348,
@ -3191,10 +3284,35 @@ enum D3D12_MESSAGE_ID
D3D12_MESSAGE_ID_NON_OPTIMAL_BARRIER_ONLY_EXECUTE_COMMAND_LISTS = 1356,
D3D12_MESSAGE_ID_EXECUTE_INDIRECT_ZERO_COMMAND_COUNT = 1357,
D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_TEXTURE_LAYOUT = 1358,
D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DYNAMIC_INDEX_BUFFER_STRIP_CUT_NOT_SUPPORTED = 1359,
D3D12_MESSAGE_ID_DYNAMIC_INDEX_BUFFER_STRIP_CUT_NOT_SUPPORTED = 1359,
D3D12_MESSAGE_ID_PRIMITIVE_TOPOLOGY_TRIANGLE_FANS_NOT_SUPPORTED = 1360,
D3D12_MESSAGE_ID_CREATE_SAMPLER_COMPARISON_FUNC_IGNORED = 1361,
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_CREATE_SAMPLER_COMPARISON_FUNC_IGNORED + 1 )
D3D12_MESSAGE_ID_CREATEHEAP_INVALIDHEAPTYPE = 1362,
D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPTYPE = 1363,
D3D12_MESSAGE_ID_DYNAMIC_DEPTH_BIAS_NOT_SUPPORTED = 1364,
D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_NON_WHOLE_DYNAMIC_DEPTH_BIAS = 1365,
D3D12_MESSAGE_ID_DYNAMIC_DEPTH_BIAS_FLAG_MISSING = 1366,
D3D12_MESSAGE_ID_DYNAMIC_DEPTH_BIAS_NO_PIPELINE = 1367,
D3D12_MESSAGE_ID_DYNAMIC_INDEX_BUFFER_STRIP_CUT_FLAG_MISSING = 1368,
D3D12_MESSAGE_ID_DYNAMIC_INDEX_BUFFER_STRIP_CUT_NO_PIPELINE = 1369,
D3D12_MESSAGE_ID_NONNORMALIZED_COORDINATE_SAMPLING_NOT_SUPPORTED = 1370,
D3D12_MESSAGE_ID_INVALID_CAST_TARGET = 1371,
D3D12_MESSAGE_ID_RENDER_PASS_COMMANDLIST_INVALID_END_STATE = 1372,
D3D12_MESSAGE_ID_RENDER_PASS_COMMANDLIST_INVALID_START_STATE = 1373,
D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_ACCESS = 1374,
D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_LOCAL_PRESERVE_PARAMETERS = 1375,
D3D12_MESSAGE_ID_RENDER_PASS_LOCAL_PRESERVE_RENDER_PARAMETERS_ERROR = 1376,
D3D12_MESSAGE_ID_RENDER_PASS_LOCAL_DEPTH_STENCIL_ERROR = 1377,
D3D12_MESSAGE_ID_DRAW_POTENTIALLY_OUTSIDE_OF_VALID_RENDER_AREA = 1378,
D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALID_LINERASTERIZATIONMODE = 1379,
D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDALIGNMENT_SMALLRESOURCE = 1380,
D3D12_MESSAGE_ID_GENERIC_DEVICE_OPERATION_UNSUPPORTED = 1381,
D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDER_TARGET_WRONG_WRITE_MASK = 1382,
D3D12_MESSAGE_ID_PROBABLE_PIX_EVENT_LEAK = 1383,
D3D12_MESSAGE_ID_PIX_EVENT_UNDERFLOW = 1384,
D3D12_MESSAGE_ID_RECREATEAT_INVALID_TARGET = 1385,
D3D12_MESSAGE_ID_RECREATEAT_INSUFFICIENT_SUPPORT = 1386,
D3D12_MESSAGE_ID_D3D12_MESSAGES_END = ( D3D12_MESSAGE_ID_RECREATEAT_INSUFFICIENT_SUPPORT + 1 )
} D3D12_MESSAGE_ID;
typedef struct D3D12_MESSAGE
@ -3225,8 +3343,8 @@ typedef struct D3D12_INFO_QUEUE_FILTER
#define D3D12_INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT 1024
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0017_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0017_v0_0_s_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0018_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0018_v0_0_s_ifspec;
#ifndef __ID3D12InfoQueue_INTERFACE_DEFINED__
#define __ID3D12InfoQueue_INTERFACE_DEFINED__
@ -3671,7 +3789,7 @@ EXTERN_C const IID IID_ID3D12InfoQueue;
#endif /* __ID3D12InfoQueue_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_d3d12sdklayers_0000_0018 */
/* interface __MIDL_itf_d3d12sdklayers_0000_0019 */
/* [local] */
typedef
@ -3691,8 +3809,8 @@ typedef void ( __stdcall *D3D12MessageFunc )(
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0018_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0018_v0_0_s_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0019_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0019_v0_0_s_ifspec;
#ifndef __ID3D12InfoQueue1_INTERFACE_DEFINED__
#define __ID3D12InfoQueue1_INTERFACE_DEFINED__
@ -3712,7 +3830,7 @@ EXTERN_C const IID IID_ID3D12InfoQueue1;
virtual HRESULT STDMETHODCALLTYPE RegisterMessageCallback(
_In_ D3D12MessageFunc CallbackFunc,
_In_ D3D12_MESSAGE_CALLBACK_FLAGS CallbackFilterFlags,
_In_ void *pContext,
_Inout_ void *pContext,
_Inout_ DWORD *pCallbackCookie) = 0;
virtual HRESULT STDMETHODCALLTYPE UnregisterMessageCallback(
@ -3914,7 +4032,7 @@ EXTERN_C const IID IID_ID3D12InfoQueue1;
ID3D12InfoQueue1 * This,
_In_ D3D12MessageFunc CallbackFunc,
_In_ D3D12_MESSAGE_CALLBACK_FLAGS CallbackFilterFlags,
_In_ void *pContext,
_Inout_ void *pContext,
_Inout_ DWORD *pCallbackCookie);
DECLSPEC_XFGVIRT(ID3D12InfoQueue1, UnregisterMessageCallback)
@ -4068,7 +4186,7 @@ EXTERN_C const IID IID_ID3D12InfoQueue1;
#endif /* __ID3D12InfoQueue1_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_d3d12sdklayers_0000_0019 */
/* interface __MIDL_itf_d3d12sdklayers_0000_0020 */
/* [local] */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */
@ -4090,12 +4208,13 @@ DEFINE_GUID(IID_ID3D12DebugCommandList,0x09e0bf36,0x54ac,0x484f,0x88,0x47,0x4b,0
DEFINE_GUID(IID_ID3D12DebugCommandList2,0xaeb575cf,0x4e06,0x48be,0xba,0x3b,0xc4,0x50,0xfc,0x96,0x65,0x2e);
DEFINE_GUID(IID_ID3D12DebugCommandList3,0x197d5e15,0x4d37,0x4d34,0xaf,0x78,0x72,0x4c,0xd7,0x0f,0xdb,0x1f);
DEFINE_GUID(IID_ID3D12SharingContract,0x0adf7d52,0x929c,0x4e61,0xad,0xdb,0xff,0xed,0x30,0xde,0x66,0xef);
DEFINE_GUID(IID_ID3D12ManualWriteTrackingResource,0x86ca3b85,0x49ad,0x4b6e,0xae,0xd5,0xed,0xdb,0x18,0x54,0x0f,0x41);
DEFINE_GUID(IID_ID3D12InfoQueue,0x0742a90b,0xc387,0x483f,0xb9,0x46,0x30,0xa7,0xe4,0xe6,0x14,0x58);
DEFINE_GUID(IID_ID3D12InfoQueue1,0x2852dd88,0xb484,0x4c0c,0xb6,0xb1,0x67,0x16,0x85,0x00,0xe6,0x00);
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0019_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0019_v0_0_s_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0020_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12sdklayers_0000_0020_v0_0_s_ifspec;
/* Additional Prototypes for ALL interfaces */

View File

@ -338,7 +338,9 @@ enum D3D12_FEATURE_VIDEO
D3D12_FEATURE_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT = 42,
D3D12_FEATURE_VIDEO_ENCODER_SUPPORT = 43,
D3D12_FEATURE_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT = 44,
D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS = 45
D3D12_FEATURE_VIDEO_ENCODER_RESOURCE_REQUIREMENTS = 45,
D3D12_FEATURE_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG = 46,
D3D12_FEATURE_VIDEO_ENCODER_SUPPORT1 = 47
} D3D12_FEATURE_VIDEO;
typedef
@ -6311,6 +6313,16 @@ DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_MPEG4PT2_SIMPLE, 0xefd64d74, 0xc9e8,0x41d
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_MPEG4PT2_ADVSIMPLE_NOGMC, 0xed418a9f, 0x010d, 0x4eda, 0x9a, 0xe3, 0x9a, 0x65, 0x35, 0x8d, 0x8d, 0x2e);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN, 0x5b11d51b, 0x2f4c, 0x4452, 0xbc, 0xc3, 0x09, 0xf2, 0xa1, 0x16, 0x0c, 0xc0);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN10, 0x107af0e0, 0xef1a, 0x4d19, 0xab, 0xa8, 0x67, 0xa1, 0x63, 0x07, 0x3d, 0x13);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MONOCHROME, 0x0685b993, 0x3d8c, 0x43a0, 0x8b, 0x28, 0xd7, 0x4c, 0x2d, 0x68, 0x99, 0xa4);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MONOCHROME10, 0x142a1d0f, 0x69dd, 0x4ec9, 0x85, 0x91, 0xb1, 0x2f, 0xfc, 0xb9, 0x1a, 0x29);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN12, 0x1a72925f, 0x0c2c, 0x4f15, 0x96, 0xfb, 0xb1, 0x7d, 0x14, 0x73, 0x60, 0x3f);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN10_422, 0x0bac4fe5, 0x1532, 0x4429, 0xa8, 0x54, 0xf8, 0x4d, 0xe0, 0x49, 0x53, 0xdb);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN12_422, 0x55bcac81, 0xf311, 0x4093, 0xa7, 0xd0, 0x1c, 0xbc, 0x0b, 0x84, 0x9b, 0xee);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN_444, 0x4008018f, 0xf537, 0x4b36, 0x98, 0xcf, 0x61, 0xaf, 0x8a, 0x2c, 0x1a, 0x33);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN10_EXT, 0x9cc55490, 0xe37c, 0x4932, 0x86, 0x84, 0x49, 0x20, 0xf9, 0xf6, 0x40, 0x9c);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN10_444, 0x0dabeffa, 0x4458, 0x4602, 0xbc, 0x03, 0x07, 0x95, 0x65, 0x9d, 0x61, 0x7c);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN12_444, 0x9798634d, 0xfe9d, 0x48e5, 0xb4, 0xda, 0xdb, 0xec, 0x45, 0xb3, 0xdf, 0x01);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_HEVC_MAIN16, 0xa4fbdbb0, 0xa113, 0x482b, 0xa2, 0x32, 0x63, 0x5c, 0xc0, 0x69, 0x7f, 0x6d);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_VP9, 0x463707f8, 0xa1d0, 0x4585, 0x87, 0x6d, 0x83, 0xaa, 0x6d, 0x60, 0xb8, 0x9e);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_VP9_10BIT_PROFILE2, 0xa4c749ef, 0x6ecf, 0x48aa, 0x84, 0x48, 0x50, 0xa7, 0xa1, 0x16, 0x5f, 0xf7);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_VP8, 0x90b899ea, 0x3a62, 0x4705, 0x88, 0xb3, 0x8d, 0xf0, 0x4b, 0x27, 0x44, 0xe7);
@ -6319,6 +6331,463 @@ DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_AV1_PROFILE1, 0x6936ff0f, 0x45b1, 0x4163,
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_AV1_PROFILE2, 0x0c5f2aa1, 0xe541, 0x4089, 0xbb, 0x7b, 0x98, 0x11, 0x0a, 0x19, 0xd7, 0xc8);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_AV1_12BIT_PROFILE2, 0x17127009, 0xa00f, 0x4ce1, 0x99, 0x4e, 0xbf, 0x40, 0x81, 0xf6, 0xf3, 0xf0);
DEFINE_GUID(D3D12_VIDEO_DECODE_PROFILE_AV1_12BIT_PROFILE2_420, 0x2d80bed6, 0x9cac, 0x4835, 0x9e, 0x91, 0x32, 0x7b, 0xbc, 0x4f, 0x9e, 0xe8);
typedef
enum D3D12_VIDEO_ENCODER_AV1_PROFILE
{
D3D12_VIDEO_ENCODER_AV1_PROFILE_MAIN = 0,
D3D12_VIDEO_ENCODER_AV1_PROFILE_HIGH = 1,
D3D12_VIDEO_ENCODER_AV1_PROFILE_PROFESSIONAL = 2
} D3D12_VIDEO_ENCODER_AV1_PROFILE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_LEVELS
{
D3D12_VIDEO_ENCODER_AV1_LEVELS_2_0 = 0,
D3D12_VIDEO_ENCODER_AV1_LEVELS_2_1 = 1,
D3D12_VIDEO_ENCODER_AV1_LEVELS_2_2 = 2,
D3D12_VIDEO_ENCODER_AV1_LEVELS_2_3 = 3,
D3D12_VIDEO_ENCODER_AV1_LEVELS_3_0 = 4,
D3D12_VIDEO_ENCODER_AV1_LEVELS_3_1 = 5,
D3D12_VIDEO_ENCODER_AV1_LEVELS_3_2 = 6,
D3D12_VIDEO_ENCODER_AV1_LEVELS_3_3 = 7,
D3D12_VIDEO_ENCODER_AV1_LEVELS_4_0 = 8,
D3D12_VIDEO_ENCODER_AV1_LEVELS_4_1 = 9,
D3D12_VIDEO_ENCODER_AV1_LEVELS_4_2 = 10,
D3D12_VIDEO_ENCODER_AV1_LEVELS_4_3 = 11,
D3D12_VIDEO_ENCODER_AV1_LEVELS_5_0 = 12,
D3D12_VIDEO_ENCODER_AV1_LEVELS_5_1 = 13,
D3D12_VIDEO_ENCODER_AV1_LEVELS_5_2 = 14,
D3D12_VIDEO_ENCODER_AV1_LEVELS_5_3 = 15,
D3D12_VIDEO_ENCODER_AV1_LEVELS_6_0 = 16,
D3D12_VIDEO_ENCODER_AV1_LEVELS_6_1 = 17,
D3D12_VIDEO_ENCODER_AV1_LEVELS_6_2 = 18,
D3D12_VIDEO_ENCODER_AV1_LEVELS_6_3 = 19,
D3D12_VIDEO_ENCODER_AV1_LEVELS_7_0 = 20,
D3D12_VIDEO_ENCODER_AV1_LEVELS_7_1 = 21,
D3D12_VIDEO_ENCODER_AV1_LEVELS_7_2 = 22,
D3D12_VIDEO_ENCODER_AV1_LEVELS_7_3 = 23
} D3D12_VIDEO_ENCODER_AV1_LEVELS;
typedef
enum D3D12_VIDEO_ENCODER_AV1_TIER
{
D3D12_VIDEO_ENCODER_AV1_TIER_MAIN = 0,
D3D12_VIDEO_ENCODER_AV1_TIER_HIGH = 1
} D3D12_VIDEO_ENCODER_AV1_TIER;
typedef struct D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS
{
D3D12_VIDEO_ENCODER_AV1_LEVELS Level;
D3D12_VIDEO_ENCODER_AV1_TIER Tier;
} D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS;
typedef
enum D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_128x128_SUPERBLOCK = 0x1,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_FILTER_INTRA = 0x2,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTRA_EDGE_FILTER = 0x4,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTERINTRA_COMPOUND = 0x8,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_MASKED_COMPOUND = 0x10,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_WARPED_MOTION = 0x20,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_DUAL_FILTER = 0x40,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_JNT_COMP = 0x80,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_FORCED_INTEGER_MOTION_VECTORS = 0x100,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_SUPER_RESOLUTION = 0x200,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_RESTORATION_FILTER = 0x400,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_PALETTE_ENCODING = 0x800,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_CDEF_FILTERING = 0x1000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_INTRA_BLOCK_COPY = 0x2000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_FRAME_REFERENCE_MOTION_VECTORS = 0x4000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_ORDER_HINT_TOOLS = 0x8000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_AUTO_SEGMENTATION = 0x10000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_CUSTOM_SEGMENTATION = 0x20000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_LOOP_FILTER_DELTAS = 0x40000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_QUANTIZATION_DELTAS = 0x80000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_QUANTIZATION_MATRIX = 0x100000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_REDUCED_TX_SET = 0x200000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_MOTION_MODE_SWITCHABLE = 0x400000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_ALLOW_HIGH_PRECISION_MV = 0x800000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_SKIP_MODE_PRESENT = 0x1000000,
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAG_DELTA_LF_PARAMS = 0x2000000
} D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_TX_MODE
{
D3D12_VIDEO_ENCODER_AV1_TX_MODE_ONLY4x4 = 0,
D3D12_VIDEO_ENCODER_AV1_TX_MODE_LARGEST = 1,
D3D12_VIDEO_ENCODER_AV1_TX_MODE_SELECT = 2
} D3D12_VIDEO_ENCODER_AV1_TX_MODE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAG_ONLY4x4 = ( 1 << D3D12_VIDEO_ENCODER_AV1_TX_MODE_ONLY4x4 ) ,
D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAG_LARGEST = ( 1 << D3D12_VIDEO_ENCODER_AV1_TX_MODE_LARGEST ) ,
D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAG_SELECT = ( 1 << D3D12_VIDEO_ENCODER_AV1_TX_MODE_SELECT )
} D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS
{
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP = 0,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP_SMOOTH = 1,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP_SHARP = 2,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_BILINEAR = 3,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_SWITCHABLE = 4
} D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS;
typedef
enum D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_EIGHTTAP = ( 1 << D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP ) ,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_EIGHTTAP_SMOOTH = ( 1 << D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP_SMOOTH ) ,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_EIGHTTAP_SHARP = ( 1 << D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_EIGHTTAP_SHARP ) ,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_BILINEAR = ( 1 << D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_BILINEAR ) ,
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAG_SWITCHABLE = ( 1 << D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_SWITCHABLE )
} D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE
{
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE_4x4 = 0,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE_8x8 = 1,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE_16x16 = 2,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE_32x32 = 3,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE_64x64 = 4
} D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE
{
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_DISABLED = 0,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_Q = 1,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_Y_V = 2,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_Y_H = 3,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_U = 4,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_V = 5,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_REF_FRAME = 6,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_SKIP = 7,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_GLOBALMV = 8
} D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_DISABLED = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_DISABLED ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_Q = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_Q ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_LF_Y_V = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_Y_V ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_LF_Y_H = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_Y_H ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_LF_U = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_U ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_LF_V = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_LF_V ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_REF_FRAME = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_REF_FRAME ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_SKIP = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_SKIP ) ,
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAG_ALT_GLOBALMV = ( 1 << D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_ALT_GLOBALMV )
} D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE
{
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE_DISABLED = 0,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE_SWITCHABLE = 1,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE_WIENER = 2,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE_SGRPROJ = 3
} D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE
{
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE_DISABLED = 0,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE_32x32 = 1,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE_64x64 = 2,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE_128x128 = 3,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE_256x256 = 4
} D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAG_NOT_SUPPORTED = 0,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAG_32x32 = 0x1,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAG_64x64 = 0x2,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAG_128x128 = 0x4,
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAG_256x256 = 0x8
} D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION
{
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_IDENTITY = 0,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_TRANSLATION = 1,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_ROTZOOM = 2,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_AFFINE = 3
} D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION;
typedef
enum D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAG_IDENTITY = ( 1 << D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_IDENTITY ) ,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAG_TRANSLATION = ( 1 << D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_TRANSLATION ) ,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAG_ROTZOOM = ( 1 << D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_ROTZOOM ) ,
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAG_AFFINE = ( 1 << D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_AFFINE )
} D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_QUANTIZATION = 0x1,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_QUANTIZATION_DELTA = 0x2,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_LOOP_FILTER = 0x4,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_LOOP_FILTER_DELTA = 0x8,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_CDEF_DATA = 0x10,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_CONTEXT_UPDATE_TILE_ID = 0x20,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_COMPOUND_PREDICTION_MODE = 0x40,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_PRIMARY_REF_FRAME = 0x80,
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAG_REFERENCE_INDICES = 0x100
} D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS);
typedef struct D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION_SUPPORT
{
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS SupportedFeatureFlags;
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS RequiredFeatureFlags;
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS_FLAGS SupportedInterpolationFilters;
D3D12_VIDEO_ENCODER_AV1_RESTORATION_SUPPORT_FLAGS SupportedRestorationParams[ 3 ][ 3 ];
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MODE_FLAGS SupportedSegmentationModes;
D3D12_VIDEO_ENCODER_AV1_TX_MODE_FLAGS SupportedTxModes[ 4 ];
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_BLOCK_SIZE SegmentationBlockSize;
D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES_FLAGS PostEncodeValuesFlags;
UINT MaxTemporalLayers;
UINT MaxSpatialLayers;
} D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION_SUPPORT;
typedef
enum D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE
{
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_KEY_FRAME = 0,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_INTER_FRAME = 1,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_INTRA_ONLY_FRAME = 2,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_SWITCH_FRAME = 3
} D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAG_KEY_FRAME = ( 1 << D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_KEY_FRAME ) ,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAG_INTER_FRAME = ( 1 << D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_INTER_FRAME ) ,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAG_INTRA_ONLY_FRAME = ( 1 << D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_INTRA_ONLY_FRAME ) ,
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAG_SWITCH_FRAME = ( 1 << D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_SWITCH_FRAME )
} D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAGS);
typedef
enum D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE
{
D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE_SINGLE_REFERENCE = 0,
D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE_COMPOUND_REFERENCE = 1
} D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE;
typedef struct D3D12_VIDEO_ENCODER_CODEC_AV1_PICTURE_CONTROL_SUPPORT
{
D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE PredictionMode;
UINT MaxUniqueReferencesPerFrame;
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE_FLAGS SupportedFrameTypes;
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION_FLAGS SupportedReferenceWarpedMotionFlags;
} D3D12_VIDEO_ENCODER_CODEC_AV1_PICTURE_CONTROL_SUPPORT;
typedef struct D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION
{
D3D12_VIDEO_ENCODER_AV1_FEATURE_FLAGS FeatureFlags;
UINT OrderHintBitsMinus1;
} D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION;
typedef struct D3D12_VIDEO_ENCODER_AV1_SEQUENCE_STRUCTURE
{
UINT IntraDistance;
UINT InterFramePeriod;
} D3D12_VIDEO_ENCODER_AV1_SEQUENCE_STRUCTURE;
typedef struct D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_WARPED_MOTION_INFO
{
D3D12_VIDEO_ENCODER_AV1_REFERENCE_WARPED_MOTION_TRANSFORMATION TransformationType;
INT TransformationMatrix[ 8 ];
BOOL InvalidAffineSet;
} D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_WARPED_MOTION_INFO;
typedef struct D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_DESCRIPTOR
{
UINT ReconstructedPictureResourceIndex;
UINT TemporalLayerIndexPlus1;
UINT SpatialLayerIndexPlus1;
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE FrameType;
D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_WARPED_MOTION_INFO WarpedMotionInfo;
UINT OrderHint;
UINT PictureIndex;
} D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_DESCRIPTOR;
typedef
enum D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_ERROR_RESILIENT_MODE = 0x1,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_DISABLE_CDF_UPDATE = 0x2,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_PALETTE_ENCODING = 0x4,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_SKIP_MODE = 0x8,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_FRAME_REFERENCE_MOTION_VECTORS = 0x10,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_FORCE_INTEGER_MOTION_VECTORS = 0x20,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ALLOW_INTRA_BLOCK_COPY = 0x40,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_USE_SUPER_RESOLUTION = 0x80,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_DISABLE_FRAME_END_UPDATE_CDF = 0x100,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_FRAME_SEGMENTATION_AUTO = 0x200,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_FRAME_SEGMENTATION_CUSTOM = 0x400,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ENABLE_WARPED_MOTION = 0x800,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_REDUCED_TX_SET = 0x1000,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_MOTION_MODE_SWITCHABLE = 0x2000,
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAG_ALLOW_HIGH_PRECISION_MV = 0x4000
} D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAGS);
typedef struct D3D12_VIDEO_ENCODER_AV1_RESTORATION_CONFIG
{
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TYPE FrameRestorationType[ 3 ];
D3D12_VIDEO_ENCODER_AV1_RESTORATION_TILESIZE LoopRestorationPixelSize[ 3 ];
} D3D12_VIDEO_ENCODER_AV1_RESTORATION_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_AV1_SEGMENT_DATA
{
UINT64 EnabledFeatures;
INT64 FeatureValue[ 8 ];
} D3D12_VIDEO_ENCODER_AV1_SEGMENT_DATA;
typedef struct D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_CONFIG
{
UINT64 UpdateMap;
UINT64 TemporalUpdate;
UINT64 UpdateData;
UINT64 NumSegments;
D3D12_VIDEO_ENCODER_AV1_SEGMENT_DATA SegmentsData[ 8 ];
} D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MAP
{
UINT SegmentsMapByteSize;
UINT8 *pSegmentsMap;
} D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MAP;
typedef struct D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_CONFIG
{
UINT64 LoopFilterLevel[ 2 ];
UINT64 LoopFilterLevelU;
UINT64 LoopFilterLevelV;
UINT64 LoopFilterSharpnessLevel;
UINT64 LoopFilterDeltaEnabled;
UINT64 UpdateRefDelta;
INT64 RefDeltas[ 8 ];
UINT64 UpdateModeDelta;
INT64 ModeDeltas[ 2 ];
} D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_DELTA_CONFIG
{
UINT64 DeltaLFPresent;
UINT64 DeltaLFMulti;
UINT64 DeltaLFRes;
} D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_DELTA_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_CONFIG
{
UINT64 BaseQIndex;
INT64 YDCDeltaQ;
INT64 UDCDeltaQ;
INT64 UACDeltaQ;
INT64 VDCDeltaQ;
INT64 VACDeltaQ;
UINT64 UsingQMatrix;
UINT64 QMY;
UINT64 QMU;
UINT64 QMV;
} D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_DELTA_CONFIG
{
UINT64 DeltaQPresent;
UINT64 DeltaQRes;
} D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_DELTA_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_AV1_CDEF_CONFIG
{
UINT64 CdefBits;
UINT64 CdefDampingMinus3;
UINT64 CdefYPriStrength[ 8 ];
UINT64 CdefUVPriStrength[ 8 ];
UINT64 CdefYSecStrength[ 8 ];
UINT64 CdefUVSecStrength[ 8 ];
} D3D12_VIDEO_ENCODER_AV1_CDEF_CONFIG;
typedef struct D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA
{
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_FLAGS Flags;
D3D12_VIDEO_ENCODER_AV1_FRAME_TYPE FrameType;
D3D12_VIDEO_ENCODER_AV1_COMP_PREDICTION_TYPE CompoundPredictionType;
D3D12_VIDEO_ENCODER_AV1_INTERPOLATION_FILTERS InterpolationFilter;
D3D12_VIDEO_ENCODER_AV1_RESTORATION_CONFIG FrameRestorationConfig;
D3D12_VIDEO_ENCODER_AV1_TX_MODE TxMode;
UINT SuperResDenominator;
UINT OrderHint;
UINT PictureIndex;
UINT TemporalLayerIndexPlus1;
UINT SpatialLayerIndexPlus1;
D3D12_VIDEO_ENCODER_AV1_REFERENCE_PICTURE_DESCRIPTOR ReferenceFramesReconPictureDescriptors[ 8 ];
UINT ReferenceIndices[ 7 ];
UINT PrimaryRefFrame;
UINT RefreshFrameFlags;
D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_CONFIG LoopFilter;
D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_DELTA_CONFIG LoopFilterDelta;
D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_CONFIG Quantization;
D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_DELTA_CONFIG QuantizationDelta;
D3D12_VIDEO_ENCODER_AV1_CDEF_CONFIG CDEF;
UINT QPMapValuesCount;
_Field_size_full_(QPMapValuesCount) INT16 *pRateControlQPMap;
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_CONFIG CustomSegmentation;
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_MAP CustomSegmentsMap;
} D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA;
typedef struct D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES
{
UINT64 RowCount;
UINT64 ColCount;
UINT64 RowHeights[ 64 ];
UINT64 ColWidths[ 64 ];
UINT64 ContextUpdateTileId;
} D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES;
typedef struct D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES
{
UINT64 CompoundPredictionType;
D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_CONFIG LoopFilter;
D3D12_VIDEO_ENCODER_CODEC_AV1_LOOP_FILTER_DELTA_CONFIG LoopFilterDelta;
D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_CONFIG Quantization;
D3D12_VIDEO_ENCODER_CODEC_AV1_QUANTIZATION_DELTA_CONFIG QuantizationDelta;
D3D12_VIDEO_ENCODER_AV1_CDEF_CONFIG CDEF;
D3D12_VIDEO_ENCODER_AV1_SEGMENTATION_CONFIG SegmentationConfig;
UINT64 PrimaryRefFrame;
UINT64 ReferenceIndices[ 7 ];
} D3D12_VIDEO_ENCODER_AV1_POST_ENCODE_VALUES;
typedef
enum D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE
{
@ -6338,7 +6807,9 @@ enum D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAGS
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QP_RANGE = 0x4,
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_INITIAL_QP = 0x8,
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_MAX_FRAME_SIZE = 0x10,
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES = 0x20
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_VBV_SIZES = 0x20,
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_EXTENSION1_SUPPORT = 0x40,
D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAG_ENABLE_QUALITY_VS_SPEED = 0x80
} D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAGS);
@ -6349,6 +6820,14 @@ typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP
UINT ConstantQP_InterPredictedFrame_BiDirectionalRef;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP1
{
UINT ConstantQP_FullIntracodedFrame;
UINT ConstantQP_InterPredictedFrame_PrevRefOnly;
UINT ConstantQP_InterPredictedFrame_BiDirectionalRef;
UINT QualityVsSpeed;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP1;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR
{
UINT InitialQP;
@ -6360,6 +6839,18 @@ typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR
UINT64 InitialVBVFullness;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR1
{
UINT InitialQP;
UINT MinQP;
UINT MaxQP;
UINT64 MaxFrameBitSize;
UINT64 TargetBitRate;
UINT64 VBVCapacity;
UINT64 InitialVBVFullness;
UINT QualityVsSpeed;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR1;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR
{
UINT InitialQP;
@ -6372,6 +6863,19 @@ typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR
UINT64 InitialVBVFullness;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR1
{
UINT InitialQP;
UINT MinQP;
UINT MaxQP;
UINT64 MaxFrameBitSize;
UINT64 TargetAvgBitRate;
UINT64 PeakBitRate;
UINT64 VBVCapacity;
UINT64 InitialVBVFullness;
UINT QualityVsSpeed;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR1;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR
{
UINT InitialQP;
@ -6383,6 +6887,25 @@ typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR
UINT ConstantQualityTarget;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR1
{
UINT InitialQP;
UINT MinQP;
UINT MaxQP;
UINT64 MaxFrameBitSize;
UINT64 TargetAvgBitRate;
UINT64 PeakBitRate;
UINT ConstantQualityTarget;
UINT64 VBVCapacity;
UINT64 InitialVBVFullness;
UINT QualityVsSpeed;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR1;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_ABSOLUTE_QP_MAP
{
UINT QualityVsSpeed;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_ABSOLUTE_QP_MAP;
typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CONFIGURATION_PARAMS
{
UINT DataSize;
@ -6392,6 +6915,11 @@ typedef struct D3D12_VIDEO_ENCODER_RATE_CONTROL_CONFIGURATION_PARAMS
const D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR *pConfiguration_CBR;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR *pConfiguration_VBR;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR *pConfiguration_QVBR;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP1 *pConfiguration_CQP1;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR1 *pConfiguration_CBR1;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR1 *pConfiguration_VBR1;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR1 *pConfiguration_QVBR1;
const D3D12_VIDEO_ENCODER_RATE_CONTROL_ABSOLUTE_QP_MAP *pConfiguration_AbsoluteQPMap;
} ;
} D3D12_VIDEO_ENCODER_RATE_CONTROL_CONFIGURATION_PARAMS;
@ -6407,7 +6935,8 @@ typedef
enum D3D12_VIDEO_ENCODER_CODEC
{
D3D12_VIDEO_ENCODER_CODEC_H264 = 0,
D3D12_VIDEO_ENCODER_CODEC_HEVC = 1
D3D12_VIDEO_ENCODER_CODEC_HEVC = 1,
D3D12_VIDEO_ENCODER_CODEC_AV1 = 2
} D3D12_VIDEO_ENCODER_CODEC;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_CODEC
@ -6439,6 +6968,7 @@ typedef struct D3D12_VIDEO_ENCODER_PROFILE_DESC
{
D3D12_VIDEO_ENCODER_PROFILE_H264 *pH264Profile;
D3D12_VIDEO_ENCODER_PROFILE_HEVC *pHEVCProfile;
D3D12_VIDEO_ENCODER_AV1_PROFILE *pAV1Profile;
} ;
} D3D12_VIDEO_ENCODER_PROFILE_DESC;
@ -6505,6 +7035,7 @@ typedef struct D3D12_VIDEO_ENCODER_LEVEL_SETTING
{
D3D12_VIDEO_ENCODER_LEVELS_H264 *pH264LevelSetting;
D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC *pHEVCLevelSetting;
D3D12_VIDEO_ENCODER_AV1_LEVEL_TIER_CONSTRAINTS *pAV1LevelSetting;
} ;
} D3D12_VIDEO_ENCODER_LEVEL_SETTING;
@ -6591,7 +7122,9 @@ enum D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_BYTES_PER_SUBREGION = 1,
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_SQUARE_UNITS_PER_SUBREGION_ROW_UNALIGNED = 2,
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_ROWS_PER_SUBREGION = 3,
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME = 4
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_PARTITIONING_SUBREGIONS_PER_FRAME = 4,
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_UNIFORM_GRID_PARTITION = 5,
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE_CONFIGURABLE_GRID_PARTITION = 6
} D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE
@ -6604,6 +7137,58 @@ typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE
BOOL IsSupported;
} D3D12_FEATURE_DATA_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE;
typedef
enum D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAGS
{
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_NONE = 0,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_NOT_SPECIFIED = 0x1,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_CODEC_CONSTRAINT = 0x2,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_HARDWARE_CONSTRAINT = 0x4,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_ROWS_COUNT = 0x8,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_COLS_COUNT = 0x10,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_WIDTH = 0x20,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_AREA = 0x40,
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAG_TOTAL_TILES = 0x80
} D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAGS);
typedef struct D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT
{
BOOL Use128SuperBlocks;
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES TilesConfiguration;
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_VALIDATION_FLAGS ValidationFlags;
UINT MinTileRows;
UINT MaxTileRows;
UINT MinTileCols;
UINT MaxTileCols;
UINT MinTileWidth;
UINT MaxTileWidth;
UINT MinTileArea;
UINT MaxTileArea;
UINT TileSizeBytesMinus1;
} D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT;
typedef struct D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT
{
UINT DataSize;
union
{
D3D12_VIDEO_ENCODER_AV1_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT *pAV1Support;
} ;
} D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG
{
UINT NodeIndex;
D3D12_VIDEO_ENCODER_CODEC Codec;
D3D12_VIDEO_ENCODER_PROFILE_DESC Profile;
D3D12_VIDEO_ENCODER_LEVEL_SETTING Level;
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE SubregionMode;
D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC FrameResolution;
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG_SUPPORT CodecSupport;
BOOL IsSupported;
} D3D12_FEATURE_DATA_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_CONFIG;
typedef
enum D3D12_VIDEO_ENCODER_HEAP_FLAGS
{
@ -6728,6 +7313,7 @@ typedef struct D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT
{
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264 *pH264Support;
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_HEVC *pHEVCSupport;
D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION_SUPPORT *pAV1Support;
} ;
} D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT;
@ -6765,6 +7351,7 @@ typedef struct D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT
{
D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_H264 *pH264Support;
D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT_HEVC *pHEVCSupport;
D3D12_VIDEO_ENCODER_CODEC_AV1_PICTURE_CONTROL_SUPPORT *pAV1Support;
} ;
} D3D12_VIDEO_ENCODER_CODEC_PICTURE_CONTROL_SUPPORT;
@ -6793,7 +7380,9 @@ enum D3D12_VIDEO_ENCODER_SUPPORT_FLAGS
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_INITIAL_QP_AVAILABLE = 0x200,
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_MAX_FRAME_SIZE_AVAILABLE = 0x400,
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_SEQUENCE_GOP_RECONFIGURATION_AVAILABLE = 0x800,
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE = 0x1000
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_MOTION_ESTIMATION_PRECISION_MODE_LIMIT_AVAILABLE = 0x1000,
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_EXTENSION1_SUPPORT = 0x2000,
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RATE_CONTROL_QUALITY_VS_SPEED_AVAILABLE = 0x4000
} D3D12_VIDEO_ENCODER_SUPPORT_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_SUPPORT_FLAGS);
@ -6855,6 +7444,7 @@ typedef struct D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION
{
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 *pH264Config;
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC *pHEVCConfig;
D3D12_VIDEO_ENCODER_AV1_CODEC_CONFIGURATION *pAV1Config;
} ;
} D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION;
@ -6870,7 +7460,8 @@ enum D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM = 0,
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_FULL_PIXEL = 1,
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_HALF_PIXEL = 2,
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_QUARTER_PIXEL = 3
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_QUARTER_PIXEL = 3,
D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_EIGHTH_PIXEL = 4
} D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS
@ -6893,7 +7484,8 @@ enum D3D12_VIDEO_ENCODER_VALIDATION_FLAGS
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_INTRA_REFRESH_MODE_NOT_SUPPORTED = 0x80,
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_SUBREGION_LAYOUT_MODE_NOT_SUPPORTED = 0x100,
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_RESOLUTION_NOT_SUPPORTED_IN_LIST = 0x200,
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_GOP_STRUCTURE_NOT_SUPPORTED = 0x800
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_GOP_STRUCTURE_NOT_SUPPORTED = 0x800,
D3D12_VIDEO_ENCODER_VALIDATION_FLAG_SUBREGION_LAYOUT_DATA_NOT_SUPPORTED = 0x1000
} D3D12_VIDEO_ENCODER_VALIDATION_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_VALIDATION_FLAGS);
@ -6920,6 +7512,7 @@ typedef struct D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE
{
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264 *pH264GroupOfPictures;
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC *pHEVCGroupOfPictures;
D3D12_VIDEO_ENCODER_AV1_SEQUENCE_STRUCTURE *pAV1SequenceStructure;
} ;
} D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE;
@ -6943,6 +7536,50 @@ typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT
_Field_size_full_(ResolutionsListCount) D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS *pResolutionDependentSupport;
} D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT;
typedef struct D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES
{
union
{
UINT MaxBytesPerSlice;
UINT NumberOfCodingUnitsPerSlice;
UINT NumberOfRowsPerSlice;
UINT NumberOfSlicesPerFrame;
} ;
} D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES;
typedef struct D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA
{
UINT DataSize;
union
{
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES *pSlicesPartition_H264;
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES *pSlicesPartition_HEVC;
const D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_TILES *pTilesPartition_AV1;
} ;
} D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1
{
UINT NodeIndex;
D3D12_VIDEO_ENCODER_CODEC Codec;
DXGI_FORMAT InputFormat;
D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION CodecConfiguration;
D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE CodecGopSequence;
D3D12_VIDEO_ENCODER_RATE_CONTROL RateControl;
D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE IntraRefresh;
D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE SubregionFrameEncoding;
UINT ResolutionsListCount;
const D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC *pResolutionList;
UINT MaxReferenceFramesInDPB;
D3D12_VIDEO_ENCODER_VALIDATION_FLAGS ValidationFlags;
D3D12_VIDEO_ENCODER_SUPPORT_FLAGS SupportFlags;
D3D12_VIDEO_ENCODER_PROFILE_DESC SuggestedProfile;
D3D12_VIDEO_ENCODER_LEVEL_SETTING SuggestedLevel;
_Field_size_full_(ResolutionsListCount) D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS *pResolutionDependentSupport;
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA SubregionFrameEncodingData;
UINT MaxQualityVsSpeed;
} D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT1;
typedef struct D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS
{
UINT NodeIndex;
@ -7716,6 +8353,7 @@ typedef struct D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA
{
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264 *pH264PicData;
D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC *pHEVCPicData;
D3D12_VIDEO_ENCODER_AV1_PICTURE_CONTROL_CODEC_DATA *pAV1PicData;
} ;
} D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA;
@ -7754,27 +8392,6 @@ enum D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS
} D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS(D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS);
typedef struct D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES
{
union
{
UINT MaxBytesPerSlice;
UINT NumberOfCodingUnitsPerSlice;
UINT NumberOfRowsPerSlice;
UINT NumberOfSlicesPerFrame;
} ;
} D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES;
typedef struct D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA
{
UINT DataSize;
union
{
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES *pSlicesPartition_H264;
const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES *pSlicesPartition_HEVC;
} ;
} D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA;
typedef struct D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_DESC
{
D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS Flags;

View File

@ -93,6 +93,7 @@ enum D3D_DRIVER_TYPE
typedef
enum D3D_FEATURE_LEVEL
{
D3D_FEATURE_LEVEL_1_0_GENERIC = 0x100,
D3D_FEATURE_LEVEL_1_0_CORE = 0x1000,
D3D_FEATURE_LEVEL_9_1 = 0x9100,
D3D_FEATURE_LEVEL_9_2 = 0x9200,

View File

@ -0,0 +1,35 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3DX12_H__
#define __D3DX12_H__
#include "d3d12.h"
#if defined( __cplusplus )
#include "d3dx12_barriers.h"
#include "d3dx12_core.h"
#include "d3dx12_default.h"
#include "d3dx12_pipeline_state_stream.h"
#include "d3dx12_render_pass.h"
#include "d3dx12_resource_helpers.h"
#include "d3dx12_root_signature.h"
#include "d3dx12_property_format_table.h"
#ifndef D3DX12_NO_STATE_OBJECT_HELPERS
#include "d3dx12_state_object.h"
#endif // !D3DX12_NO_STATE_OBJECT_HELPERS
#ifndef D3DX12_NO_CHECK_FEATURE_SUPPORT_CLASS
#include "d3dx12_check_feature_support.h"
#endif // !D3DX12_NO_CHECK_FEATURE_SUPPORT_CLASS
#endif // defined( __cplusplus )
#endif //__D3DX12_H__

View File

@ -0,0 +1,192 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3DX12_BARRIERS_H__
#define __D3DX12_BARRIERS_H__
#if defined( __cplusplus )
#include "d3d12.h"
//------------------------------------------------------------------------------------------------
struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
{
CD3DX12_RESOURCE_BARRIER() = default;
explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept :
D3D12_RESOURCE_BARRIER(o)
{}
static inline CD3DX12_RESOURCE_BARRIER Transition(
_In_ ID3D12Resource* pResource,
D3D12_RESOURCE_STATES stateBefore,
D3D12_RESOURCE_STATES stateAfter,
UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
result.Flags = flags;
barrier.Transition.pResource = pResource;
barrier.Transition.StateBefore = stateBefore;
barrier.Transition.StateAfter = stateAfter;
barrier.Transition.Subresource = subresource;
return result;
}
static inline CD3DX12_RESOURCE_BARRIER Aliasing(
_In_opt_ ID3D12Resource* pResourceBefore,
_In_opt_ ID3D12Resource* pResourceAfter) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
barrier.Aliasing.pResourceBefore = pResourceBefore;
barrier.Aliasing.pResourceAfter = pResourceAfter;
return result;
}
static inline CD3DX12_RESOURCE_BARRIER UAV(
_In_opt_ ID3D12Resource* pResource) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
barrier.UAV.pResource = pResource;
return result;
}
};
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 608)
//================================================================================================
// D3DX12 Enhanced Barrier Helpers
//================================================================================================
class CD3DX12_BARRIER_SUBRESOURCE_RANGE : public D3D12_BARRIER_SUBRESOURCE_RANGE
{
public:
CD3DX12_BARRIER_SUBRESOURCE_RANGE() = default;
CD3DX12_BARRIER_SUBRESOURCE_RANGE(const D3D12_BARRIER_SUBRESOURCE_RANGE &o) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE(o)
{}
explicit CD3DX12_BARRIER_SUBRESOURCE_RANGE(UINT Subresource) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE{ Subresource, 0, 0, 0, 0, 0 }
{}
CD3DX12_BARRIER_SUBRESOURCE_RANGE(
UINT firstMipLevel,
UINT numMips,
UINT firstArraySlice,
UINT numArraySlices,
UINT firstPlane = 0,
UINT numPlanes = 1) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE
{
firstMipLevel,
numMips,
firstArraySlice,
numArraySlices,
firstPlane,
numPlanes
}
{}
};
class CD3DX12_GLOBAL_BARRIER : public D3D12_GLOBAL_BARRIER
{
public:
CD3DX12_GLOBAL_BARRIER() = default;
CD3DX12_GLOBAL_BARRIER(const D3D12_GLOBAL_BARRIER &o) noexcept : D3D12_GLOBAL_BARRIER(o){}
CD3DX12_GLOBAL_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter) noexcept : D3D12_GLOBAL_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter
}
{}
};
class CD3DX12_BUFFER_BARRIER : public D3D12_BUFFER_BARRIER
{
public:
CD3DX12_BUFFER_BARRIER() = default;
CD3DX12_BUFFER_BARRIER(const D3D12_BUFFER_BARRIER &o) noexcept : D3D12_BUFFER_BARRIER(o){}
CD3DX12_BUFFER_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter,
ID3D12Resource *pRes) noexcept : D3D12_BUFFER_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter,
pRes,
0, ULLONG_MAX
}
{}
};
class CD3DX12_TEXTURE_BARRIER : public D3D12_TEXTURE_BARRIER
{
public:
CD3DX12_TEXTURE_BARRIER() = default;
CD3DX12_TEXTURE_BARRIER(const D3D12_TEXTURE_BARRIER &o) noexcept : D3D12_TEXTURE_BARRIER(o){}
CD3DX12_TEXTURE_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter,
D3D12_BARRIER_LAYOUT layoutBefore,
D3D12_BARRIER_LAYOUT layoutAfter,
ID3D12Resource *pRes,
const D3D12_BARRIER_SUBRESOURCE_RANGE &subresources,
D3D12_TEXTURE_BARRIER_FLAGS flag = D3D12_TEXTURE_BARRIER_FLAG_NONE) noexcept : D3D12_TEXTURE_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter,
layoutBefore,
layoutAfter,
pRes,
subresources,
flag
}
{}
};
class CD3DX12_BARRIER_GROUP : public D3D12_BARRIER_GROUP
{
public:
CD3DX12_BARRIER_GROUP() = default;
CD3DX12_BARRIER_GROUP(const D3D12_BARRIER_GROUP &o) noexcept : D3D12_BARRIER_GROUP(o){}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_BUFFER_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_BUFFER;
NumBarriers = numBarriers;
pBufferBarriers = pBarriers;
}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_TEXTURE_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_TEXTURE;
NumBarriers = numBarriers;
pTextureBarriers = pBarriers;
}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_GLOBAL_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_GLOBAL;
NumBarriers = numBarriers;
pGlobalBarriers = pBarriers;
}
};
#endif // D3D12_SDK_VERSION >= 608
#endif // defined( __cplusplus )
#endif // __D3DX12_BARRIERS_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
struct CD3DX12_DEFAULT {};
extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3D12_PROPERTY_LAYOUT_FORMAT_TABLE_H__
#define __D3D12_PROPERTY_LAYOUT_FORMAT_TABLE_H__
#include "d3d12.h"
#define MAP_ALIGN_REQUIREMENT 16 // Map is required to return 16-byte aligned addresses
struct D3D12_PROPERTY_LAYOUT_FORMAT_TABLE
{
public:
// ----------------------------------------------------------------------------
// Information describing everything about a D3D Resource Format
// ----------------------------------------------------------------------------
typedef struct FORMAT_DETAIL
{
DXGI_FORMAT DXGIFormat;
DXGI_FORMAT ParentFormat;
const DXGI_FORMAT* pDefaultFormatCastSet; // This is dependent on FL/driver version, but is here to save a lot of space
UINT8 BitsPerComponent[4]; // only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
UINT8 BitsPerUnit;
BYTE SRGBFormat : 1;
UINT WidthAlignment : 4; // number of texels to align to in a mip level.
UINT HeightAlignment : 4; // Top level dimensions must be a multiple of these
UINT DepthAlignment : 1; // values.
D3D_FORMAT_LAYOUT Layout : 1;
D3D_FORMAT_TYPE_LEVEL TypeLevel : 2;
D3D_FORMAT_COMPONENT_NAME ComponentName0 : 3; // RED ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName1 : 3; // GREEN ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName2 : 3; // BLUE ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName3 : 3; // ALPHA ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation0 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation1 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation2 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation3 : 3; // only used for D3DFTL_FULL_TYPE
bool bDX9VertexOrIndexFormat : 1;
bool bDX9TextureFormat : 1;
bool bFloatNormFormat : 1;
bool bPlanar : 1;
bool bYUV : 1;
bool bDependantFormatCastSet : 1; // This indicates that the format cast set is dependent on FL/driver version
bool bInternal : 1;
} FORMAT_DETAIL;
private:
static const FORMAT_DETAIL s_FormatDetail[];
static const UINT s_NumFormats;
static const LPCSTR s_FormatNames[]; // separate from above structure so it can be compiled out of runtime.
public:
static UINT GetNumFormats();
static const FORMAT_DETAIL* GetFormatTable();
static D3D_FEATURE_LEVEL GetHighestDefinedFeatureLevel();
static DXGI_FORMAT GetFormat (SIZE_T Index);
static bool FormatExists (DXGI_FORMAT Format);
static bool FormatExistsInHeader (DXGI_FORMAT Format, bool bExternalHeader = true);
static UINT GetByteAlignment (DXGI_FORMAT Format);
static bool IsBlockCompressFormat (DXGI_FORMAT Format);
static LPCSTR GetName (DXGI_FORMAT Format, bool bHideInternalFormats = true);
static bool IsSRGBFormat (DXGI_FORMAT Format);
static UINT GetBitsPerStencil (DXGI_FORMAT Format);
static void GetFormatReturnTypes (DXGI_FORMAT Format, D3D_FORMAT_COMPONENT_INTERPRETATION* pInterpretations); // return array of 4 components
static UINT GetNumComponentsInFormat(DXGI_FORMAT Format);
// Converts the sequential component index (range from 0 to GetNumComponentsInFormat()) to
// the absolute component index (range 0 to 3).
static UINT Sequential2AbsoluteComponentIndex (DXGI_FORMAT Format, UINT SequentialComponentIndex);
static bool CanBeCastEvenFullyTyped (DXGI_FORMAT Format, D3D_FEATURE_LEVEL fl);
static UINT8 GetAddressingBitsPerAlignedSize (DXGI_FORMAT Format);
static DXGI_FORMAT GetParentFormat (DXGI_FORMAT Format);
static const DXGI_FORMAT* GetFormatCastSet (DXGI_FORMAT Format);
static D3D_FORMAT_LAYOUT GetLayout (DXGI_FORMAT Format);
static D3D_FORMAT_TYPE_LEVEL GetTypeLevel (DXGI_FORMAT Format);
static UINT GetBitsPerUnit (DXGI_FORMAT Format);
static UINT GetBitsPerUnitThrow (DXGI_FORMAT Format);
static UINT GetBitsPerElement (DXGI_FORMAT Format); // Legacy function used to support D3D10on9 only. Do not use.
static UINT GetWidthAlignment (DXGI_FORMAT Format);
static UINT GetHeightAlignment (DXGI_FORMAT Format);
static UINT GetDepthAlignment (DXGI_FORMAT Format);
static BOOL Planar (DXGI_FORMAT Format);
static BOOL NonOpaquePlanar (DXGI_FORMAT Format);
static BOOL YUV (DXGI_FORMAT Format);
static BOOL Opaque (DXGI_FORMAT Format);
static bool FamilySupportsStencil (DXGI_FORMAT Format);
static UINT NonOpaquePlaneCount (DXGI_FORMAT Format);
static BOOL DX9VertexOrIndexFormat (DXGI_FORMAT Format);
static BOOL DX9TextureFormat (DXGI_FORMAT Format);
static BOOL FloatNormTextureFormat (DXGI_FORMAT Format);
static bool DepthOnlyFormat (DXGI_FORMAT format);
static UINT8 GetPlaneCount (DXGI_FORMAT Format);
static bool MotionEstimatorAllowedInputFormat (DXGI_FORMAT Format);
static bool SupportsSamplerFeedback (DXGI_FORMAT Format);
static bool DecodeHistogramAllowedForOutputFormatSupport(DXGI_FORMAT Format);
static UINT8 GetPlaneSliceFromViewFormat (DXGI_FORMAT ResourceFormat, DXGI_FORMAT ViewFormat);
static bool FloatAndNotFloatFormats (DXGI_FORMAT FormatA, DXGI_FORMAT FormatB);
static bool SNORMAndUNORMFormats (DXGI_FORMAT FormatA, DXGI_FORMAT FormatB);
static bool ValidCastToR32UAV (DXGI_FORMAT from, DXGI_FORMAT to);
static bool IsSupportedTextureDisplayableFormat (DXGI_FORMAT, bool bMediaFormatOnly);
static D3D_FORMAT_COMPONENT_INTERPRETATION GetFormatComponentInterpretation (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static UINT GetBitsPerComponent (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static D3D_FORMAT_COMPONENT_NAME GetComponentName (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static HRESULT CalculateExtraPlanarRows (DXGI_FORMAT format, UINT plane0Height, _Out_ UINT& totalHeight);
static HRESULT CalculateMinimumRowMajorRowPitch (DXGI_FORMAT Format, UINT Width, _Out_ UINT& RowPitch);
static HRESULT CalculateMinimumRowMajorSlicePitch (DXGI_FORMAT Format, UINT ContextBasedRowPitch, UINT Height, _Out_ UINT& SlicePitch);
static void GetYCbCrChromaSubsampling (DXGI_FORMAT Format, _Out_ UINT& HorizontalSubsampling, _Out_ UINT& VerticalSubsampling);
static HRESULT CalculateResourceSize (UINT width, UINT height, UINT depth, DXGI_FORMAT format, UINT mipLevels, UINT subresources, _Out_ SIZE_T& totalByteSize, _Out_writes_opt_(subresources) D3D12_MEMCPY_DEST* pDst = nullptr);
static void GetTileShape (D3D12_TILE_SHAPE* pTileShape, DXGI_FORMAT Format, D3D12_RESOURCE_DIMENSION Dimension, UINT SampleCount);
static void Get4KTileShape (D3D12_TILE_SHAPE* pTileShape, DXGI_FORMAT Format, D3D12_RESOURCE_DIMENSION Dimension, UINT SampleCount);
static void GetMipDimensions (UINT8 mipSlice, _Inout_ UINT64* pWidth, _Inout_opt_ UINT64* pHeight = nullptr, _Inout_opt_ UINT64* pDepth = nullptr);
static void GetPlaneSubsampledSizeAndFormatForCopyableLayout(UINT PlaneSlice, DXGI_FORMAT Format, UINT Width, UINT Height, _Out_ DXGI_FORMAT& PlaneFormat, _Out_ UINT& MinPlanePitchWidth, _Out_ UINT& PlaneWidth, _Out_ UINT& PlaneHeight);
static UINT GetDetailTableIndex (DXGI_FORMAT Format);
static UINT GetDetailTableIndexNoThrow (DXGI_FORMAT Format);
static UINT GetDetailTableIndexThrow (DXGI_FORMAT Format);
private:
static const FORMAT_DETAIL* GetFormatDetail (DXGI_FORMAT Format);
};
#endif

View File

@ -0,0 +1,102 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
#ifndef __cplusplus
#error D3DX12 requires C++
#endif
#include "d3d12.h"
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
inline bool operator==(const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
inline bool operator==(const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
inline bool operator==(const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
#endif
inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &b) noexcept
{
return a.ClearValue == b.ClearValue;
}
inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &a, const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &b) noexcept
{
if (a.pSrcResource != b.pSrcResource) return false;
if (a.pDstResource != b.pDstResource) return false;
if (a.SubresourceCount != b.SubresourceCount) return false;
if (a.Format != b.Format) return false;
if (a.ResolveMode != b.ResolveMode) return false;
if (a.PreserveResolveSource != b.PreserveResolveSource) return false;
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) noexcept
{
if (a.Type != b.Type) return false;
switch (a.Type)
{
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR:
if (!(a.Clear == b.Clear)) return false;
break;
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_RENDER:
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_SRV:
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_UAV:
if (!(a.PreserveLocal == b.PreserveLocal)) return false;
break;
#endif
}
return true;
}
inline bool operator==(const D3D12_RENDER_PASS_ENDING_ACCESS& a, const D3D12_RENDER_PASS_ENDING_ACCESS& b) noexcept
{
if (a.Type != b.Type) return false;
switch (a.Type)
{
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE:
if (!(a.Resolve == b.Resolve)) return false;
break;
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_RENDER:
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_SRV:
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_UAV:
if (!(a.PreserveLocal == b.PreserveLocal)) return false;
break;
#endif
}
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) noexcept
{
if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false;
if (!(a.BeginningAccess == b.BeginningAccess)) return false;
if (!(a.EndingAccess == b.EndingAccess)) return false;
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &b) noexcept
{
if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false;
if (!(a.DepthBeginningAccess == b.DepthBeginningAccess)) return false;
if (!(a.StencilBeginningAccess == b.StencilBeginningAccess)) return false;
if (!(a.DepthEndingAccess == b.DepthEndingAccess)) return false;
if (!(a.StencilEndingAccess == b.StencilEndingAccess)) return false;
return true;
}

View File

@ -0,0 +1,602 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
#ifndef __cplusplus
#error D3DX12 requires C++
#endif
#include "d3d12.h"
#include "d3dx12_core.h"
#include "d3dx12_property_format_table.h"
//------------------------------------------------------------------------------------------------
template <typename T, typename U, typename V>
inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept
{
MipSlice = static_cast<T>(Subresource % MipLevels);
ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
}
//------------------------------------------------------------------------------------------------
// Row-by-row memcpy
inline void MemcpySubresource(
_In_ const D3D12_MEMCPY_DEST* pDest,
_In_ const D3D12_SUBRESOURCE_DATA* pSrc,
SIZE_T RowSizeInBytes,
UINT NumRows,
UINT NumSlices) noexcept
{
for (UINT z = 0; z < NumSlices; ++z)
{
auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
for (UINT y = 0; y < NumRows; ++y)
{
memcpy(pDestSlice + pDest->RowPitch * y,
pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
RowSizeInBytes);
}
}
}
//------------------------------------------------------------------------------------------------
// Row-by-row memcpy
inline void MemcpySubresource(
_In_ const D3D12_MEMCPY_DEST* pDest,
_In_ const void* pResourceData,
_In_ const D3D12_SUBRESOURCE_INFO* pSrc,
SIZE_T RowSizeInBytes,
UINT NumRows,
UINT NumSlices) noexcept
{
for (UINT z = 0; z < NumSlices; ++z)
{
auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
auto pSrcSlice = (static_cast<const BYTE*>(pResourceData) + pSrc->Offset) + pSrc->DepthPitch * ULONG_PTR(z);
for (UINT y = 0; y < NumRows; ++y)
{
memcpy(pDestSlice + pDest->RowPitch * y,
pSrcSlice + pSrc->RowPitch * ULONG_PTR(y),
RowSizeInBytes);
}
}
}
//------------------------------------------------------------------------------------------------
// Returns required size of a buffer to be used for data upload
inline UINT64 GetRequiredIntermediateSize(
_In_ ID3D12Resource* pDestinationResource,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) noexcept
{
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
UINT64 RequiredSize = 0;
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
pDevice->Release();
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
UINT64 RequiredSize,
_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_In_reads_(NumSubresources) const UINT* pNumRows,
_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
// Minor validation
#if defined(_MSC_VER) || !defined(_WIN32)
const auto IntermediateDesc = pIntermediate->GetDesc();
const auto DestinationDesc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
#endif
if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
RequiredSize > SIZE_T(-1) ||
(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(FirstSubresource != 0 || NumSubresources != 1)))
{
return 0;
}
BYTE* pData;
HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
if (FAILED(hr))
{
return 0;
}
for (UINT i = 0; i < NumSubresources; ++i)
{
if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
}
pIntermediate->Unmap(0, nullptr);
if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
pCmdList->CopyBufferRegion(
pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
for (UINT i = 0; i < NumSubresources; ++i)
{
const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
}
}
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
UINT64 RequiredSize,
_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_In_reads_(NumSubresources) const UINT* pNumRows,
_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
// Minor validation
#if defined(_MSC_VER) || !defined(_WIN32)
const auto IntermediateDesc = pIntermediate->GetDesc();
const auto DestinationDesc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
#endif
if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
RequiredSize > SIZE_T(-1) ||
(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(FirstSubresource != 0 || NumSubresources != 1)))
{
return 0;
}
BYTE* pData;
HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
if (FAILED(hr))
{
return 0;
}
for (UINT i = 0; i < NumSubresources; ++i)
{
if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
MemcpySubresource(&DestData, pResourceData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
}
pIntermediate->Unmap(0, nullptr);
if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
pCmdList->CopyBufferRegion(
pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
for (UINT i = 0; i < NumSubresources; ++i)
{
const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
}
}
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// Heap-allocating UpdateSubresources implementation
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
if (MemToAlloc > SIZE_MAX)
{
return 0;
}
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
if (pMem == nullptr)
{
return 0;
}
auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
pDevice->Release();
const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
HeapFree(GetProcessHeap(), 0, pMem);
return Result;
}
//------------------------------------------------------------------------------------------------
// Heap-allocating UpdateSubresources implementation
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
if (MemToAlloc > SIZE_MAX)
{
return 0;
}
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
if (pMem == nullptr)
{
return 0;
}
auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
pDevice->Release();
const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pResourceData, pSrcData);
HeapFree(GetProcessHeap(), 0, pMem);
return Result;
}
//------------------------------------------------------------------------------------------------
// Stack-allocating UpdateSubresources implementation
template <UINT MaxSubresources>
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,MaxSubresources) UINT FirstSubresource,
_In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
UINT NumRows[MaxSubresources];
UINT64 RowSizesInBytes[MaxSubresources];
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
pDevice->Release();
return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
}
//------------------------------------------------------------------------------------------------
// Stack-allocating UpdateSubresources implementation
template <UINT MaxSubresources>
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,MaxSubresources) UINT FirstSubresource,
_In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
UINT NumRows[MaxSubresources];
UINT64 RowSizesInBytes[MaxSubresources];
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
pDevice->Release();
return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pResourceData, pSrcData);
}
//------------------------------------------------------------------------------------------------
constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept
{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; }
//------------------------------------------------------------------------------------------------
template< typename T >
inline T D3DX12Align(T uValue, T uAlign)
{
// Assert power of 2 alignment
D3DX12_ASSERT(0 == (uAlign & (uAlign - 1)));
T uMask = uAlign - 1;
T uResult = (uValue + uMask) & ~uMask;
D3DX12_ASSERT(uResult >= uValue);
D3DX12_ASSERT(0 == (uResult % uAlign));
return uResult;
}
//------------------------------------------------------------------------------------------------
template< typename T >
inline T D3DX12AlignAtLeast(T uValue, T uAlign)
{
T aligned = D3DX12Align(uValue, uAlign);
return aligned > uAlign ? aligned : uAlign;
}
inline const CD3DX12_RESOURCE_DESC1* D3DX12ConditionallyExpandAPIDesc(
D3D12_RESOURCE_DESC1& LclDesc,
const D3D12_RESOURCE_DESC1* pDesc)
{
return D3DX12ConditionallyExpandAPIDesc(static_cast<CD3DX12_RESOURCE_DESC1&>(LclDesc), static_cast<const CD3DX12_RESOURCE_DESC1*>(pDesc));
}
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606)
//------------------------------------------------------------------------------------------------
// The difference between D3DX12GetCopyableFootprints and ID3D12Device::GetCopyableFootprints
// is that this one loses a lot of error checking by assuming the arguments are correct
inline bool D3DX12GetCopyableFootprints(
_In_ const D3D12_RESOURCE_DESC1& ResourceDesc,
_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
UINT64 BaseOffset,
_Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_Out_writes_opt_(NumSubresources) UINT* pNumRows,
_Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
_Out_opt_ UINT64* pTotalBytes)
{
constexpr UINT64 uint64_max = ~0ull;
UINT64 TotalBytes = uint64_max;
UINT uSubRes = 0;
bool bResourceOverflow = false;
TotalBytes = 0;
const DXGI_FORMAT Format = ResourceDesc.Format;
CD3DX12_RESOURCE_DESC1 LresourceDesc;
const CD3DX12_RESOURCE_DESC1& resourceDesc = *D3DX12ConditionallyExpandAPIDesc(LresourceDesc, &ResourceDesc);
// Check if its a valid format
D3DX12_ASSERT(D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::FormatExists(Format));
const UINT WidthAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetWidthAlignment( Format );
const UINT HeightAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetHeightAlignment( Format );
const UINT16 DepthAlignment = UINT16( D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetDepthAlignment( Format ) );
for (; uSubRes < NumSubresources; ++uSubRes)
{
bool bOverflow = false;
UINT Subresource = FirstSubresource + uSubRes;
D3DX12_ASSERT(resourceDesc.MipLevels != 0);
UINT subresourceCount = resourceDesc.MipLevels * resourceDesc.ArraySize() * D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneCount(resourceDesc.Format);
if (Subresource > subresourceCount)
{
break;
}
TotalBytes = D3DX12Align< UINT64 >( TotalBytes, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT );
UINT MipLevel, ArraySlice, PlaneSlice;
D3D12DecomposeSubresource(Subresource, resourceDesc.MipLevels, resourceDesc.ArraySize(), /*_Out_*/MipLevel, /*_Out_*/ArraySlice, /*_Out_*/PlaneSlice);
const UINT64 Width = D3DX12AlignAtLeast<UINT64>(resourceDesc.Width >> MipLevel, WidthAlignment);
const UINT Height = D3DX12AlignAtLeast(resourceDesc.Height >> MipLevel, HeightAlignment);
const UINT16 Depth = D3DX12AlignAtLeast<UINT16>(resourceDesc.Depth() >> MipLevel, DepthAlignment);
// Adjust for the current PlaneSlice. Most formats have only one plane.
DXGI_FORMAT PlaneFormat;
UINT32 MinPlanePitchWidth, PlaneWidth, PlaneHeight;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneSubsampledSizeAndFormatForCopyableLayout(PlaneSlice, Format, (UINT)Width, Height, /*_Out_*/ PlaneFormat, /*_Out_*/ MinPlanePitchWidth, /* _Out_ */ PlaneWidth, /*_Out_*/ PlaneHeight);
D3D12_SUBRESOURCE_FOOTPRINT LocalPlacement;
auto& Placement = pLayouts ? pLayouts[uSubRes].Footprint : LocalPlacement;
Placement.Format = PlaneFormat;
Placement.Width = PlaneWidth;
Placement.Height = PlaneHeight;
Placement.Depth = Depth;
// Calculate row pitch
UINT MinPlaneRowPitch = 0;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, MinPlanePitchWidth, MinPlaneRowPitch);
// Formats with more than one plane choose a larger pitch alignment to ensure that each plane begins on the row
// immediately following the previous plane while still adhering to subresource alignment restrictions.
static_assert( D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT >= D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
&& ((D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) == 0),
"D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT must be >= and evenly divisible by D3D12_TEXTURE_DATA_PITCH_ALIGNMENT." );
Placement.RowPitch = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format)
? D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT )
: D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT );
if (pRowSizeInBytes)
{
UINT PlaneRowSize = 0;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, PlaneWidth, PlaneRowSize);
pRowSizeInBytes[uSubRes] = PlaneRowSize;
}
// Number of rows (accounting for block compression and additional planes)
UINT NumRows = 0;
if (D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format))
{
NumRows = PlaneHeight;
}
else
{
D3DX12_ASSERT(Height % HeightAlignment == 0);
NumRows = Height / HeightAlignment;
}
if (pNumRows)
{
pNumRows[uSubRes] = NumRows;
}
// Offsetting
if (pLayouts)
{
pLayouts[uSubRes].Offset = (bOverflow ? uint64_max : TotalBytes + BaseOffset);
}
const UINT16 NumSlices = Depth;
const UINT64 SubresourceSize = (NumRows * NumSlices - 1) * Placement.RowPitch + MinPlaneRowPitch;
// uint64 addition with overflow checking
TotalBytes = TotalBytes + SubresourceSize;
if(TotalBytes < SubresourceSize)
{
TotalBytes = uint64_max;
}
bResourceOverflow = bResourceOverflow || bOverflow;
}
// Overflow error
if (bResourceOverflow)
{
TotalBytes = uint64_max;
}
if (pLayouts)
{
memset( pLayouts + uSubRes, -1, sizeof( *pLayouts ) * (NumSubresources - uSubRes) );
}
if (pNumRows)
{
memset(pNumRows + uSubRes, -1, sizeof(*pNumRows) * (NumSubresources - uSubRes));
}
if (pRowSizeInBytes)
{
memset(pRowSizeInBytes + uSubRes, -1, sizeof(*pRowSizeInBytes) * (NumSubresources - uSubRes));
}
if (pTotalBytes)
{
*pTotalBytes = TotalBytes;
}
if(TotalBytes == uint64_max)
{
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------
inline D3D12_RESOURCE_DESC1 D3DX12ResourceDesc0ToDesc1(D3D12_RESOURCE_DESC const& desc0)
{
D3D12_RESOURCE_DESC1 desc1;
desc1.Dimension = desc0.Dimension;
desc1.Alignment = desc0.Alignment;
desc1.Width = desc0.Width;
desc1.Height = desc0.Height;
desc1.DepthOrArraySize = desc0.DepthOrArraySize;
desc1.MipLevels = desc0.MipLevels;
desc1.Format = desc0.Format;
desc1.SampleDesc.Count = desc0.SampleDesc.Count;
desc1.SampleDesc.Quality = desc0.SampleDesc.Quality;
desc1.Layout = desc0.Layout;
desc1.Flags = desc0.Flags;
desc1.SamplerFeedbackMipRegion.Width = 0;
desc1.SamplerFeedbackMipRegion.Height = 0;
desc1.SamplerFeedbackMipRegion.Depth = 0;
return desc1;
}
//------------------------------------------------------------------------------------------------
inline bool D3DX12GetCopyableFootprints(
_In_ const D3D12_RESOURCE_DESC& pResourceDesc,
_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
UINT64 BaseOffset,
_Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_Out_writes_opt_(NumSubresources) UINT* pNumRows,
_Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
_Out_opt_ UINT64* pTotalBytes)
{
// From D3D12_RESOURCE_DESC to D3D12_RESOURCE_DESC1
D3D12_RESOURCE_DESC1 desc = D3DX12ResourceDesc0ToDesc1(pResourceDesc);
return D3DX12GetCopyableFootprints(
*static_cast<CD3DX12_RESOURCE_DESC1*>(&desc),// From D3D12_RESOURCE_DESC1 to CD3DX12_RESOURCE_DESC1
FirstSubresource,
NumSubresources,
BaseOffset,
pLayouts,
pNumRows,
pRowSizeInBytes,
pTotalBytes);
}
#endif // D3D12_SDK_VERSION >= 606

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,790 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
#ifndef __cplusplus
#error D3DX12 requires C++
#endif
#include "d3d12.h"
//================================================================================================
// D3DX12 State Object Creation Helpers
//
// Helper classes for creating new style state objects out of an arbitrary set of subobjects.
// Uses STL
//
// Start by instantiating CD3DX12_STATE_OBJECT_DESC (see its public methods).
// One of its methods is CreateSubobject(), which has a comment showing a couple of options for
// defining subobjects using the helper classes for each subobject (CD3DX12_DXIL_LIBRARY_SUBOBJECT
// etc.). The subobject helpers each have methods specific to the subobject for configuring its
// contents.
//
//================================================================================================
#include <list>
#include <memory>
#include <string>
#include <vector>
#ifndef D3DX12_USE_ATL
#include <wrl/client.h>
#define D3DX12_COM_PTR Microsoft::WRL::ComPtr
#define D3DX12_COM_PTR_GET(x) x.Get()
#define D3DX12_COM_PTR_ADDRESSOF(x) x.GetAddressOf()
#else
#include <atlbase.h>
#define D3DX12_COM_PTR ATL::CComPtr
#define D3DX12_COM_PTR_GET(x) x.p
#define D3DX12_COM_PTR_ADDRESSOF(x) &x.p
#endif
//------------------------------------------------------------------------------------------------
class CD3DX12_STATE_OBJECT_DESC
{
public:
CD3DX12_STATE_OBJECT_DESC() noexcept
{
Init(D3D12_STATE_OBJECT_TYPE_COLLECTION);
}
CD3DX12_STATE_OBJECT_DESC(D3D12_STATE_OBJECT_TYPE Type) noexcept
{
Init(Type);
}
void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) noexcept { m_Desc.Type = Type; }
operator const D3D12_STATE_OBJECT_DESC&()
{
// Do final preparation work
m_RepointedAssociations.clear();
m_SubobjectArray.clear();
m_SubobjectArray.reserve(m_Desc.NumSubobjects);
// Flatten subobjects into an array (each flattened subobject still has a
// member that's a pointer to its desc that's not flattened)
for (auto Iter = m_SubobjectList.begin();
Iter != m_SubobjectList.end(); Iter++)
{
m_SubobjectArray.push_back(*Iter);
// Store new location in array so we can redirect pointers contained in subobjects
Iter->pSubobjectArrayLocation = &m_SubobjectArray.back();
}
// For subobjects with pointer fields, create a new copy of those subobject definitions
// with fixed pointers
for (UINT i = 0; i < m_Desc.NumSubobjects; i++)
{
if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION)
{
auto pOriginalSubobjectAssociation =
static_cast<const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION*>(m_SubobjectArray[i].pDesc);
D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION Repointed = *pOriginalSubobjectAssociation;
auto pWrapper =
static_cast<const SUBOBJECT_WRAPPER*>(pOriginalSubobjectAssociation->pSubobjectToAssociate);
Repointed.pSubobjectToAssociate = pWrapper->pSubobjectArrayLocation;
m_RepointedAssociations.push_back(Repointed);
m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back();
}
}
// Below: using ugly way to get pointer in case .data() is not defined
m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr;
return m_Desc;
}
operator const D3D12_STATE_OBJECT_DESC*()
{
// Cast calls the above final preparation work
return &static_cast<const D3D12_STATE_OBJECT_DESC&>(*this);
}
// CreateSubobject creates a sububject helper (e.g. CD3DX12_HIT_GROUP_SUBOBJECT)
// whose lifetime is owned by this class.
// e.g.
//
// CD3DX12_STATE_OBJECT_DESC Collection1(D3D12_STATE_OBJECT_TYPE_COLLECTION);
// auto Lib0 = Collection1.CreateSubobject<CD3DX12_DXIL_LIBRARY_SUBOBJECT>();
// Lib0->SetDXILLibrary(&pMyAppDxilLibs[0]);
// Lib0->DefineExport(L"rayGenShader0"); // in practice these export listings might be
// // data/engine driven
// etc.
//
// Alternatively, users can instantiate sububject helpers explicitly, such as via local
// variables instead, passing the state object desc that should point to it into the helper
// constructor (or call mySubobjectHelper.AddToStateObject(Collection1)).
// In this alternative scenario, the user must keep the subobject alive as long as the state
// object it is associated with is alive, else its pointer references will be stale.
// e.g.
//
// CD3DX12_STATE_OBJECT_DESC RaytracingState2(D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE);
// CD3DX12_DXIL_LIBRARY_SUBOBJECT LibA(RaytracingState2);
// LibA.SetDXILLibrary(&pMyAppDxilLibs[4]); // not manually specifying exports
// // - meaning all exports in the libraries
// // are exported
// etc.
template<typename T>
T* CreateSubobject()
{
T* pSubobject = new T(*this);
m_OwnedSubobjectHelpers.emplace_back(pSubobject);
return pSubobject;
}
private:
D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc)
{
SUBOBJECT_WRAPPER Subobject;
Subobject.pSubobjectArrayLocation = nullptr;
Subobject.Type = Type;
Subobject.pDesc = pDesc;
m_SubobjectList.push_back(Subobject);
m_Desc.NumSubobjects++;
return &m_SubobjectList.back();
}
void Init(D3D12_STATE_OBJECT_TYPE Type) noexcept
{
SetStateObjectType(Type);
m_Desc.pSubobjects = nullptr;
m_Desc.NumSubobjects = 0;
m_SubobjectList.clear();
m_SubobjectArray.clear();
m_RepointedAssociations.clear();
}
typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT
{
D3D12_STATE_SUBOBJECT* pSubobjectArrayLocation; // new location when flattened into array
// for repointing pointers in subobjects
} SUBOBJECT_WRAPPER;
D3D12_STATE_OBJECT_DESC m_Desc;
std::list<SUBOBJECT_WRAPPER> m_SubobjectList; // Pointers to list nodes handed out so
// these can be edited live
std::vector<D3D12_STATE_SUBOBJECT> m_SubobjectArray; // Built at the end, copying list contents
std::list<D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION>
m_RepointedAssociations; // subobject type that contains pointers to other subobjects,
// repointed to flattened array
class StringContainer
{
public:
LPCWSTR LocalCopy(LPCWSTR string, bool bSingleString = false)
{
if (string)
{
if (bSingleString)
{
m_Strings.clear();
m_Strings.push_back(string);
}
else
{
m_Strings.push_back(string);
}
return m_Strings.back().c_str();
}
else
{
return nullptr;
}
}
void clear() noexcept { m_Strings.clear(); }
private:
std::list<std::wstring> m_Strings;
};
class SUBOBJECT_HELPER_BASE
{
public:
SUBOBJECT_HELPER_BASE() noexcept { Init(); }
virtual ~SUBOBJECT_HELPER_BASE() = default;
virtual D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept = 0;
void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data());
}
protected:
virtual void* Data() noexcept = 0;
void Init() noexcept { m_pSubobject = nullptr; }
D3D12_STATE_SUBOBJECT* m_pSubobject;
};
#if(__cplusplus >= 201103L)
std::list<std::unique_ptr<const SUBOBJECT_HELPER_BASE>> m_OwnedSubobjectHelpers;
#else
class OWNED_HELPER
{
public:
OWNED_HELPER(const SUBOBJECT_HELPER_BASE* pHelper) noexcept { m_pHelper = pHelper; }
~OWNED_HELPER() { delete m_pHelper; }
const SUBOBJECT_HELPER_BASE* m_pHelper;
};
std::list<OWNED_HELPER> m_OwnedSubobjectHelpers;
#endif
friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT;
friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT;
friend class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT;
friend class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
friend class CD3DX12_HIT_GROUP_SUBOBJECT;
friend class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT;
friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT;
friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT;
friend class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT;
friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT;
friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT;
friend class CD3DX12_NODE_MASK_SUBOBJECT;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_DXIL_LIBRARY_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_DXIL_LIBRARY_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetDXILLibrary(const D3D12_SHADER_BYTECODE* pCode) noexcept
{
static const D3D12_SHADER_BYTECODE Default = {};
m_Desc.DXILLibrary = pCode ? *pCode : Default;
}
void DefineExport(
LPCWSTR Name,
LPCWSTR ExportToRename = nullptr,
D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE)
{
D3D12_EXPORT_DESC Export;
Export.Name = m_Strings.LocalCopy(Name);
Export.ExportToRename = m_Strings.LocalCopy(ExportToRename);
Export.Flags = Flags;
m_Exports.push_back(Export);
m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined
m_Desc.NumExports = static_cast<UINT>(m_Exports.size());
}
template<size_t N>
void DefineExports(LPCWSTR(&Exports)[N])
{
for (UINT i = 0; i < N; i++)
{
DefineExport(Exports[i]);
}
}
void DefineExports(const LPCWSTR* Exports, UINT N)
{
for (UINT i = 0; i < N; i++)
{
DefineExport(Exports[i]);
}
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_DXIL_LIBRARY_DESC&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
m_Strings.clear();
m_Exports.clear();
}
void* Data() noexcept override { return &m_Desc; }
D3D12_DXIL_LIBRARY_DESC m_Desc;
CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings;
std::vector<D3D12_EXPORT_DESC> m_Exports;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_EXISTING_COLLECTION_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_EXISTING_COLLECTION_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetExistingCollection(ID3D12StateObject*pExistingCollection) noexcept
{
m_Desc.pExistingCollection = pExistingCollection;
m_CollectionRef = pExistingCollection;
}
void DefineExport(
LPCWSTR Name,
LPCWSTR ExportToRename = nullptr,
D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE)
{
D3D12_EXPORT_DESC Export;
Export.Name = m_Strings.LocalCopy(Name);
Export.ExportToRename = m_Strings.LocalCopy(ExportToRename);
Export.Flags = Flags;
m_Exports.push_back(Export);
m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined
m_Desc.NumExports = static_cast<UINT>(m_Exports.size());
}
template<size_t N>
void DefineExports(LPCWSTR(&Exports)[N])
{
for (UINT i = 0; i < N; i++)
{
DefineExport(Exports[i]);
}
}
void DefineExports(const LPCWSTR* Exports, UINT N)
{
for (UINT i = 0; i < N; i++)
{
DefineExport(Exports[i]);
}
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_EXISTING_COLLECTION_DESC&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
m_CollectionRef = nullptr;
m_Strings.clear();
m_Exports.clear();
}
void* Data() noexcept override { return &m_Desc; }
D3D12_EXISTING_COLLECTION_DESC m_Desc;
D3DX12_COM_PTR<ID3D12StateObject> m_CollectionRef;
CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings;
std::vector<D3D12_EXPORT_DESC> m_Exports;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetSubobjectToAssociate(const D3D12_STATE_SUBOBJECT& SubobjectToAssociate) noexcept
{
m_Desc.pSubobjectToAssociate = &SubobjectToAssociate;
}
void AddExport(LPCWSTR Export)
{
m_Desc.NumExports++;
m_Exports.push_back(m_Strings.LocalCopy(Export));
m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined
}
template<size_t N>
void AddExports(LPCWSTR (&Exports)[N])
{
for (UINT i = 0; i < N; i++)
{
AddExport(Exports[i]);
}
}
void AddExports(const LPCWSTR* Exports, UINT N)
{
for (UINT i = 0; i < N; i++)
{
AddExport(Exports[i]);
}
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
m_Strings.clear();
m_Exports.clear();
}
void* Data() noexcept override { return &m_Desc; }
D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc;
CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings;
std::vector<LPCWSTR> m_Exports;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION() noexcept
{
Init();
}
CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetSubobjectNameToAssociate(LPCWSTR SubobjectToAssociate)
{
m_Desc.SubobjectToAssociate = m_SubobjectName.LocalCopy(SubobjectToAssociate, true);
}
void AddExport(LPCWSTR Export)
{
m_Desc.NumExports++;
m_Exports.push_back(m_Strings.LocalCopy(Export));
m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined
}
template<size_t N>
void AddExports(LPCWSTR (&Exports)[N])
{
for (UINT i = 0; i < N; i++)
{
AddExport(Exports[i]);
}
}
void AddExports(const LPCWSTR* Exports, UINT N)
{
for (UINT i = 0; i < N; i++)
{
AddExport(Exports[i]);
}
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
m_Strings.clear();
m_SubobjectName.clear();
m_Exports.clear();
}
void* Data() noexcept override { return &m_Desc; }
D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc;
CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings;
CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName;
std::vector<LPCWSTR> m_Exports;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_HIT_GROUP_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_HIT_GROUP_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetHitGroupExport(LPCWSTR exportName)
{
m_Desc.HitGroupExport = m_Strings[0].LocalCopy(exportName, true);
}
void SetHitGroupType(D3D12_HIT_GROUP_TYPE Type) noexcept { m_Desc.Type = Type; }
void SetAnyHitShaderImport(LPCWSTR importName)
{
m_Desc.AnyHitShaderImport = m_Strings[1].LocalCopy(importName, true);
}
void SetClosestHitShaderImport(LPCWSTR importName)
{
m_Desc.ClosestHitShaderImport = m_Strings[2].LocalCopy(importName, true);
}
void SetIntersectionShaderImport(LPCWSTR importName)
{
m_Desc.IntersectionShaderImport = m_Strings[3].LocalCopy(importName, true);
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_HIT_GROUP_DESC&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
for (UINT i = 0; i < m_NumStrings; i++)
{
m_Strings[i].clear();
}
}
void* Data() noexcept override { return &m_Desc; }
D3D12_HIT_GROUP_DESC m_Desc;
static constexpr UINT m_NumStrings = 4;
CD3DX12_STATE_OBJECT_DESC::StringContainer
m_Strings[m_NumStrings]; // one string for every entrypoint name
};
//------------------------------------------------------------------------------------------------
class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void Config(UINT MaxPayloadSizeInBytes, UINT MaxAttributeSizeInBytes) noexcept
{
m_Desc.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes;
m_Desc.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_RAYTRACING_SHADER_CONFIG&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
}
void* Data() noexcept override { return &m_Desc; }
D3D12_RAYTRACING_SHADER_CONFIG m_Desc;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void Config(UINT MaxTraceRecursionDepth) noexcept
{
m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
}
void* Data() noexcept override { return &m_Desc; }
D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void Config(UINT MaxTraceRecursionDepth, D3D12_RAYTRACING_PIPELINE_FLAGS Flags) noexcept
{
m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth;
m_Desc.Flags = Flags;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_RAYTRACING_PIPELINE_CONFIG1&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
}
void* Data() noexcept override { return &m_Desc; }
D3D12_RAYTRACING_PIPELINE_CONFIG1 m_Desc;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept
{
m_pRootSig = pRootSig;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_pRootSig = nullptr;
}
void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); }
D3DX12_COM_PTR<ID3D12RootSignature> m_pRootSig;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept
{
m_pRootSig = pRootSig;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_pRootSig = nullptr;
}
void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); }
D3DX12_COM_PTR<ID3D12RootSignature> m_pRootSig;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetFlags(D3D12_STATE_OBJECT_FLAGS Flags) noexcept
{
m_Desc.Flags = Flags;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_STATE_OBJECT_CONFIG&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
}
void* Data() noexcept override { return &m_Desc; }
D3D12_STATE_OBJECT_CONFIG m_Desc;
};
//------------------------------------------------------------------------------------------------
class CD3DX12_NODE_MASK_SUBOBJECT
: public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE
{
public:
CD3DX12_NODE_MASK_SUBOBJECT() noexcept
{
Init();
}
CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject)
{
Init();
AddToStateObject(ContainingStateObject);
}
void SetNodeMask(UINT NodeMask) noexcept
{
m_Desc.NodeMask = NodeMask;
}
D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override
{
return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK;
}
operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; }
operator const D3D12_NODE_MASK&() const noexcept { return m_Desc; }
private:
void Init() noexcept
{
SUBOBJECT_HELPER_BASE::Init();
m_Desc = {};
}
void* Data() noexcept override { return &m_Desc; }
D3D12_NODE_MASK m_Desc;
};
#undef D3DX12_COM_PTR
#undef D3DX12_COM_PTR_GET
#undef D3DX12_COM_PTR_ADDRESSOF

View File

@ -135,6 +135,8 @@ typedef enum DXGI_FORMAT
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190,
DXGI_FORMAT_A4B4G4R4_UNORM = 191,
DXGI_FORMAT_FORCE_UINT = 0xffffffff
} DXGI_FORMAT;

View File

@ -0,0 +1,195 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#ifndef __cplusplus
#error "This header requires C++"
#endif
constexpr inline bool ConstexprIsEqualGUID(REFGUID a, REFGUID b)
{
return a.Data1 == b.Data1 &&
a.Data2 == b.Data2 &&
a.Data3 == b.Data3 &&
a.Data4[0] == b.Data4[0] &&
a.Data4[1] == b.Data4[1] &&
a.Data4[2] == b.Data4[2] &&
a.Data4[3] == b.Data4[3] &&
a.Data4[4] == b.Data4[4] &&
a.Data4[5] == b.Data4[5] &&
a.Data4[6] == b.Data4[6] &&
a.Data4[7] == b.Data4[7];
}
template <typename T> GUID uuidof() = delete;
template <typename T> GUID uuidof(T*) { return uuidof<T>(); }
template <typename T> GUID uuidof(T**) { return uuidof<T>(); }
template <typename T> GUID uuidof(T&) { return uuidof<T>(); }
// Each COM interface (e.g. ID3D12Device) has a unique interface ID (IID) associated with it. With MSVC, the IID is defined
// along with the interface declaration using compiler intrinsics (__declspec(uuid(...)); the IID can then be retrieved
// using __uuidof. These intrinsics are not supported with all toolchains, so these helpers redefine IID values that can be
// used with the various adapter COM helpers (ComPtr, IID_PPV_ARGS, etc.) for Linux. IIDs are stable and cannot change, but as
// a precaution we statically assert the values are as expected when compiling for Windows.
#if defined(_MSC_VER)
#define _DXGUIDS_SUPPORT_STATIC_ASSERT_IID
#elif defined(__CRT_UUID_DECL)
/* match _mingw.h */
#if __cpp_constexpr >= 200704l && __cpp_inline_variables >= 201606L
#define _DXGUIDS_SUPPORT_STATIC_ASSERT_IID
#endif /* __cpp_constexpr >= 200704l && __cpp_inline_variables >= 201606L */
#endif /* _MSC_VER */
#ifdef _DXGUIDS_SUPPORT_STATIC_ASSERT_IID
#define _WINADAPTER_ASSERT_IID(InterfaceName) \
static_assert(ConstexprIsEqualGUID(uuidof<InterfaceName>(), __uuidof(InterfaceName)), "GUID definition mismatch: "#InterfaceName);
#else
#define _WINADAPTER_ASSERT_IID(InterfaceName)
#endif
#ifdef __CRT_UUID_DECL
#define WINADAPTER_IID(InterfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
template <> constexpr GUID uuidof<InterfaceName>() \
{ \
return { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }; \
} \
__CRT_UUID_DECL(InterfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
_WINADAPTER_ASSERT_IID(InterfaceName)
#else
#define WINADAPTER_IID(InterfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
template <> constexpr GUID uuidof<InterfaceName>() \
{ \
return { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }; \
} \
_WINADAPTER_ASSERT_IID(InterfaceName)
#endif /* defined(_WIN32) && defined(__MINGW32__) */
// Direct3D
#ifdef __d3d12_h__
WINADAPTER_IID(ID3D12Object, 0xc4fec28f, 0x7966, 0x4e95, 0x9f, 0x94, 0xf4, 0x31, 0xcb, 0x56, 0xc3, 0xb8);
WINADAPTER_IID(ID3D12DeviceChild, 0x905db94b, 0xa00c, 0x4140, 0x9d, 0xf5, 0x2b, 0x64, 0xca, 0x9e, 0xa3, 0x57);
WINADAPTER_IID(ID3D12RootSignature, 0xc54a6b66, 0x72df, 0x4ee8, 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14);
WINADAPTER_IID(ID3D12RootSignatureDeserializer, 0x34AB647B, 0x3CC8, 0x46AC, 0x84, 0x1B, 0xC0, 0x96, 0x56, 0x45, 0xC0, 0x46);
WINADAPTER_IID(ID3D12VersionedRootSignatureDeserializer, 0x7F91CE67, 0x090C, 0x4BB7, 0xB7, 0x8E, 0xED, 0x8F, 0xF2, 0xE3, 0x1D, 0xA0);
WINADAPTER_IID(ID3D12Pageable, 0x63ee58fb, 0x1268, 0x4835, 0x86, 0xda, 0xf0, 0x08, 0xce, 0x62, 0xf0, 0xd6);
WINADAPTER_IID(ID3D12Heap, 0x6b3b2502, 0x6e51, 0x45b3, 0x90, 0xee, 0x98, 0x84, 0x26, 0x5e, 0x8d, 0xf3);
WINADAPTER_IID(ID3D12Resource, 0x696442be, 0xa72e, 0x4059, 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad);
WINADAPTER_IID(ID3D12CommandAllocator, 0x6102dee4, 0xaf59, 0x4b09, 0xb9, 0x99, 0xb4, 0x4d, 0x73, 0xf0, 0x9b, 0x24);
WINADAPTER_IID(ID3D12Fence, 0x0a753dcf, 0xc4d8, 0x4b91, 0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76);
WINADAPTER_IID(ID3D12Fence1, 0x433685fe, 0xe22b, 0x4ca0, 0xa8, 0xdb, 0xb5, 0xb4, 0xf4, 0xdd, 0x0e, 0x4a);
WINADAPTER_IID(ID3D12PipelineState, 0x765a30f3, 0xf624, 0x4c6f, 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45);
WINADAPTER_IID(ID3D12DescriptorHeap, 0x8efb471d, 0x616c, 0x4f49, 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51);
WINADAPTER_IID(ID3D12QueryHeap, 0x0d9658ae, 0xed45, 0x469e, 0xa6, 0x1d, 0x97, 0x0e, 0xc5, 0x83, 0xca, 0xb4);
WINADAPTER_IID(ID3D12CommandSignature, 0xc36a797c, 0xec80, 0x4f0a, 0x89, 0x85, 0xa7, 0xb2, 0x47, 0x50, 0x82, 0xd1);
WINADAPTER_IID(ID3D12CommandList, 0x7116d91c, 0xe7e4, 0x47ce, 0xb8, 0xc6, 0xec, 0x81, 0x68, 0xf4, 0x37, 0xe5);
WINADAPTER_IID(ID3D12GraphicsCommandList, 0x5b160d0f, 0xac1b, 0x4185, 0x8b, 0xa8, 0xb3, 0xae, 0x42, 0xa5, 0xa4, 0x55);
WINADAPTER_IID(ID3D12GraphicsCommandList1, 0x553103fb, 0x1fe7, 0x4557, 0xbb, 0x38, 0x94, 0x6d, 0x7d, 0x0e, 0x7c, 0xa7);
WINADAPTER_IID(ID3D12GraphicsCommandList2, 0x38C3E585, 0xFF17, 0x412C, 0x91, 0x50, 0x4F, 0xC6, 0xF9, 0xD7, 0x2A, 0x28);
WINADAPTER_IID(ID3D12CommandQueue, 0x0ec870a6, 0x5d7e, 0x4c22, 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed);
WINADAPTER_IID(ID3D12Device, 0x189819f1, 0x1db6, 0x4b57, 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7);
WINADAPTER_IID(ID3D12PipelineLibrary, 0xc64226a8, 0x9201, 0x46af, 0xb4, 0xcc, 0x53, 0xfb, 0x9f, 0xf7, 0x41, 0x4f);
WINADAPTER_IID(ID3D12PipelineLibrary1, 0x80eabf42, 0x2568, 0x4e5e, 0xbd, 0x82, 0xc3, 0x7f, 0x86, 0x96, 0x1d, 0xc3);
WINADAPTER_IID(ID3D12Device1, 0x77acce80, 0x638e, 0x4e65, 0x88, 0x95, 0xc1, 0xf2, 0x33, 0x86, 0x86, 0x3e);
WINADAPTER_IID(ID3D12Device2, 0x30baa41e, 0xb15b, 0x475c, 0xa0, 0xbb, 0x1a, 0xf5, 0xc5, 0xb6, 0x43, 0x28);
WINADAPTER_IID(ID3D12Device3, 0x81dadc15, 0x2bad, 0x4392, 0x93, 0xc5, 0x10, 0x13, 0x45, 0xc4, 0xaa, 0x98);
WINADAPTER_IID(ID3D12ProtectedSession, 0xA1533D18, 0x0AC1, 0x4084, 0x85, 0xB9, 0x89, 0xA9, 0x61, 0x16, 0x80, 0x6B);
WINADAPTER_IID(ID3D12ProtectedResourceSession, 0x6CD696F4, 0xF289, 0x40CC, 0x80, 0x91, 0x5A, 0x6C, 0x0A, 0x09, 0x9C, 0x3D);
WINADAPTER_IID(ID3D12Device4, 0xe865df17, 0xa9ee, 0x46f9, 0xa4, 0x63, 0x30, 0x98, 0x31, 0x5a, 0xa2, 0xe5);
WINADAPTER_IID(ID3D12LifetimeOwner, 0xe667af9f, 0xcd56, 0x4f46, 0x83, 0xce, 0x03, 0x2e, 0x59, 0x5d, 0x70, 0xa8);
WINADAPTER_IID(ID3D12SwapChainAssistant, 0xf1df64b6, 0x57fd, 0x49cd, 0x88, 0x07, 0xc0, 0xeb, 0x88, 0xb4, 0x5c, 0x8f);
WINADAPTER_IID(ID3D12LifetimeTracker, 0x3fd03d36, 0x4eb1, 0x424a, 0xa5, 0x82, 0x49, 0x4e, 0xcb, 0x8b, 0xa8, 0x13);
WINADAPTER_IID(ID3D12StateObject, 0x47016943, 0xfca8, 0x4594, 0x93, 0xea, 0xaf, 0x25, 0x8b, 0x55, 0x34, 0x6d);
WINADAPTER_IID(ID3D12StateObjectProperties, 0xde5fa827, 0x9bf9, 0x4f26, 0x89, 0xff, 0xd7, 0xf5, 0x6f, 0xde, 0x38, 0x60);
WINADAPTER_IID(ID3D12Device5, 0x8b4f173b, 0x2fea, 0x4b80, 0x8f, 0x58, 0x43, 0x07, 0x19, 0x1a, 0xb9, 0x5d);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedDataSettings, 0x82BC481C, 0x6B9B, 0x4030, 0xAE, 0xDB, 0x7E, 0xE3, 0xD1, 0xDF, 0x1E, 0x63);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedDataSettings1, 0xDBD5AE51, 0x3317, 0x4F0A, 0xAD, 0xF9, 0x1D, 0x7C, 0xED, 0xCA, 0xAE, 0x0B);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedDataSettings2, 0x61552388, 0x01ab, 0x4008, 0xa4, 0x36, 0x83, 0xdb, 0x18, 0x95, 0x66, 0xea);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedData, 0x98931D33, 0x5AE8, 0x4791, 0xAA, 0x3C, 0x1A, 0x73, 0xA2, 0x93, 0x4E, 0x71);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedData1, 0x9727A022, 0xCF1D, 0x4DDA, 0x9E, 0xBA, 0xEF, 0xFA, 0x65, 0x3F, 0xC5, 0x06);
WINADAPTER_IID(ID3D12DeviceRemovedExtendedData2, 0x67FC5816, 0xE4CA, 0x4915, 0xBF, 0x18, 0x42, 0x54, 0x12, 0x72, 0xDA, 0x54);
WINADAPTER_IID(ID3D12Device6, 0xc70b221b, 0x40e4, 0x4a17, 0x89, 0xaf, 0x02, 0x5a, 0x07, 0x27, 0xa6, 0xdc);
WINADAPTER_IID(ID3D12ProtectedResourceSession1, 0xD6F12DD6, 0x76FB, 0x406E, 0x89, 0x61, 0x42, 0x96, 0xEE, 0xFC, 0x04, 0x09);
WINADAPTER_IID(ID3D12Device7, 0x5c014b53, 0x68a1, 0x4b9b, 0x8b, 0xd1, 0xdd, 0x60, 0x46, 0xb9, 0x35, 0x8b);
WINADAPTER_IID(ID3D12Device8, 0x9218E6BB, 0xF944, 0x4F7E, 0xA7, 0x5C, 0xB1, 0xB2, 0xC7, 0xB7, 0x01, 0xF3);
WINADAPTER_IID(ID3D12Resource1, 0x9D5E227A, 0x4430, 0x4161, 0x88, 0xB3, 0x3E, 0xCA, 0x6B, 0xB1, 0x6E, 0x19);
WINADAPTER_IID(ID3D12Resource2, 0xBE36EC3B, 0xEA85, 0x4AEB, 0xA4, 0x5A, 0xE9, 0xD7, 0x64, 0x04, 0xA4, 0x95);
WINADAPTER_IID(ID3D12Heap1, 0x572F7389, 0x2168, 0x49E3, 0x96, 0x93, 0xD6, 0xDF, 0x58, 0x71, 0xBF, 0x6D);
WINADAPTER_IID(ID3D12GraphicsCommandList3, 0x6FDA83A7, 0xB84C, 0x4E38, 0x9A, 0xC8, 0xC7, 0xBD, 0x22, 0x01, 0x6B, 0x3D);
WINADAPTER_IID(ID3D12MetaCommand, 0xDBB84C27, 0x36CE, 0x4FC9, 0xB8, 0x01, 0xF0, 0x48, 0xC4, 0x6A, 0xC5, 0x70);
WINADAPTER_IID(ID3D12GraphicsCommandList4, 0x8754318e, 0xd3a9, 0x4541, 0x98, 0xcf, 0x64, 0x5b, 0x50, 0xdc, 0x48, 0x74);
WINADAPTER_IID(ID3D12ShaderCacheSession, 0x28e2495d, 0x0f64, 0x4ae4, 0xa6, 0xec, 0x12, 0x92, 0x55, 0xdc, 0x49, 0xa8);
WINADAPTER_IID(ID3D12Device9, 0x4c80e962, 0xf032, 0x4f60, 0xbc, 0x9e, 0xeb, 0xc2, 0xcf, 0xa1, 0xd8, 0x3c);
WINADAPTER_IID(ID3D12Device10, 0x517f8718, 0xaa66, 0x49f9, 0xb0, 0x2b, 0xa7, 0xab, 0x89, 0xc0, 0x60, 0x31);
WINADAPTER_IID(ID3D12Device11, 0x5405c344, 0xd457, 0x444e, 0xb4, 0xdd, 0x23, 0x66, 0xe4, 0x5a, 0xee, 0x39);
WINADAPTER_IID(ID3D12VirtualizationGuestDevice, 0xbc66d368, 0x7373, 0x4943, 0x87, 0x57, 0xfc, 0x87, 0xdc, 0x79, 0xe4, 0x76);
WINADAPTER_IID(ID3D12Tools, 0x7071e1f0, 0xe84b, 0x4b33, 0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5);
WINADAPTER_IID(ID3D12SDKConfiguration, 0xe9eb5314, 0x33aa, 0x42b2, 0xa7, 0x18, 0xd7, 0x7f, 0x58, 0xb1, 0xf1, 0xc7);
WINADAPTER_IID(ID3D12SDKConfiguration1, 0x8aaf9303, 0xad25, 0x48b9, 0x9a, 0x57, 0xd9, 0xc3, 0x7e, 0x00, 0x9d, 0x9f);
WINADAPTER_IID(ID3D12DeviceFactory, 0x61f307d3, 0xd34e, 0x4e7c, 0x83, 0x74, 0x3b, 0xa4, 0xde, 0x23, 0xcc, 0xcb);
WINADAPTER_IID(ID3D12DeviceConfiguration, 0x78dbf87b, 0xf766, 0x422b, 0xa6, 0x1c, 0xc8, 0xc4, 0x46, 0xbd, 0xb9, 0xad);
WINADAPTER_IID(ID3D12GraphicsCommandList5, 0x55050859, 0x4024, 0x474c, 0x87, 0xf5, 0x64, 0x72, 0xea, 0xee, 0x44, 0xea);
WINADAPTER_IID(ID3D12GraphicsCommandList6, 0xc3827890, 0xe548, 0x4cfa, 0x96, 0xcf, 0x56, 0x89, 0xa9, 0x37, 0x0f, 0x80);
WINADAPTER_IID(ID3D12GraphicsCommandList7, 0xdd171223, 0x8b61, 0x4769, 0x90, 0xe3, 0x16, 0x0c, 0xcd, 0xe4, 0xe2, 0xc1);
WINADAPTER_IID(ID3D12GraphicsCommandList8, 0xee936ef9, 0x599d, 0x4d28, 0x93, 0x8e, 0x23, 0xc4, 0xad, 0x05, 0xce, 0x51);
#endif
// Direct3D Video
#ifdef __d3d12video_h__
WINADAPTER_IID(ID3D12VideoDecoderHeap,0x0946B7C9,0xEBF6,0x4047,0xBB,0x73,0x86,0x83,0xE2,0x7D,0xBB,0x1F);
WINADAPTER_IID(ID3D12VideoDevice,0x1F052807,0x0B46,0x4ACC,0x8A,0x89,0x36,0x4F,0x79,0x37,0x18,0xA4);
WINADAPTER_IID(ID3D12VideoDecoder,0xC59B6BDC,0x7720,0x4074,0xA1,0x36,0x17,0xA1,0x56,0x03,0x74,0x70);
WINADAPTER_IID(ID3D12VideoProcessor,0x304FDB32,0xBEDE,0x410A,0x85,0x45,0x94,0x3A,0xC6,0xA4,0x61,0x38);
WINADAPTER_IID(ID3D12VideoDecodeCommandList,0x3B60536E,0xAD29,0x4E64,0xA2,0x69,0xF8,0x53,0x83,0x7E,0x5E,0x53);
WINADAPTER_IID(ID3D12VideoProcessCommandList,0xAEB2543A,0x167F,0x4682,0xAC,0xC8,0xD1,0x59,0xED,0x4A,0x62,0x09);
WINADAPTER_IID(ID3D12VideoDecodeCommandList1,0xD52F011B,0xB56E,0x453C,0xA0,0x5A,0xA7,0xF3,0x11,0xC8,0xF4,0x72);
WINADAPTER_IID(ID3D12VideoProcessCommandList1,0x542C5C4D,0x7596,0x434F,0x8C,0x93,0x4E,0xFA,0x67,0x66,0xF2,0x67);
WINADAPTER_IID(ID3D12VideoMotionEstimator,0x33FDAE0E,0x098B,0x428F,0x87,0xBB,0x34,0xB6,0x95,0xDE,0x08,0xF8);
WINADAPTER_IID(ID3D12VideoMotionVectorHeap,0x5BE17987,0x743A,0x4061,0x83,0x4B,0x23,0xD2,0x2D,0xAE,0xA5,0x05);
WINADAPTER_IID(ID3D12VideoDevice1,0x981611AD,0xA144,0x4C83,0x98,0x90,0xF3,0x0E,0x26,0xD6,0x58,0xAB);
WINADAPTER_IID(ID3D12VideoEncodeCommandList,0x8455293A,0x0CBD,0x4831,0x9B,0x39,0xFB,0xDB,0xAB,0x72,0x47,0x23);
WINADAPTER_IID(ID3D12VideoDecoder1,0x79A2E5FB,0xCCD2,0x469A,0x9F,0xDE,0x19,0x5D,0x10,0x95,0x1F,0x7E);
WINADAPTER_IID(ID3D12VideoDecoderHeap1,0xDA1D98C5,0x539F,0x41B2,0xBF,0x6B,0x11,0x98,0xA0,0x3B,0x6D,0x26);
WINADAPTER_IID(ID3D12VideoProcessor1,0xF3CFE615,0x553F,0x425C,0x86,0xD8,0xEE,0x8C,0x1B,0x1F,0xB0,0x1C);
WINADAPTER_IID(ID3D12VideoExtensionCommand,0x554E41E8,0xAE8E,0x4A8C,0xB7,0xD2,0x5B,0x4F,0x27,0x4A,0x30,0xE4);
WINADAPTER_IID(ID3D12VideoDevice2,0xF019AC49,0xF838,0x4A95,0x9B,0x17,0x57,0x94,0x37,0xC8,0xF5,0x13);
WINADAPTER_IID(ID3D12VideoDecodeCommandList2,0x6e120880,0xc114,0x4153,0x80,0x36,0xd2,0x47,0x05,0x1e,0x17,0x29);
WINADAPTER_IID(ID3D12VideoDecodeCommandList3,0x2aee8c37,0x9562,0x42da,0x8a,0xbf,0x61,0xef,0xeb,0x2e,0x45,0x13);
WINADAPTER_IID(ID3D12VideoProcessCommandList2,0xdb525ae4,0x6ad6,0x473c,0xba,0xa7,0x59,0xb2,0xe3,0x70,0x82,0xe4);
WINADAPTER_IID(ID3D12VideoProcessCommandList3,0x1a0a4ca4,0x9f08,0x40ce,0x95,0x58,0xb4,0x11,0xfd,0x26,0x66,0xff);
WINADAPTER_IID(ID3D12VideoEncodeCommandList1,0x94971eca,0x2bdb,0x4769,0x88,0xcf,0x36,0x75,0xea,0x75,0x7e,0xbc);
WINADAPTER_IID(ID3D12VideoEncoder,0x2E0D212D,0x8DF9,0x44A6,0xA7,0x70,0xBB,0x28,0x9B,0x18,0x27,0x37);
WINADAPTER_IID(ID3D12VideoEncoderHeap,0x22B35D96,0x876A,0x44C0,0xB2,0x5E,0xFB,0x8C,0x9C,0x7F,0x1C,0x4A);
WINADAPTER_IID(ID3D12VideoDevice3,0x4243ADB4,0x3A32,0x4666,0x97,0x3C,0x0C,0xCC,0x56,0x25,0xDC,0x44);
WINADAPTER_IID(ID3D12VideoEncodeCommandList2,0x895491e2,0xe701,0x46a9,0x9a,0x1f,0x8d,0x34,0x80,0xed,0x86,0x7a);
WINADAPTER_IID(ID3D12VideoEncodeCommandList3,0x7f027b22,0x1515,0x4e85,0xaa,0x0d,0x02,0x64,0x86,0x58,0x05,0x76);
#endif
#ifdef __d3d12sdklayers_h__
WINADAPTER_IID(ID3D12Debug, 0x344488b7, 0x6846, 0x474b, 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0);
WINADAPTER_IID(ID3D12Debug1, 0xaffaa4ca, 0x63fe, 0x4d8e, 0xb8, 0xad, 0x15, 0x90, 0x00, 0xaf, 0x43, 0x04);
WINADAPTER_IID(ID3D12Debug2, 0x93a665c4, 0xa3b2, 0x4e5d, 0xb6, 0x92, 0xa2, 0x6a, 0xe1, 0x4e, 0x33, 0x74);
WINADAPTER_IID(ID3D12Debug3, 0x5cf4e58f, 0xf671, 0x4ff1, 0xa5, 0x42, 0x36, 0x86, 0xe3, 0xd1, 0x53, 0xd1);
WINADAPTER_IID(ID3D12Debug4, 0x014b816e, 0x9ec5, 0x4a2f, 0xa8, 0x45, 0xff, 0xbe, 0x44, 0x1c, 0xe1, 0x3a);
WINADAPTER_IID(ID3D12Debug5, 0x548d6b12, 0x09fa, 0x40e0, 0x90, 0x69, 0x5d, 0xcd, 0x58, 0x9a, 0x52, 0xc9);
WINADAPTER_IID(ID3D12Debug6, 0x82a816d6, 0x5d01, 0x4157, 0x97, 0xd0, 0x49, 0x75, 0x46, 0x3f, 0xd1, 0xed);
WINADAPTER_IID(ID3D12DebugDevice1, 0xa9b71770, 0xd099, 0x4a65, 0xa6, 0x98, 0x3d, 0xee, 0x10, 0x02, 0x0f, 0x88);
WINADAPTER_IID(ID3D12DebugDevice, 0x3febd6dd, 0x4973, 0x4787, 0x81, 0x94, 0xe4, 0x5f, 0x9e, 0x28, 0x92, 0x3e);
WINADAPTER_IID(ID3D12DebugDevice2, 0x60eccbc1, 0x378d, 0x4df1, 0x89, 0x4c, 0xf8, 0xac, 0x5c, 0xe4, 0xd7, 0xdd);
WINADAPTER_IID(ID3D12DebugCommandQueue, 0x09e0bf36, 0x54ac, 0x484f, 0x88, 0x47, 0x4b, 0xae, 0xea, 0xb6, 0x05, 0x3a);
WINADAPTER_IID(ID3D12DebugCommandQueue1, 0x16be35a2, 0xbfd6, 0x49f2, 0xbc, 0xae, 0xea, 0xae, 0x4a, 0xff, 0x86, 0x2d);
WINADAPTER_IID(ID3D12DebugCommandList1, 0x102ca951, 0x311b, 0x4b01, 0xb1, 0x1f, 0xec, 0xb8, 0x3e, 0x06, 0x1b, 0x37);
WINADAPTER_IID(ID3D12DebugCommandList, 0x09e0bf36, 0x54ac, 0x484f, 0x88, 0x47, 0x4b, 0xae, 0xea, 0xb6, 0x05, 0x3f);
WINADAPTER_IID(ID3D12DebugCommandList2, 0xaeb575cf, 0x4e06, 0x48be, 0xba, 0x3b, 0xc4, 0x50, 0xfc, 0x96, 0x65, 0x2e);
WINADAPTER_IID(ID3D12DebugCommandList3, 0x197d5e15, 0x4d37, 0x4d34, 0xaf, 0x78, 0x72, 0x4c, 0xd7, 0x0f, 0xdb, 0x1f);
WINADAPTER_IID(ID3D12SharingContract, 0x0adf7d52, 0x929c, 0x4e61, 0xad, 0xdb, 0xff, 0xed, 0x30, 0xde, 0x66, 0xef);
WINADAPTER_IID(ID3D12InfoQueue, 0x0742a90b, 0xc387, 0x483f, 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58);
WINADAPTER_IID(ID3D12InfoQueue1, 0x2852dd88, 0xb484, 0x4c0c, 0xb6, 0xb1, 0x67, 0x16, 0x85, 0x00, 0xe6, 0x00);
#endif
// DXCore
#ifdef __dxcore_interface_h__
WINADAPTER_IID(IDXCoreAdapterFactory, 0x78ee5945, 0xc36e, 0x4b13, 0xa6, 0x69, 0x00, 0x5d, 0xd1, 0x1c, 0x0f, 0x06);
WINADAPTER_IID(IDXCoreAdapterList, 0x526c7776, 0x40e9, 0x459b, 0xb7, 0x11, 0xf3, 0x2a, 0xd7, 0x6d, 0xfc, 0x28);
WINADAPTER_IID(IDXCoreAdapter, 0xf0db4c7f, 0xfe5a, 0x42a2, 0xbd, 0x62, 0xf2, 0xa6, 0xcf, 0x6f, 0xc8, 0x3e);
#endif