Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimentally implement SM 6.7 #1591

Merged
merged 15 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/vkd3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ extern "C" {
#define VKD3D_CONFIG_FLAG_FORCE_COMPUTE_ROOT_PARAMETERS_PUSH_UBO (1ull << 38)
#define VKD3D_CONFIG_FLAG_SKIP_DRIVER_WORKAROUNDS (1ull << 39)
#define VKD3D_CONFIG_FLAG_CURB_MEMORY_PSO_CACHE (1ull << 40)
#define VKD3D_CONFIG_FLAG_ENABLE_EXPERIMENTAL_FEATURES (1ull << 41)

struct vkd3d_instance;

Expand Down
15 changes: 15 additions & 0 deletions include/vkd3d_d3d12.idl
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,8 @@ typedef enum D3D12_UAV_DIMENSION
D3D12_UAV_DIMENSION_TEXTURE1DARRAY = 3,
D3D12_UAV_DIMENSION_TEXTURE2D = 4,
D3D12_UAV_DIMENSION_TEXTURE2DARRAY = 5,
D3D12_UAV_DIMENSION_TEXTURE2DMS = 6,
D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY = 7,
D3D12_UAV_DIMENSION_TEXTURE3D = 8,
} D3D12_UAV_DIMENSION;

Expand Down Expand Up @@ -1877,6 +1879,17 @@ typedef struct D3D12_TEX2D_ARRAY_UAV
UINT PlaneSlice;
} D3D12_TEX2D_ARRAY_UAV;

typedef struct D3D12_TEX2DMS_UAV
{
UINT Unused;
} D3D12_TEX2DMS_UAV;

typedef struct D3D12_TEX2DMS_ARRAY_UAV
{
UINT FirstArraySlice;
UINT ArraySize;
} D3D12_TEX2DMS_ARRAY_UAV;

typedef struct D3D12_TEX3D_UAV
{
UINT MipSlice;
Expand All @@ -1895,6 +1908,8 @@ typedef struct D3D12_UNORDERED_ACCESS_VIEW_DESC
D3D12_TEX1D_ARRAY_UAV Texture1DArray;
D3D12_TEX2D_UAV Texture2D;
D3D12_TEX2D_ARRAY_UAV Texture2DArray;
D3D12_TEX2DMS_UAV Texture2DMS;
D3D12_TEX2DMS_ARRAY_UAV Texture2DMSArray;
D3D12_TEX3D_UAV Texture3D;
};
} D3D12_UNORDERED_ACCESS_VIEW_DESC;
Expand Down
2 changes: 1 addition & 1 deletion libs/d3d12core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,4 +431,4 @@ HRESULT WINAPI DLLEXPORT D3D12GetInterface(REFCLSID rcslid, REFIID iid, void **d

/* Just expose the latest stable AgilitySDK version.
* This is actually exported as a UINT and not a function it seems. */
DLLEXPORT const UINT D3D12SDKVersion = 608;
DLLEXPORT const UINT D3D12SDKVersion = 610;
63 changes: 59 additions & 4 deletions libs/vkd3d/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
{"force_compute_root_parameters_push_ubo", VKD3D_CONFIG_FLAG_FORCE_COMPUTE_ROOT_PARAMETERS_PUSH_UBO},
{"skip_driver_workarounds", VKD3D_CONFIG_FLAG_SKIP_DRIVER_WORKAROUNDS},
{"curb_memory_pso_cache", VKD3D_CONFIG_FLAG_CURB_MEMORY_PSO_CACHE},
{"enable_experimental_features", VKD3D_CONFIG_FLAG_ENABLE_EXPERIMENTAL_FEATURES},
};

static void vkd3d_config_flags_init_once(void)
Expand Down Expand Up @@ -4111,9 +4112,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(d3d12_device_i
return E_INVALIDARG;
}

data->AdvancedTextureOpsSupported = FALSE;
data->WriteableMSAATexturesSupported = FALSE;
data->IndependentFrontAndBackStencilRefMaskSupported = FALSE;
*data = device->d3d12_caps.options14;

TRACE("AdvancedTextureOpsSupported %u\n", data->AdvancedTextureOpsSupported);
TRACE("WriteableMSAATexturesSupported %u\n", data->WriteableMSAATexturesSupported);
TRACE("IndependentFrontAndBackStencilRefMaskSupported %u\n", data->IndependentFrontAndBackStencilRefMaskSupported);

return S_OK;
}

Expand Down Expand Up @@ -6961,6 +6965,22 @@ static void d3d12_device_caps_init_feature_options13(struct d3d12_device *device
options13->InvertedViewportDepthFlipsZSupported = TRUE;
}

static void d3d12_device_caps_init_feature_options14(struct d3d12_device *device)
{
D3D12_FEATURE_DATA_D3D12_OPTIONS14 *options14 = &device->d3d12_caps.options14;

/* This is more dubious to enable.
* The only blocking feature here is texture with dynamic offsets.
* In Vulkan as-is, only textureGather supports integer offsets.
* This works fine in practice, however, but we shouldn't expose this by default
* until we have an actual extension. */
options14->AdvancedTextureOpsSupported = (vkd3d_config_flags & VKD3D_CONFIG_FLAG_ENABLE_EXPERIMENTAL_FEATURES) &&
device->d3d12_caps.max_shader_model >= D3D_SHADER_MODEL_6_7;
options14->WriteableMSAATexturesSupported = device->d3d12_caps.max_shader_model >= D3D_SHADER_MODEL_6_7 &&
device->device_info.features2.features.shaderStorageImageMultisample;
options14->IndependentFrontAndBackStencilRefMaskSupported = FALSE;
}

static void d3d12_device_caps_init_feature_level(struct d3d12_device *device)
{
const VkPhysicalDeviceFeatures *features = &device->device_info.features2.features;
Expand Down Expand Up @@ -7166,6 +7186,39 @@ static void d3d12_device_caps_init_shader_model(struct d3d12_device *device)
INFO("Enabling support for SM 6.6.\n");
device->d3d12_caps.max_shader_model = D3D_SHADER_MODEL_6_6;
}

/* SM 6.7 adds:
* - QuadAny / All (required)
* - This can be implemented directly with quad shuffles.
* - In both D3D12 docs and on real implementations, undefined behavior happens when inactive lanes are used.
* - Helper lanes in wave ops (required)
* - Vulkan by default says that helper lanes participate, but they may not participate in any non-quad operation.
* - In practice, this assumption holds, and we can enable it based on driverID checks where we know this behavior
* is normal.
* - Programmable offsets (AdvancedTextureOps)
* - There is no legal way to use this, except for textureGather.
* - In practice however, it just happens to work anyways.
* - It's optional and depends on castable texture formats either way.
* - We can enable it through app-opt if there is a real need for it.
* - MSAA UAV (separate feature)
* - Trivial Vulkan catch-up
* - SampleCmpLevel (AdvancedTextureOps)
* - Trivial Vulkan catch-up
* - Raw Gather (AdvancedTextureOps)
* - Looks scary, but the view format must be R16, R32 or R32G32_UINT, which makes it trivial.
* - It behaves exactly like you're doing GatherRed or bitcast(GatherRed, GatherGreen).
* - Tested against RGBA8, and it does *not* reinterpret RGBA8 to R32 in the shader.
* - Integer sampling (AdvancedTextureOps)
* - Trivial Vulkan catch-up. Requires implementing border colors as well.
*/
if (device->d3d12_caps.max_shader_model == D3D_SHADER_MODEL_6_6 &&
(vkd3d_config_flags & VKD3D_CONFIG_FLAG_ENABLE_EXPERIMENTAL_FEATURES))
{
/* Helper lanes in wave ops behavior appears to work as intended on NV and RADV.
* Technically needs an extension to *guarantee* this behavior however ... */
INFO("Experimentally enabling support for SM 6.7.\n");
device->d3d12_caps.max_shader_model = D3D_SHADER_MODEL_6_7;
}
}
else
{
Expand Down Expand Up @@ -7270,6 +7323,8 @@ static void d3d12_device_caps_override(struct d3d12_device *device)
static void d3d12_device_caps_init(struct d3d12_device *device)
{
d3d12_device_caps_init_shader_model(device);
d3d12_device_caps_shader_model_override(device);

d3d12_device_caps_init_feature_options(device);
d3d12_device_caps_init_feature_options1(device);
d3d12_device_caps_init_feature_options2(device);
Expand All @@ -7283,9 +7338,9 @@ static void d3d12_device_caps_init(struct d3d12_device *device)
d3d12_device_caps_init_feature_options10(device);
d3d12_device_caps_init_feature_options11(device);
d3d12_device_caps_init_feature_options13(device);
d3d12_device_caps_init_feature_options14(device);
d3d12_device_caps_init_feature_level(device);

d3d12_device_caps_shader_model_override(device);
d3d12_device_caps_override(device);
d3d12_device_caps_override_application(device);
}
Expand Down
88 changes: 66 additions & 22 deletions libs/vkd3d/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,12 @@ HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC1 *desc, struct d3
{
const struct vkd3d_format *format;

if (desc->Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D && desc->SampleDesc.Count > 1)
{
WARN("MSAA not supported on 1D and 3D textures.\n");
return E_INVALIDARG;
}

switch (desc->Dimension)
{
case D3D12_RESOURCE_DIMENSION_BUFFER:
Expand Down Expand Up @@ -2218,6 +2224,22 @@ HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC1 *desc, struct d3
}
/* Fall through. */
case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
if (desc->SampleDesc.Count > 1)
{
if (!(desc->Flags & (D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL | D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET)))
{
WARN("Multi-sampled textures must be created with render target or depth attachment usage.\n");
return E_INVALIDARG;
}

if ((desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) &&
!device->d3d12_caps.options14.WriteableMSAATexturesSupported)
{
WARN("MSAA UAV textures not supported.\n");
return E_INVALIDARG;
}
}
/* Fall through */
HansKristian-Work marked this conversation as resolved.
Show resolved Hide resolved
case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
if (desc->SampleDesc.Count == 0)
{
Expand Down Expand Up @@ -4842,13 +4864,26 @@ static struct vkd3d_view *vkd3d_create_texture_uav_view(struct d3d12_device *dev
key.u.texture.layer_count = 1;
key.u.texture.aspect_mask = vk_image_aspect_flags_from_d3d12(resource->format, desc->Texture2D.PlaneSlice);
break;
case D3D12_UAV_DIMENSION_TEXTURE2DMS:
key.u.texture.view_type = VK_IMAGE_VIEW_TYPE_2D;
key.u.texture.miplevel_idx = 0;
key.u.texture.layer_count = 1;
key.u.texture.aspect_mask = vk_image_aspect_flags_from_d3d12(resource->format, desc->Texture2D.PlaneSlice);
break;
case D3D12_UAV_DIMENSION_TEXTURE2DARRAY:
key.u.texture.view_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
key.u.texture.miplevel_idx = desc->Texture2DArray.MipSlice;
key.u.texture.layer_idx = desc->Texture2DArray.FirstArraySlice;
key.u.texture.layer_count = desc->Texture2DArray.ArraySize;
key.u.texture.aspect_mask = vk_image_aspect_flags_from_d3d12(resource->format, desc->Texture2DArray.PlaneSlice);
break;
case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY:
key.u.texture.view_type = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
key.u.texture.miplevel_idx = 0;
key.u.texture.layer_idx = desc->Texture2DMSArray.FirstArraySlice;
key.u.texture.layer_count = desc->Texture2DMSArray.ArraySize;
key.u.texture.aspect_mask = vk_image_aspect_flags_from_d3d12(resource->format, 0);
break;
case D3D12_UAV_DIMENSION_TEXTURE3D:
key.u.texture.view_type = VK_IMAGE_VIEW_TYPE_3D;
key.u.texture.miplevel_idx = desc->Texture3D.MipSlice;
Expand Down Expand Up @@ -5739,41 +5774,56 @@ static VkBorderColor vk_static_border_color_from_d3d12(D3D12_STATIC_BORDER_COLOR
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE:
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT:
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
case D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT:
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
WARN("Unhandled static border color %u.\n", border_color);
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
}
}

static VkBorderColor vk_border_color_from_d3d12(struct d3d12_device *device, const float *border_color)
static VkBorderColor vk_border_color_from_d3d12(struct d3d12_device *device, const uint32_t *border_color,
D3D12_SAMPLER_FLAGS flags)
{
bool uint_border = !!(flags & D3D12_SAMPLER_FLAG_UINT_BORDER_COLOR);
unsigned int i;

#define ONE_FP32 0x3f800000
static const struct
{
float color[4];
uint32_t color[4];
bool uint_border;
VkBorderColor vk_border_color;
}
border_colors[] = {
{ {0.0f, 0.0f, 0.0f, 0.0f}, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK },
{ {0.0f, 0.0f, 0.0f, 1.0f}, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK },
{ {1.0f, 1.0f, 1.0f, 1.0f}, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE },
{ {0, 0, 0, 0}, false, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK },
{ {0, 0, 0, ONE_FP32}, false, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK },
{ {ONE_FP32, ONE_FP32, ONE_FP32, ONE_FP32}, false, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE },
{ {0, 0, 0, 0}, true, VK_BORDER_COLOR_INT_TRANSPARENT_BLACK },
{ {0, 0, 0, 1}, true, VK_BORDER_COLOR_INT_OPAQUE_BLACK },
{ {1, 1, 1, 1}, true, VK_BORDER_COLOR_INT_OPAQUE_WHITE},
};
#undef ONE_FP32

for (i = 0; i < ARRAY_SIZE(border_colors); i++)
{
if (!memcmp(border_color, border_colors[i].color, sizeof(border_colors[i].color)))
if (uint_border == border_colors[i].uint_border &&
!memcmp(border_color, border_colors[i].color, sizeof(border_colors[i].color)))
{
return border_colors[i].vk_border_color;
}
}

if (!device->device_info.custom_border_color_features.customBorderColorWithoutFormat)
{
FIXME("Unsupported border color (%f, %f, %f, %f).\n",
FIXME("Unsupported border color (#%x, #%x, #%x, #%x).\n",
border_color[0], border_color[1], border_color[2], border_color[3]);
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
return uint_border ? VK_BORDER_COLOR_INT_TRANSPARENT_BLACK : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
}

return VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
return uint_border ? VK_BORDER_COLOR_INT_CUSTOM_EXT : VK_BORDER_COLOR_FLOAT_CUSTOM_EXT;
}

HRESULT d3d12_create_static_sampler(struct d3d12_device *device,
Expand All @@ -5784,9 +5834,6 @@ HRESULT d3d12_create_static_sampler(struct d3d12_device *device,
VkSamplerCreateInfo sampler_desc;
VkResult vr;

if (desc->Flags)
FIXME_ONCE("Ignoring static sampler flags #%x.\n", desc->Flags);

reduction_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT;
reduction_desc.pNext = NULL;
reduction_desc.reductionMode = vk_reduction_mode_from_d3d12(D3D12_DECODE_FILTER_REDUCTION(desc->Filter));
Expand Down Expand Up @@ -5834,8 +5881,8 @@ static HRESULT d3d12_create_sampler(struct d3d12_device *device,

border_color_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
border_color_info.pNext = NULL;
memcpy(border_color_info.customBorderColor.float32, desc->FloatBorderColor,
sizeof(border_color_info.customBorderColor.float32));
memcpy(border_color_info.customBorderColor.uint32, desc->UintBorderColor,
sizeof(border_color_info.customBorderColor.uint32));
border_color_info.format = VK_FORMAT_UNDEFINED;

reduction_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT;
Expand Down Expand Up @@ -5868,10 +5915,13 @@ static HRESULT d3d12_create_sampler(struct d3d12_device *device,
sampler_desc.maxAnisotropy = min(16.0f, sampler_desc.maxAnisotropy);

if (d3d12_sampler_needs_border_color(desc->AddressU, desc->AddressV, desc->AddressW))
sampler_desc.borderColor = vk_border_color_from_d3d12(device, desc->FloatBorderColor);
sampler_desc.borderColor = vk_border_color_from_d3d12(device, desc->UintBorderColor, desc->Flags);

if (sampler_desc.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT)
if (sampler_desc.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT ||
sampler_desc.borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT)
{
vk_prepend_struct(&sampler_desc, &border_color_info);
}

if (reduction_desc.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE &&
device->device_info.vulkan_1_2_features.samplerFilterMinmax)
Expand All @@ -5897,9 +5947,6 @@ void d3d12_desc_create_sampler_embedded(vkd3d_cpu_descriptor_va_t desc_va,
return;
}

if (desc->Flags)
FIXME("Ignoring sampler flags #%x.\n", desc->Flags);

key.view_type = VKD3D_VIEW_TYPE_SAMPLER;
key.u.sampler = *desc;

Expand Down Expand Up @@ -5935,9 +5982,6 @@ void d3d12_desc_create_sampler(vkd3d_cpu_descriptor_va_t desc_va,
return;
}

if (desc->Flags)
FIXME("Ignoring sampler flags #%x.\n", desc->Flags);

d = d3d12_desc_decode_va(desc_va);

key.view_type = VKD3D_VIEW_TYPE_SAMPLER;
Expand Down
1 change: 1 addition & 0 deletions libs/vkd3d/vkd3d_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -4018,6 +4018,7 @@ struct d3d12_caps
D3D12_FEATURE_DATA_D3D12_OPTIONS10 options10;
D3D12_FEATURE_DATA_D3D12_OPTIONS11 options11;
D3D12_FEATURE_DATA_D3D12_OPTIONS13 options13;
D3D12_FEATURE_DATA_D3D12_OPTIONS14 options14;

D3D_FEATURE_LEVEL max_feature_level;
D3D_SHADER_MODEL max_shader_model;
Expand Down
2 changes: 1 addition & 1 deletion tests/d3d12.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

/* Uncomment when testing against Agility SDK debug layers. */
#if 0
__declspec(dllexport) extern const UINT D3D12SDKVersion = 608;
__declspec(dllexport) extern const UINT D3D12SDKVersion = 610;
__declspec(dllexport) extern const char *D3D12SDKPath = u8".\\D3D12\\";
#endif

Expand Down
Loading
Loading