From 97061dd7ee40d3ab82caff5485065a5e25016147 Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Wed, 11 Jan 2023 12:28:34 -0500 Subject: [PATCH] d3d12: Add support for Xbox GDK. The big items in this patch: - New screen file, to support the Xbox "windowing" system - Lots of small macros/changes to support the Xbox D3D12 API without messing with the Win32 path too much - A few changes to avoid requiring COM interfaces (the big one was QueryInterface which is unsupported) Co-authored-by: Ethan Lee Co-authored-by: David Jacewicz Co-authored-by: tieuchanlong Reviewed-by: Jesse Natalie Part-of: --- src/gallium/drivers/d3d12/d3d12_batch.cpp | 2 + src/gallium/drivers/d3d12/d3d12_common.h | 19 +++ src/gallium/drivers/d3d12/d3d12_context.cpp | 4 + src/gallium/drivers/d3d12/d3d12_context.h | 2 + src/gallium/drivers/d3d12/d3d12_draw.cpp | 5 +- .../drivers/d3d12/d3d12_dxgi_xbox_screen.cpp | 137 ++++++++++++++++++ src/gallium/drivers/d3d12/d3d12_fence.cpp | 4 +- src/gallium/drivers/d3d12/d3d12_resource.cpp | 30 +++- .../drivers/d3d12/d3d12_root_signature.cpp | 15 +- src/gallium/drivers/d3d12/d3d12_screen.cpp | 81 ++++++++++- src/gallium/drivers/d3d12/d3d12_screen.h | 8 + src/gallium/drivers/d3d12/meson.build | 11 +- 12 files changed, 296 insertions(+), 22 deletions(-) create mode 100644 src/gallium/drivers/d3d12/d3d12_dxgi_xbox_screen.cpp diff --git a/src/gallium/drivers/d3d12/d3d12_batch.cpp b/src/gallium/drivers/d3d12/d3d12_batch.cpp index 40394a0f82d..465adf8da0c 100644 --- a/src/gallium/drivers/d3d12/d3d12_batch.cpp +++ b/src/gallium/drivers/d3d12/d3d12_batch.cpp @@ -235,7 +235,9 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) mtx_lock(&screen->submit_mutex); +#ifndef _GAMING_XBOX d3d12_process_batch_residency(screen, batch); +#endif bool has_state_fixup = d3d12_context_state_resolve_submission(ctx, batch); diff --git a/src/gallium/drivers/d3d12/d3d12_common.h b/src/gallium/drivers/d3d12/d3d12_common.h index 749979071ff..42857dda755 100644 --- a/src/gallium/drivers/d3d12/d3d12_common.h +++ b/src/gallium/drivers/d3d12/d3d12_common.h @@ -33,8 +33,27 @@ #endif #define D3D12_IGNORE_SDK_LAYERS +#ifndef _GAMING_XBOX #include #include +#elif defined(__cplusplus) +#ifdef _GAMING_XBOX_SCARLETT +#include +#include +#else +#include +#include +#endif +#ifdef IID_PPV_ARGS +#undef IID_PPV_ARGS +#endif +#define IID_PPV_ARGS IID_GRAPHICS_PPV_ARGS +#define D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT (D3D12_HEAP_FLAGS) 0x800 +#endif /* _GAMING_XBOX */ + +#ifndef D3D12_TEXTURE_DATA_PITCH_ALIGNMENT +#define D3D12_TEXTURE_DATA_PITCH_ALIGNMENT D3D12XBOX_TEXTURE_DATA_PITCH_ALIGNMENT +#endif /* D3D12_TEXTURE_DATA_PITCH_ALIGNMENT */ #if defined(__cplusplus) #if !defined(_WIN32) || defined(_MSC_VER) || D3D12_SDK_VERSION < 606 diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index c03909cd691..933c2956a94 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -76,8 +76,10 @@ d3d12_context_destroy(struct pipe_context *pctx) dxil_destroy_validator(ctx->dxil_validator); #endif +#ifndef _GAMING_XBOX if (ctx->dev_config) ctx->dev_config->Release(); +#endif if (ctx->timestamp_query) pctx->destroy_query(pctx, ctx->timestamp_query); @@ -2546,7 +2548,9 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->D3D12SerializeVersionedRootSignature = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)util_dl_get_proc_address(screen->d3d12_mod, "D3D12SerializeVersionedRootSignature"); +#ifndef _GAMING_XBOX (void)screen->dev->QueryInterface(&ctx->dev_config); +#endif ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull; diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index c28a778dbd3..27ff9ba80d9 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -255,7 +255,9 @@ struct d3d12_context { struct d3d12_descriptor_handle null_sampler; PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature; +#ifndef _GAMING_XBOX ID3D12DeviceConfiguration *dev_config; +#endif #ifdef _WIN32 struct dxil_validator *dxil_validator; #endif diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index cccc3372e29..77d514801e1 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -41,10 +41,7 @@ #include "util/u_prim_restart.h" #include "util/u_math.h" -static const D3D12_RECT MAX_SCISSOR = { D3D12_VIEWPORT_BOUNDS_MIN, - D3D12_VIEWPORT_BOUNDS_MIN, - D3D12_VIEWPORT_BOUNDS_MAX, - D3D12_VIEWPORT_BOUNDS_MAX }; +static const D3D12_RECT MAX_SCISSOR = { 0, 0, 16384, 16384 }; static const D3D12_RECT MAX_SCISSOR_ARRAY[] = { MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, diff --git a/src/gallium/drivers/d3d12/d3d12_dxgi_xbox_screen.cpp b/src/gallium/drivers/d3d12/d3d12_dxgi_xbox_screen.cpp new file mode 100644 index 00000000000..6e6104962fb --- /dev/null +++ b/src/gallium/drivers/d3d12/d3d12_dxgi_xbox_screen.cpp @@ -0,0 +1,137 @@ +/* + * Copyright © Microsoft Corporation + * + * 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 (including the next + * paragraph) 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 + +#include "d3d12_screen.h" +#include "d3d12_public.h" +#include "d3d12_debug.h" + +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "util/u_dl.h" + +static const char* +dxgi_get_name(struct pipe_screen *screen) +{ + struct d3d12_dxgi_screen *dxgi_screen = d3d12_dxgi_screen(d3d12_screen(screen)); + static char buf[1000]; + if (dxgi_screen->description[0] == L'\0') + return "D3D12 (Unknown)"; + + snprintf(buf, sizeof(buf), "D3D12 (%S)", dxgi_screen->description); + return buf; +} + +static void +dxgi_get_memory_info(struct d3d12_screen *screen, struct d3d12_memory_info *output) +{ + assert(0); +} + +static void +d3d12_deinit_dxgi_screen(struct d3d12_screen *dscreen) +{ + d3d12_deinit_screen(dscreen); + struct d3d12_dxgi_screen *screen = d3d12_dxgi_screen(dscreen); + if (screen->adapter) { + screen->adapter->Release(); + screen->adapter = nullptr; + } +} + +static void +d3d12_destroy_dxgi_screen(struct pipe_screen *pscreen) +{ + struct d3d12_screen *screen = d3d12_screen(pscreen); + d3d12_deinit_dxgi_screen(screen); + d3d12_destroy_screen(screen); +} + +static bool +d3d12_init_dxgi_screen(struct d3d12_screen *dscreen) +{ + if (!d3d12_init_screen(dscreen, NULL)) { + debug_printf("D3D12: failed to initialize DXGI screen\n"); + return false; + } + + struct d3d12_dxgi_screen *screen = d3d12_dxgi_screen(dscreen); + IDXGIDevice1 *dxgiDevice = nullptr; + + if (FAILED(dscreen->dev->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))) { + debug_printf("D3D12: failed to query dxgi interface\n"); + return false; + } + + if (FAILED(dxgiDevice->GetAdapter(&screen->adapter))) { + debug_printf("D3D12: failed to get adapter\n"); + return false; + } + + dxgiDevice->Release(); + dxgiDevice = nullptr; + + DXGI_ADAPTER_DESC adapter_desc = {}; + HRESULT res = screen->adapter->GetDesc(&adapter_desc); + if (FAILED(res)) { + debug_printf("D3D12: failed to retrieve adapter description\n"); + return false; + } + + screen->base.driver_version = 0; + screen->base.vendor_id = adapter_desc.VendorId; + screen->base.device_id = adapter_desc.DeviceId; + screen->base.subsys_id = adapter_desc.SubSysId; + screen->base.revision = adapter_desc.Revision; + // Note: memory sizes in bytes, but stored in size_t, so may be capped at 4GB. + // In that case, adding before conversion to MB can easily overflow. + screen->base.memory_size_megabytes = (adapter_desc.DedicatedVideoMemory >> 20) + + (adapter_desc.DedicatedSystemMemory >> 20) + + (adapter_desc.SharedSystemMemory >> 20); + wcsncpy(screen->description, adapter_desc.Description, ARRAY_SIZE(screen->description)); + screen->base.base.get_name = dxgi_get_name; + screen->base.get_memory_info = dxgi_get_memory_info; + + return true; +} + +struct pipe_screen* + d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid) +{ + struct d3d12_dxgi_screen *screen = CALLOC_STRUCT(d3d12_dxgi_screen); + if (!screen) + return nullptr; + + d3d12_init_screen_base(&screen->base, winsys, adapter_luid); + screen->base.base.destroy = d3d12_destroy_dxgi_screen; + screen->base.init = d3d12_init_dxgi_screen; + screen->base.deinit = d3d12_deinit_dxgi_screen; + + if (!d3d12_init_dxgi_screen(&screen->base)) { + d3d12_destroy_dxgi_screen(&screen->base.base); + return nullptr; + } + + return &screen->base.base; +} diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp index 38ed7ad4a15..c496c9fa9d4 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.cpp +++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp @@ -49,10 +49,10 @@ d3d12_create_fence(struct d3d12_screen *screen) ret->cmdqueue_fence = screen->fence; ret->value = ++screen->fence_value; ret->event = d3d12_fence_create_event(&ret->event_fd); - if (FAILED(screen->fence->SetEventOnCompletion(ret->value, ret->event))) - goto fail; if (FAILED(screen->cmdqueue->Signal(screen->fence, ret->value))) goto fail; + if (FAILED(screen->fence->SetEventOnCompletion(ret->value, ret->event))) + goto fail; pipe_reference_init(&ret->reference, 1); return ret; diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp index 957d14c0b2a..50b7adc78e7 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp @@ -41,8 +41,10 @@ #include #include +#ifndef _GAMING_XBOX #include using Microsoft::WRL::ComPtr; +#endif #ifndef GENERIC_ALL // This is only added to winadapter.h in newer DirectX-Headers @@ -462,6 +464,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen, HANDLE d3d_handle = (HANDLE) (intptr_t) handle->handle; #endif +#ifndef _GAMING_XBOX if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) { ComPtr screen_device; ComPtr res_device; @@ -487,6 +490,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen, } } } +#endif #ifdef _WIN32 HANDLE d3d_handle_to_close = nullptr; @@ -501,10 +505,11 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen, if (res->bo) { d3d12_res = res->bo->res; } else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) { - IUnknown *obj = (IUnknown *)handle->com_obj; - (void)obj->QueryInterface(&d3d12_res); - (void)obj->QueryInterface(&d3d12_heap); - obj->Release(); + if (handle->modifier == 1) { + d3d12_heap = (ID3D12Heap *) handle->com_obj; + } else { + d3d12_res = (ID3D12Resource *) handle->com_obj; + } } else { screen->dev->OpenSharedHandle(d3d_handle, IID_PPV_ARGS(&d3d12_res)); } @@ -892,7 +897,12 @@ d3d12_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handl } struct d3d12_screen *screen = d3d12_screen(pscreen); - IUnknown *obj; +#ifdef _GAMING_XBOX + IGraphicsUnknown +#else + IUnknown +#endif + *obj; #ifdef _WIN32 HANDLE d3d_handle = handle->handle; #else @@ -927,8 +937,13 @@ d3d12_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handl } memobj->base.dedicated = dedicated; - (void)obj->QueryInterface(&memobj->res); - (void)obj->QueryInterface(&memobj->heap); + obj->AddRef(); + if (handle->modifier == 1) { + memobj->heap = (ID3D12Heap *) obj; + } else { + memobj->res = (ID3D12Resource *) obj; + } + obj->Release(); if (!memobj->res && !memobj->heap) { debug_printf("d3d12: Memory object isn't a resource or heap\n"); @@ -969,6 +984,7 @@ d3d12_resource_from_memobj(struct pipe_screen *pscreen, whandle.com_obj = memobj->res ? (void *) memobj->res : (void *) memobj->heap; whandle.offset = offset; whandle.format = templ->format; + whandle.modifier = memobj->res ? 0 : 1; // WINSYS_HANDLE_TYPE_D3D12_RES implies taking ownership of the reference ((IUnknown *)whandle.com_obj)->AddRef(); diff --git a/src/gallium/drivers/d3d12/d3d12_root_signature.cpp b/src/gallium/drivers/d3d12/d3d12_root_signature.cpp index 8cdaaddee86..4cb20dd5a16 100644 --- a/src/gallium/drivers/d3d12/d3d12_root_signature.cpp +++ b/src/gallium/drivers/d3d12/d3d12_root_signature.cpp @@ -21,6 +21,9 @@ * IN THE SOFTWARE. */ +#include +using Microsoft::WRL::ComPtr; + #include "d3d12_root_signature.h" #include "d3d12_compiler.h" #include "d3d12_screen.h" @@ -29,9 +32,6 @@ #include -#include -using Microsoft::WRL::ComPtr; - struct d3d12_root_signature { struct d3d12_root_signature_key key; ID3D12RootSignature *sig; @@ -83,11 +83,15 @@ init_range(D3D12_DESCRIPTOR_RANGE1 *range, range->NumDescriptors = num_descs; range->BaseShaderRegister = base_shader_register; range->RegisterSpace = register_space; +#ifdef _GAMING_XBOX + range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; +#else if (type == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER || type == D3D12_DESCRIPTOR_RANGE_TYPE_UAV) range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; else range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS; +#endif range->OffsetInDescriptorsFromTableStart = offset_from_start; } @@ -208,13 +212,16 @@ create_root_signature(struct d3d12_context *ctx, struct d3d12_root_signature_key root_sig_desc.Desc_1_1.Flags |= D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT; ComPtr sig, error; +#ifndef _GAMING_XBOX if (ctx->dev_config) { if (FAILED(ctx->dev_config->SerializeVersionedRootSignature(&root_sig_desc, &sig, &error))) { debug_printf("D3D12SerializeRootSignature failed\n"); return NULL; } - } else { + } else +#endif + { if (FAILED(ctx->D3D12SerializeVersionedRootSignature(&root_sig_desc, &sig, &error))) { debug_printf("D3D12SerializeRootSignature failed\n"); diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index 5eb19b9b1ba..d3757c9a65e 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -51,7 +51,9 @@ #include "nir_to_dxil.h" #include "git_sha1.h" +#ifndef _GAMING_XBOX #include +#endif #include static GUID OpenGLOn12CreatorID = { 0x6bb3cd34, 0x0d19, 0x45ab, { 0x97, 0xed, 0xd7, 0x20, 0xba, 0x3d, 0xfc, 0x80 } }; @@ -783,7 +785,7 @@ d3d12_flush_frontbuffer(struct pipe_screen * pscreen, winsys->displaytarget_unmap(winsys, res->dt); } -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_GAMING_XBOX) // WindowFromDC is Windows-only, and this method requires an HWND, so only use it on Windows ID3D12SharingContract *sharing_contract; if (SUCCEEDED(screen->cmdqueue->QueryInterface(IID_PPV_ARGS(&sharing_contract)))) { @@ -796,6 +798,7 @@ d3d12_flush_frontbuffer(struct pipe_screen * pscreen, winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box); } +#ifndef _GAMING_XBOX static ID3D12Debug * get_debug_interface(util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) { @@ -845,6 +848,52 @@ enable_gpu_validation(util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) debug->Release(); } } +#endif + +#ifdef _GAMING_XBOX + +static ID3D12Device3 * +create_device(util_dl_library *d3d12_mod, IUnknown *adapter) +{ + D3D12XBOX_PROCESS_DEBUG_FLAGS debugFlags = + D3D12XBOX_PROCESS_DEBUG_FLAG_ENABLE_COMMON_STATE_PROMOTION; /* For compatibility with desktop D3D12 */ + + if (d3d12_debug & D3D12_DEBUG_EXPERIMENTAL) { + debug_printf("D3D12: experimental shader models are not supported on GDKX\n"); + return nullptr; + } + + if (d3d12_debug & D3D12_DEBUG_GPU_VALIDATOR) { + debug_printf("D3D12: gpu validation is not supported on GDKX\n"); /* FIXME: Is this right? */ + return nullptr; + } + + if (d3d12_debug & D3D12_DEBUG_DEBUG_LAYER) + debugFlags |= D3D12XBOX_PROCESS_DEBUG_FLAG_DEBUG; + + D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {}; + params.Version = D3D12_SDK_VERSION; + params.ProcessDebugFlags = debugFlags; + params.GraphicsCommandQueueRingSizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + params.GraphicsScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + params.ComputeScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + + ID3D12Device3 *dev = nullptr; + + typedef HRESULT(WINAPI * PFN_D3D12XBOXCREATEDEVICE)(IGraphicsUnknown *, const D3D12XBOX_CREATE_DEVICE_PARAMETERS *, REFIID, void **); + PFN_D3D12XBOXCREATEDEVICE D3D12XboxCreateDevice = + (PFN_D3D12XBOXCREATEDEVICE) util_dl_get_proc_address(d3d12_mod, "D3D12XboxCreateDevice"); + if (!D3D12XboxCreateDevice) { + debug_printf("D3D12: failed to load D3D12XboxCreateDevice from D3D12 DLL\n"); + return NULL; + } + if (FAILED(D3D12XboxCreateDevice((IGraphicsUnknown*) adapter, ¶ms, IID_PPV_ARGS(&dev)))) + debug_printf("D3D12: D3D12XboxCreateDevice failed\n"); + + return dev; +} + +#else static ID3D12Device3 * create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory) @@ -892,6 +941,8 @@ create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory return dev; } +#endif /* _GAMING_XBOX */ + static bool can_attribute_at_vertex(struct d3d12_screen *screen) { @@ -1209,7 +1260,17 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU screen->base.interop_query_device_info = d3d12_interop_query_device_info; screen->base.interop_export_object = d3d12_interop_export_object; - screen->d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT); + screen->d3d12_mod = util_dl_open( + UTIL_DL_PREFIX +#ifdef _GAMING_XBOX_SCARLETT + "d3d12_xs" +#elif defined(_GAMING_XBOX) + "d3d12_x" +#else + "d3d12" +#endif + UTIL_DL_EXT + ); if (!screen->d3d12_mod) { debug_printf("D3D12: failed to load D3D12.DLL\n"); return false; @@ -1250,6 +1311,7 @@ try_find_d3d12core_next_to_self(char *path, size_t path_arr_size) } #endif +#ifndef _GAMING_XBOX static ID3D12DeviceFactory * try_create_device_factory(util_dl_library *d3d12_mod) { @@ -1301,12 +1363,14 @@ try_create_device_factory(util_dl_library *d3d12_mod) (void)D3D12GetInterface(CLSID_D3D12DeviceFactory, IID_PPV_ARGS(&factory)); return factory; } +#endif bool d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) { assert(screen->base.destroy != nullptr); +#ifndef _GAMING_XBOX ID3D12DeviceFactory *factory = try_create_device_factory(screen->d3d12_mod); #ifndef DEBUG @@ -1321,6 +1385,9 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) if (factory) factory->Release(); +#else + screen->dev = create_device(screen->d3d12_mod, adapter); +#endif if (!screen->dev) { debug_printf("D3D12: failed to create device\n"); @@ -1329,6 +1396,7 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) screen->adapter_luid = GetAdapterLuid(screen->dev); +#ifndef _GAMING_XBOX ID3D12InfoQueue *info_queue; if (SUCCEEDED(screen->dev->QueryInterface(IID_PPV_ARGS(&info_queue)))) { D3D12_MESSAGE_SEVERITY severities[] = { @@ -1349,6 +1417,7 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) info_queue->PushStorageFilter(&NewFilter); info_queue->Release(); } +#endif /* !_GAMING_XBOX */ if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &screen->opts, @@ -1424,13 +1493,16 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queue_desc.NodeMask = 0; +#ifndef _GAMING_XBOX ID3D12Device9 *device9; if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, IID_PPV_ARGS(&screen->cmdqueue)))) return false; device9->Release(); - } else { + } else +#endif + { if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&screen->cmdqueue)))) return false; @@ -1506,11 +1578,14 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) screen->have_load_at_vertex = can_attribute_at_vertex(screen); screen->support_shader_images = can_shader_image_load_all_formats(screen); + +#ifndef _GAMING_XBOX ID3D12Device8 *dev8; if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) { dev8->Release(); screen->support_create_not_resident = true; } +#endif screen->nir_options = *dxil_get_nir_compiler_options(); diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h b/src/gallium/drivers/d3d12/d3d12_screen.h index 980ccad4134..e69100754e0 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.h +++ b/src/gallium/drivers/d3d12/d3d12_screen.h @@ -124,6 +124,10 @@ struct d3d12_screen { bool have_load_at_vertex; bool support_shader_images; bool support_create_not_resident; + +#ifdef _GAMING_XBOX + UINT64 frame_token; +#endif }; static inline struct d3d12_screen * @@ -135,8 +139,12 @@ d3d12_screen(struct pipe_screen *pipe) struct d3d12_dxgi_screen { struct d3d12_screen base; +#ifndef _GAMING_XBOX struct IDXGIFactory4 *factory; struct IDXGIAdapter3 *adapter; +#else + struct IDXGIAdapter *adapter; +#endif wchar_t description[128]; }; diff --git a/src/gallium/drivers/d3d12/meson.build b/src/gallium/drivers/d3d12/meson.build index ef3c576956e..b6c14d16a83 100644 --- a/src/gallium/drivers/d3d12/meson.build +++ b/src/gallium/drivers/d3d12/meson.build @@ -29,7 +29,6 @@ files_libd3d12 = files( 'd3d12_context.cpp', 'd3d12_descriptor_pool.cpp', 'd3d12_draw.cpp', - 'd3d12_dxcore_screen.cpp', 'd3d12_fence.cpp', 'd3d12_format.c', 'd3d12_gs_variant.cpp', @@ -73,8 +72,16 @@ if with_gallium_d3d12_video ] endif +is_xbox = target_machine.system().startswith('Gaming.Xbox') if host_machine.system() == 'windows' - files_libd3d12 += files('d3d12_dxgi_screen.cpp') + if is_xbox + files_libd3d12 += files('d3d12_dxgi_xbox_screen.cpp') + else + files_libd3d12 += files('d3d12_dxgi_screen.cpp') + endif +endif +if is_xbox == false + files_libd3d12 += files('d3d12_dxcore_screen.cpp') endif libd3d12 = static_library(