Module: Mesa
Branch: main
Commit: 97061dd7ee40d3ab82caff5485065a5e25016147
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=97061dd7ee40d3ab82caff5485065a5e25016147

Author: Caleb Cornett <[email protected]>
Date:   Wed Jan 11 12:28:34 2023 -0500

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 <[email protected]>
Co-authored-by: David Jacewicz <[email protected]>
Co-authored-by: tieuchanlong <[email protected]>
Reviewed-by: Jesse Natalie <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19022>

---

 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 +++--
 src/gallium/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(-)

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 <directx/d3d12.h>
 #include <directx/d3d12video.h>
+#elif defined(__cplusplus)
+#ifdef _GAMING_XBOX_SCARLETT
+#include <d3d12_xs.h>
+#include <d3d12video_xs.h>
+#else
+#include <d3d12_x.h>
+#include <d3d12video_x.h>
+#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 <windows.h>
+
+#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 <dxguids/dxguids.h>
 #include <memory>
 
+#ifndef _GAMING_XBOX
 #include <wrl/client.h>
 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<IUnknown> screen_device;
       ComPtr<IUnknown> 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 <wrl/client.h>
+using Microsoft::WRL::ComPtr;
+
 #include "d3d12_root_signature.h"
 #include "d3d12_compiler.h"
 #include "d3d12_screen.h"
@@ -29,9 +32,6 @@
 
 #include <dxguids/dxguids.h>
 
-#include <wrl/client.h>
-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<ID3DBlob> 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 <directx/d3d12sdklayers.h>
+#endif
 
 #include <dxguids/dxguids.h>
 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, &params, 
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(

Reply via email to