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 <flibitijibibo@gmail.com>
Co-authored-by: David Jacewicz <david.jacewicz@protonmail.com>
Co-authored-by: tieuchanlong <tieuchanlong@gmail.com>
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19022>
This commit is contained in:
Caleb Cornett
2023-01-11 12:28:34 -05:00
committed by Marge Bot
parent 882a78b8ad
commit 97061dd7ee
12 changed files with 296 additions and 22 deletions

View File

@@ -235,7 +235,9 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
mtx_lock(&screen->submit_mutex); mtx_lock(&screen->submit_mutex);
#ifndef _GAMING_XBOX
d3d12_process_batch_residency(screen, batch); d3d12_process_batch_residency(screen, batch);
#endif
bool has_state_fixup = d3d12_context_state_resolve_submission(ctx, batch); bool has_state_fixup = d3d12_context_state_resolve_submission(ctx, batch);

View File

@@ -33,8 +33,27 @@
#endif #endif
#define D3D12_IGNORE_SDK_LAYERS #define D3D12_IGNORE_SDK_LAYERS
#ifndef _GAMING_XBOX
#include <directx/d3d12.h> #include <directx/d3d12.h>
#include <directx/d3d12video.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(__cplusplus)
#if !defined(_WIN32) || defined(_MSC_VER) || D3D12_SDK_VERSION < 606 #if !defined(_WIN32) || defined(_MSC_VER) || D3D12_SDK_VERSION < 606

View File

@@ -76,8 +76,10 @@ d3d12_context_destroy(struct pipe_context *pctx)
dxil_destroy_validator(ctx->dxil_validator); dxil_destroy_validator(ctx->dxil_validator);
#endif #endif
#ifndef _GAMING_XBOX
if (ctx->dev_config) if (ctx->dev_config)
ctx->dev_config->Release(); ctx->dev_config->Release();
#endif
if (ctx->timestamp_query) if (ctx->timestamp_query)
pctx->destroy_query(pctx, 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 = ctx->D3D12SerializeVersionedRootSignature =
(PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)util_dl_get_proc_address(screen->d3d12_mod, "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); (void)screen->dev->QueryInterface(&ctx->dev_config);
#endif
ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull; ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull;

View File

@@ -255,7 +255,9 @@ struct d3d12_context {
struct d3d12_descriptor_handle null_sampler; struct d3d12_descriptor_handle null_sampler;
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature; PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignature;
#ifndef _GAMING_XBOX
ID3D12DeviceConfiguration *dev_config; ID3D12DeviceConfiguration *dev_config;
#endif
#ifdef _WIN32 #ifdef _WIN32
struct dxil_validator *dxil_validator; struct dxil_validator *dxil_validator;
#endif #endif

View File

@@ -41,10 +41,7 @@
#include "util/u_prim_restart.h" #include "util/u_prim_restart.h"
#include "util/u_math.h" #include "util/u_math.h"
static const D3D12_RECT MAX_SCISSOR = { D3D12_VIEWPORT_BOUNDS_MIN, static const D3D12_RECT MAX_SCISSOR = { 0, 0, 16384, 16384 };
D3D12_VIEWPORT_BOUNDS_MIN,
D3D12_VIEWPORT_BOUNDS_MAX,
D3D12_VIEWPORT_BOUNDS_MAX };
static const D3D12_RECT MAX_SCISSOR_ARRAY[] = { static const D3D12_RECT MAX_SCISSOR_ARRAY[] = {
MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR, MAX_SCISSOR,

View File

@@ -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;
}

View File

@@ -49,10 +49,10 @@ d3d12_create_fence(struct d3d12_screen *screen)
ret->cmdqueue_fence = screen->fence; ret->cmdqueue_fence = screen->fence;
ret->value = ++screen->fence_value; ret->value = ++screen->fence_value;
ret->event = d3d12_fence_create_event(&ret->event_fd); 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))) if (FAILED(screen->cmdqueue->Signal(screen->fence, ret->value)))
goto fail; goto fail;
if (FAILED(screen->fence->SetEventOnCompletion(ret->value, ret->event)))
goto fail;
pipe_reference_init(&ret->reference, 1); pipe_reference_init(&ret->reference, 1);
return ret; return ret;

View File

@@ -41,8 +41,10 @@
#include <dxguids/dxguids.h> #include <dxguids/dxguids.h>
#include <memory> #include <memory>
#ifndef _GAMING_XBOX
#include <wrl/client.h> #include <wrl/client.h>
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
#endif
#ifndef GENERIC_ALL #ifndef GENERIC_ALL
// This is only added to winadapter.h in newer DirectX-Headers // 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; HANDLE d3d_handle = (HANDLE) (intptr_t) handle->handle;
#endif #endif
#ifndef _GAMING_XBOX
if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) { if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) {
ComPtr<IUnknown> screen_device; ComPtr<IUnknown> screen_device;
ComPtr<IUnknown> res_device; ComPtr<IUnknown> res_device;
@@ -487,6 +490,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
} }
} }
} }
#endif
#ifdef _WIN32 #ifdef _WIN32
HANDLE d3d_handle_to_close = nullptr; HANDLE d3d_handle_to_close = nullptr;
@@ -501,10 +505,11 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
if (res->bo) { if (res->bo) {
d3d12_res = res->bo->res; d3d12_res = res->bo->res;
} else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) { } else if (handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) {
IUnknown *obj = (IUnknown *)handle->com_obj; if (handle->modifier == 1) {
(void)obj->QueryInterface(&d3d12_res); d3d12_heap = (ID3D12Heap *) handle->com_obj;
(void)obj->QueryInterface(&d3d12_heap); } else {
obj->Release(); d3d12_res = (ID3D12Resource *) handle->com_obj;
}
} else { } else {
screen->dev->OpenSharedHandle(d3d_handle, IID_PPV_ARGS(&d3d12_res)); 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); struct d3d12_screen *screen = d3d12_screen(pscreen);
IUnknown *obj; #ifdef _GAMING_XBOX
IGraphicsUnknown
#else
IUnknown
#endif
*obj;
#ifdef _WIN32 #ifdef _WIN32
HANDLE d3d_handle = handle->handle; HANDLE d3d_handle = handle->handle;
#else #else
@@ -927,8 +937,13 @@ d3d12_memobj_create_from_handle(struct pipe_screen *pscreen, struct winsys_handl
} }
memobj->base.dedicated = dedicated; memobj->base.dedicated = dedicated;
(void)obj->QueryInterface(&memobj->res); obj->AddRef();
(void)obj->QueryInterface(&memobj->heap); if (handle->modifier == 1) {
memobj->heap = (ID3D12Heap *) obj;
} else {
memobj->res = (ID3D12Resource *) obj;
}
obj->Release(); obj->Release();
if (!memobj->res && !memobj->heap) { if (!memobj->res && !memobj->heap) {
debug_printf("d3d12: Memory object isn't a resource or heap\n"); 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.com_obj = memobj->res ? (void *) memobj->res : (void *) memobj->heap;
whandle.offset = offset; whandle.offset = offset;
whandle.format = templ->format; whandle.format = templ->format;
whandle.modifier = memobj->res ? 0 : 1;
// WINSYS_HANDLE_TYPE_D3D12_RES implies taking ownership of the reference // WINSYS_HANDLE_TYPE_D3D12_RES implies taking ownership of the reference
((IUnknown *)whandle.com_obj)->AddRef(); ((IUnknown *)whandle.com_obj)->AddRef();

View File

@@ -21,6 +21,9 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
#include "d3d12_root_signature.h" #include "d3d12_root_signature.h"
#include "d3d12_compiler.h" #include "d3d12_compiler.h"
#include "d3d12_screen.h" #include "d3d12_screen.h"
@@ -29,9 +32,6 @@
#include <dxguids/dxguids.h> #include <dxguids/dxguids.h>
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
struct d3d12_root_signature { struct d3d12_root_signature {
struct d3d12_root_signature_key key; struct d3d12_root_signature_key key;
ID3D12RootSignature *sig; ID3D12RootSignature *sig;
@@ -83,11 +83,15 @@ init_range(D3D12_DESCRIPTOR_RANGE1 *range,
range->NumDescriptors = num_descs; range->NumDescriptors = num_descs;
range->BaseShaderRegister = base_shader_register; range->BaseShaderRegister = base_shader_register;
range->RegisterSpace = register_space; range->RegisterSpace = register_space;
#ifdef _GAMING_XBOX
range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
#else
if (type == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER || if (type == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER ||
type == D3D12_DESCRIPTOR_RANGE_TYPE_UAV) type == D3D12_DESCRIPTOR_RANGE_TYPE_UAV)
range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE; range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
else else
range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS; range->Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS;
#endif
range->OffsetInDescriptorsFromTableStart = offset_from_start; 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; root_sig_desc.Desc_1_1.Flags |= D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT;
ComPtr<ID3DBlob> sig, error; ComPtr<ID3DBlob> sig, error;
#ifndef _GAMING_XBOX
if (ctx->dev_config) { if (ctx->dev_config) {
if (FAILED(ctx->dev_config->SerializeVersionedRootSignature(&root_sig_desc, if (FAILED(ctx->dev_config->SerializeVersionedRootSignature(&root_sig_desc,
&sig, &error))) { &sig, &error))) {
debug_printf("D3D12SerializeRootSignature failed\n"); debug_printf("D3D12SerializeRootSignature failed\n");
return NULL; return NULL;
} }
} else { } else
#endif
{
if (FAILED(ctx->D3D12SerializeVersionedRootSignature(&root_sig_desc, if (FAILED(ctx->D3D12SerializeVersionedRootSignature(&root_sig_desc,
&sig, &error))) { &sig, &error))) {
debug_printf("D3D12SerializeRootSignature failed\n"); debug_printf("D3D12SerializeRootSignature failed\n");

View File

@@ -51,7 +51,9 @@
#include "nir_to_dxil.h" #include "nir_to_dxil.h"
#include "git_sha1.h" #include "git_sha1.h"
#ifndef _GAMING_XBOX
#include <directx/d3d12sdklayers.h> #include <directx/d3d12sdklayers.h>
#endif
#include <dxguids/dxguids.h> #include <dxguids/dxguids.h>
static GUID OpenGLOn12CreatorID = { 0x6bb3cd34, 0x0d19, 0x45ab, { 0x97, 0xed, 0xd7, 0x20, 0xba, 0x3d, 0xfc, 0x80 } }; 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); 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 // WindowFromDC is Windows-only, and this method requires an HWND, so only use it on Windows
ID3D12SharingContract *sharing_contract; ID3D12SharingContract *sharing_contract;
if (SUCCEEDED(screen->cmdqueue->QueryInterface(IID_PPV_ARGS(&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); winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
} }
#ifndef _GAMING_XBOX
static ID3D12Debug * static ID3D12Debug *
get_debug_interface(util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory) 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(); 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 * static ID3D12Device3 *
create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory) 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; return dev;
} }
#endif /* _GAMING_XBOX */
static bool static bool
can_attribute_at_vertex(struct d3d12_screen *screen) 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_query_device_info = d3d12_interop_query_device_info;
screen->base.interop_export_object = d3d12_interop_export_object; 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) { if (!screen->d3d12_mod) {
debug_printf("D3D12: failed to load D3D12.DLL\n"); debug_printf("D3D12: failed to load D3D12.DLL\n");
return false; return false;
@@ -1250,6 +1311,7 @@ try_find_d3d12core_next_to_self(char *path, size_t path_arr_size)
} }
#endif #endif
#ifndef _GAMING_XBOX
static ID3D12DeviceFactory * static ID3D12DeviceFactory *
try_create_device_factory(util_dl_library *d3d12_mod) 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)); (void)D3D12GetInterface(CLSID_D3D12DeviceFactory, IID_PPV_ARGS(&factory));
return factory; return factory;
} }
#endif
bool bool
d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
{ {
assert(screen->base.destroy != nullptr); assert(screen->base.destroy != nullptr);
#ifndef _GAMING_XBOX
ID3D12DeviceFactory *factory = try_create_device_factory(screen->d3d12_mod); ID3D12DeviceFactory *factory = try_create_device_factory(screen->d3d12_mod);
#ifndef DEBUG #ifndef DEBUG
@@ -1321,6 +1385,9 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
if (factory) if (factory)
factory->Release(); factory->Release();
#else
screen->dev = create_device(screen->d3d12_mod, adapter);
#endif
if (!screen->dev) { if (!screen->dev) {
debug_printf("D3D12: failed to create device\n"); 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); screen->adapter_luid = GetAdapterLuid(screen->dev);
#ifndef _GAMING_XBOX
ID3D12InfoQueue *info_queue; ID3D12InfoQueue *info_queue;
if (SUCCEEDED(screen->dev->QueryInterface(IID_PPV_ARGS(&info_queue)))) { if (SUCCEEDED(screen->dev->QueryInterface(IID_PPV_ARGS(&info_queue)))) {
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY severities[] = {
@@ -1349,6 +1417,7 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
info_queue->PushStorageFilter(&NewFilter); info_queue->PushStorageFilter(&NewFilter);
info_queue->Release(); info_queue->Release();
} }
#endif /* !_GAMING_XBOX */
if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS,
&screen->opts, &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.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.NodeMask = 0; queue_desc.NodeMask = 0;
#ifndef _GAMING_XBOX
ID3D12Device9 *device9; ID3D12Device9 *device9;
if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { if (SUCCEEDED(screen->dev->QueryInterface(&device9))) {
if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID,
IID_PPV_ARGS(&screen->cmdqueue)))) IID_PPV_ARGS(&screen->cmdqueue))))
return false; return false;
device9->Release(); device9->Release();
} else { } else
#endif
{
if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, if (FAILED(screen->dev->CreateCommandQueue(&queue_desc,
IID_PPV_ARGS(&screen->cmdqueue)))) IID_PPV_ARGS(&screen->cmdqueue))))
return false; 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->have_load_at_vertex = can_attribute_at_vertex(screen);
screen->support_shader_images = can_shader_image_load_all_formats(screen); screen->support_shader_images = can_shader_image_load_all_formats(screen);
#ifndef _GAMING_XBOX
ID3D12Device8 *dev8; ID3D12Device8 *dev8;
if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) { if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) {
dev8->Release(); dev8->Release();
screen->support_create_not_resident = true; screen->support_create_not_resident = true;
} }
#endif
screen->nir_options = *dxil_get_nir_compiler_options(); screen->nir_options = *dxil_get_nir_compiler_options();

View File

@@ -124,6 +124,10 @@ struct d3d12_screen {
bool have_load_at_vertex; bool have_load_at_vertex;
bool support_shader_images; bool support_shader_images;
bool support_create_not_resident; bool support_create_not_resident;
#ifdef _GAMING_XBOX
UINT64 frame_token;
#endif
}; };
static inline struct d3d12_screen * static inline struct d3d12_screen *
@@ -135,8 +139,12 @@ d3d12_screen(struct pipe_screen *pipe)
struct d3d12_dxgi_screen { struct d3d12_dxgi_screen {
struct d3d12_screen base; struct d3d12_screen base;
#ifndef _GAMING_XBOX
struct IDXGIFactory4 *factory; struct IDXGIFactory4 *factory;
struct IDXGIAdapter3 *adapter; struct IDXGIAdapter3 *adapter;
#else
struct IDXGIAdapter *adapter;
#endif
wchar_t description[128]; wchar_t description[128];
}; };

View File

@@ -29,7 +29,6 @@ files_libd3d12 = files(
'd3d12_context.cpp', 'd3d12_context.cpp',
'd3d12_descriptor_pool.cpp', 'd3d12_descriptor_pool.cpp',
'd3d12_draw.cpp', 'd3d12_draw.cpp',
'd3d12_dxcore_screen.cpp',
'd3d12_fence.cpp', 'd3d12_fence.cpp',
'd3d12_format.c', 'd3d12_format.c',
'd3d12_gs_variant.cpp', 'd3d12_gs_variant.cpp',
@@ -73,8 +72,16 @@ if with_gallium_d3d12_video
] ]
endif endif
is_xbox = target_machine.system().startswith('Gaming.Xbox')
if host_machine.system() == 'windows' 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 endif
libd3d12 = static_library( libd3d12 = static_library(