Some games, e.g. Shadow of the Tomb Raider, do not check for success, and if the feature check is unimplemented they will use uninitialised data for the result.
Supersedes 174666.
Conor McCarthy (5): vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS1. vkd3d: Implement support for D3D12_FEATURE_ARCHITECTURE1. vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS2. vkd3d: Implement support for D3D12_FEATURE_SHADER_CACHE. vkd3d: Implement support for D3D12_FEATURE_COMMAND_QUEUE_PRIORITY.
include/vkd3d_d3d12.idl | 53 ++++++++++++++++ libs/vkd3d/device.c | 126 +++++++++++++++++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 2 + 3 files changed, 181 insertions(+)
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_d3d12.idl | 10 ++++++++++ libs/vkd3d/device.c | 28 ++++++++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 1 + 3 files changed, 39 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index ec8b83d..5cfb229 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -1608,6 +1608,16 @@ typedef struct D3D12_FEATURE_DATA_SHADER_MODEL D3D_SHADER_MODEL HighestShaderModel; } D3D12_FEATURE_DATA_SHADER_MODEL;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1 +{ + BOOL WaveOps; + UINT WaveLaneCountMin; + UINT WaveLaneCountMax; + UINT TotalLaneCount; + BOOL ExpandedComputeResourceStates; + BOOL Int64ShaderOps; +} D3D12_FEATURE_DATA_D3D12_OPTIONS1; + typedef enum D3D12_FEATURE { D3D12_FEATURE_D3D12_OPTIONS = 0, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index fd593bc..90044ac 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1336,6 +1336,13 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, device->feature_options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = FALSE; device->feature_options.ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2;
+ device->feature_options1.WaveOps = FALSE; + device->feature_options1.WaveLaneCountMin = 0; + device->feature_options1.WaveLaneCountMax = 0; + device->feature_options1.TotalLaneCount = 0; + device->feature_options1.ExpandedComputeResourceStates = TRUE; + device->feature_options1.Int64ShaderOps = features->shaderInt64; + if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0) { ERR("Failed to enumerate device extensions, vr %d.\n", vr); @@ -2668,6 +2675,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; }
+ case D3D12_FEATURE_D3D12_OPTIONS1: + { + D3D12_FEATURE_DATA_D3D12_OPTIONS1 *data = feature_data; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + *data = device->feature_options1; + + TRACE("Wave ops %#x.\n", data->WaveOps); + TRACE("Min wave lane count %#x.\n", data->WaveLaneCountMin); + TRACE("Max wave lane count %#x.\n", data->WaveLaneCountMax); + TRACE("Total lane count %#x.\n", data->TotalLaneCount); + TRACE("Expanded compute resource states %#x.\n", data->ExpandedComputeResourceStates); + TRACE("Int64 shader ops %#x.\n", data->Int64ShaderOps); + return S_OK; + } + case D3D12_FEATURE_ROOT_SIGNATURE: { D3D12_FEATURE_DATA_ROOT_SIGNATURE *data = feature_data; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 28801ba..6c7ec4e 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1134,6 +1134,7 @@ struct d3d12_device PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options; + D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1;
struct vkd3d_vulkan_info vk_info;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_d3d12.idl | 9 +++++++++ libs/vkd3d/device.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 5cfb229..ec102a8 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -1618,6 +1618,15 @@ typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1 BOOL Int64ShaderOps; } D3D12_FEATURE_DATA_D3D12_OPTIONS1;
+typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1 +{ + UINT NodeIndex; + BOOL TileBasedRenderer; + BOOL UMA; + BOOL CacheCoherentUMA; + BOOL IsolatedMMU; +} D3D12_FEATURE_DATA_ARCHITECTURE1; + typedef enum D3D12_FEATURE { D3D12_FEATURE_D3D12_OPTIONS = 0, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 90044ac..dc8ca44 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2713,6 +2713,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; }
+ case D3D12_FEATURE_ARCHITECTURE1: + { + D3D12_FEATURE_DATA_ARCHITECTURE1 *data = feature_data; + bool coherent; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + if (data->NodeIndex) + { + FIXME("Multi-adapter not supported.\n"); + return E_INVALIDARG; + } + + WARN("Assuming device does not support tile based rendering.\n"); + data->TileBasedRenderer = FALSE; + + data->UMA = d3d12_device_is_uma(device, &coherent); + data->CacheCoherentUMA = data->UMA ? coherent : FALSE; + + WARN("Assuming device does not have an isolated memory management unit.\n"); + data->IsolatedMMU = FALSE; + + TRACE("Tile based renderer %#x, UMA %#x, cache coherent UMA %#x, isolated MMU %#x.\n", + data->TileBasedRenderer, data->UMA, data->CacheCoherentUMA, data->IsolatedMMU); + return S_OK; + } + default: FIXME("Unhandled feature %#x.\n", feature); return E_NOTIMPL;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_d3d12.idl | 13 +++++++++++++ libs/vkd3d/device.c | 22 ++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 1 + 3 files changed, 36 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index ec102a8..4c69454 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -177,6 +177,13 @@ typedef enum D3D12_FORMAT_SUPPORT2 D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000, } D3D12_FORMAT_SUPPORT2;
+typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER +{ + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0x0, + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 0x1, + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 0x2, +} D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER; + interface ID3D12Fence; interface ID3D12RootSignature; interface ID3D12Heap; @@ -1627,6 +1634,12 @@ typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1 BOOL IsolatedMMU; } D3D12_FEATURE_DATA_ARCHITECTURE1;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2 +{ + BOOL DepthBoundsTestSupported; + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier; +} D3D12_FEATURE_DATA_D3D12_OPTIONS2; + typedef enum D3D12_FEATURE { D3D12_FEATURE_D3D12_OPTIONS = 0, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index dc8ca44..1063680 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1343,6 +1343,11 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, device->feature_options1.ExpandedComputeResourceStates = TRUE; device->feature_options1.Int64ShaderOps = features->shaderInt64;
+ /* Depth bounds test is enabled in D3D12_DEPTH_STENCIL_DESC1, which is not supported. */ + device->feature_options2.DepthBoundsTestSupported = FALSE; + /* d3d12_command_list_SetSamplePositions() is not implemented. */ + device->feature_options2.ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED; + if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0) { ERR("Failed to enumerate device extensions, vr %d.\n", vr); @@ -2744,6 +2749,23 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; }
+ case D3D12_FEATURE_D3D12_OPTIONS2: + { + D3D12_FEATURE_DATA_D3D12_OPTIONS2 *data = feature_data; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + *data = device->feature_options2; + + TRACE("Depth bounds test %#x.\n", data->DepthBoundsTestSupported); + TRACE("Programmable sample positions tier %#x.\n", data->ProgrammableSamplePositionsTier); + return S_OK; + } + default: FIXME("Unhandled feature %#x.\n", feature); return E_NOTIMPL; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 6c7ec4e..72a7913 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1135,6 +1135,7 @@ struct d3d12_device
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options; D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1; + D3D12_FEATURE_DATA_D3D12_OPTIONS2 feature_options2;
struct vkd3d_vulkan_info vk_info;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_d3d12.idl | 14 ++++++++++++++ libs/vkd3d/device.c | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 4c69454..60f36b4 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -184,6 +184,15 @@ typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 0x2, } D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER;
+typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS +{ + D3D12_SHADER_CACHE_SUPPORT_NONE = 0x0, + D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO = 0x1, + D3D12_SHADER_CACHE_SUPPORT_LIBRARY = 0x2, + D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4, + D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8, +} D3D12_SHADER_CACHE_SUPPORT_FLAGS; + interface ID3D12Fence; interface ID3D12RootSignature; interface ID3D12Heap; @@ -1640,6 +1649,11 @@ typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2 D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier; } D3D12_FEATURE_DATA_D3D12_OPTIONS2;
+typedef struct D3D12_FEATURE_DATA_SHADER_CACHE +{ + D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags; +} D3D12_FEATURE_DATA_SHADER_CACHE; + typedef enum D3D12_FEATURE { D3D12_FEATURE_D3D12_OPTIONS = 0, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 1063680..694c322 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2766,6 +2766,25 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; }
+ case D3D12_FEATURE_SHADER_CACHE: + { + D3D12_FEATURE_DATA_SHADER_CACHE *data = feature_data; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + /* FIXME: The D3D12 documentation states that D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO is + * always supported, but the CachedPSO field of D3D12_GRAPHICS_PIPELINE_STATE_DESC is + * ignored and GetCachedBlob() is a stub. */ + data->SupportFlags = D3D12_SHADER_CACHE_SUPPORT_NONE; + + TRACE("Shader cache support %#x.\n", data->SupportFlags); + return S_OK; + } + default: FIXME("Unhandled feature %#x.\n", feature); return E_NOTIMPL;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- include/vkd3d_d3d12.idl | 7 +++++++ libs/vkd3d/device.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 60f36b4..6e674a0 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -1654,6 +1654,13 @@ typedef struct D3D12_FEATURE_DATA_SHADER_CACHE D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags; } D3D12_FEATURE_DATA_SHADER_CACHE;
+typedef struct D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY +{ + D3D12_COMMAND_LIST_TYPE CommandListType; + UINT Priority; + BOOL PriorityForTypeIsSupported; +} D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY; + typedef enum D3D12_FEATURE { D3D12_FEATURE_D3D12_OPTIONS = 0, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 694c322..8bae29d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2785,6 +2785,32 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; }
+ case D3D12_FEATURE_COMMAND_QUEUE_PRIORITY: + { + D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY *data = feature_data; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + switch (data->CommandListType) + { + case D3D12_COMMAND_LIST_TYPE_DIRECT: + case D3D12_COMMAND_LIST_TYPE_COMPUTE: + case D3D12_COMMAND_LIST_TYPE_COPY: + data->PriorityForTypeIsSupported = FALSE; + TRACE("Command list type %#x, priority %u, supported %#x.\n", + data->CommandListType, data->Priority, data->PriorityForTypeIsSupported); + return S_OK; + + default: + FIXME("Unhandled command list type %#x.\n", data->CommandListType); + return E_INVALIDARG; + } + } + default: FIXME("Unhandled feature %#x.\n", feature); return E_NOTIMPL;