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

Add Vulkan profile #1567

Merged
merged 12 commits into from
May 25, 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ build
build.*
vkd3d-proton-*.tar.zst
vkd3d-proton-*/

/profiles/vulkan
/profiles/profile-test
754 changes: 754 additions & 0 deletions VP_D3D12_VKD3D_PROTON_profile.json

Large diffs are not rendered by default.

52 changes: 46 additions & 6 deletions libs/vkd3d/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(EXT_IMAGE_VIEW_MIN_LOD, EXT_image_view_min_lod),
VK_EXTENSION(EXT_ROBUSTNESS_2, EXT_robustness2),
VK_EXTENSION(EXT_SHADER_STENCIL_EXPORT, EXT_shader_stencil_export),
VK_EXTENSION(EXT_SHADER_VIEWPORT_INDEX_LAYER, EXT_shader_viewport_index_layer),
VK_EXTENSION(EXT_TRANSFORM_FEEDBACK, EXT_transform_feedback),
VK_EXTENSION(EXT_VERTEX_ATTRIBUTE_DIVISOR, EXT_vertex_attribute_divisor),
VK_EXTENSION(EXT_EXTENDED_DYNAMIC_STATE_2, EXT_extended_dynamic_state2),
Expand Down Expand Up @@ -1569,7 +1568,10 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
{
info->graphics_pipeline_library_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT;
info->graphics_pipeline_library_properties.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT;
vk_prepend_struct(&info->features2, &info->graphics_pipeline_library_features);
vk_prepend_struct(&info->properties2, &info->graphics_pipeline_library_properties);
}

if (vulkan_info->EXT_fragment_shader_interlock)
Expand Down Expand Up @@ -2068,18 +2070,42 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
physical_device_info->properties2.properties.sparseProperties.residencyNonResidentStrict = VK_FALSE;
}

/* We need independent interpolation to use GPL. */
if (!physical_device_info->graphics_pipeline_library_properties.graphicsPipelineLibraryIndependentInterpolationDecoration)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required even if we compile FS and all vertex stages into one single library?

Spec wording kind of indicates that it is but I don't know if this is really the intent here, but I guess every driver that supports GPL will want to support this bit anyway.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked for an exception, but there is none. Maybe it should be clarified in spec, but most likely drivers have a separate GPL path where they don't do cross stage stuff, and conditionally adding cross stage linking if all stages are present is slightly unexpected.

{
vulkan_info->EXT_graphics_pipeline_library = false;
physical_device_info->graphics_pipeline_library_features.graphicsPipelineLibrary = VK_FALSE;
}

vulkan_info->device_limits = physical_device_info->properties2.properties.limits;
vulkan_info->sparse_properties = physical_device_info->properties2.properties.sparseProperties;
vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect;
vulkan_info->transform_feedback_queries = physical_device_info->xfb_properties.transformFeedbackQueries;
vulkan_info->max_vertex_attrib_divisor = max(physical_device_info->vertex_divisor_properties.maxVertexAttribDivisor, 1);

if (!physical_device_info->conditional_rendering_features.conditionalRendering)
vulkan_info->EXT_conditional_rendering = false;
if (!physical_device_info->depth_clip_features.depthClipEnable)
vulkan_info->EXT_depth_clip_enable = false;

vulkan_info->vertex_attrib_zero_divisor = physical_device_info->vertex_divisor_features.vertexAttributeInstanceRateZeroDivisor;
if (!physical_device_info->vertex_divisor_features.vertexAttributeInstanceRateDivisor ||
!physical_device_info->vertex_divisor_features.vertexAttributeInstanceRateZeroDivisor)
{
ERR("Lacking support for VK_EXT_vertex_attribute_divisor.\n");
return E_INVALIDARG;
}

if (!physical_device_info->xfb_properties.transformFeedbackQueries)
{
ERR("Lacking support for transform feedback.\n");
return E_INVALIDARG;
}

if (!physical_device_info->vulkan_1_3_properties.storageTexelBufferOffsetSingleTexelAlignment ||
!physical_device_info->vulkan_1_3_properties.uniformTexelBufferOffsetSingleTexelAlignment)
{
ERR("Lacking support for single texel alignment.\n");
return E_INVALIDARG;
}

/* Disable unused Vulkan features. The following features need
* to remain enabled for DXVK in order to support D3D11on12:
Expand Down Expand Up @@ -2135,6 +2161,13 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
return E_INVALIDARG;
}

if (!physical_device_info->robustness2_features.robustBufferAccess2 ||
!physical_device_info->robustness2_features.robustImageAccess2)
{
ERR("Robustness2 features not supported. This is required.\n");
return E_INVALIDARG;
}

if (!physical_device_info->robustness2_features.nullDescriptor)
{
ERR("Null descriptor in VK_EXT_robustness2 is not supported by this implementation. This is required for correct operation.\n");
Expand Down Expand Up @@ -6681,7 +6714,9 @@ static void d3d12_device_caps_init_feature_options(struct d3d12_device *device)
options->StandardSwizzle64KBSupported = FALSE;
options->CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED;
options->CrossAdapterRowMajorTextureSupported = FALSE;
options->VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = vk_info->EXT_shader_viewport_index_layer;
options->VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation =
device->device_info.vulkan_1_2_features.shaderOutputViewportIndex &&
device->device_info.vulkan_1_2_features.shaderOutputLayer;
options->ResourceHeapTier = d3d12_device_determine_heap_tier(device);
}

Expand Down Expand Up @@ -6973,7 +7008,8 @@ static void d3d12_device_caps_init_shader_model(struct d3d12_device *device)

if (physical_device_info->vulkan_1_1_properties.subgroupSize >= 4 &&
(physical_device_info->vulkan_1_1_properties.subgroupSupportedOperations & required) == required &&
(physical_device_info->vulkan_1_1_properties.subgroupSupportedStages & required_stages) == required_stages)
(physical_device_info->vulkan_1_1_properties.subgroupSupportedStages & required_stages) == required_stages &&
(physical_device_info->vulkan_1_2_features.scalarBlockLayout || physical_device_info->vulkan_1_2_features.uniformBufferStandardLayout))
{
/* From testing on native Polaris drivers, AMD expose SM 6.5, even if lots of features are not supported.
* This is a good hint that shader model versions are not tied to features which have caps bits.
Expand Down Expand Up @@ -7553,6 +7589,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
out_free_private_store:
vkd3d_private_store_destroy(&device->private_store);
out_free_vk_resources:
d3d12_device_destroy_vkd3d_queues(device);
vk_procs = &device->vk_procs;
VK_CALL(vkDestroyDevice(device->vk_device, NULL));
out_free_instance:
Expand Down Expand Up @@ -7628,8 +7665,11 @@ bool d3d12_device_validate_shader_meta(struct d3d12_device *device, const struct
return false;
}

/* From Vulkan 1.2 promotion of the extension:
* Enabling both features is equivalent to enabling the VK_EXT_shader_viewport_index_layer extension. */
if ((meta->flags & VKD3D_SHADER_META_FLAG_USES_SHADER_VIEWPORT_INDEX_LAYER) &&
!device->vk_info.EXT_shader_viewport_index_layer)
(!device->device_info.vulkan_1_2_features.shaderOutputLayer ||
!device->device_info.vulkan_1_2_features.shaderOutputViewportIndex))
{
WARN("Attempting to use shader viewport index layer in shader %016"PRIx64", but this requires VK_EXT_shader_viewport_index_layer.\n", meta->hash);
return false;
Expand Down
3 changes: 2 additions & 1 deletion libs/vkd3d/meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,8 @@ static HRESULT vkd3d_meta_ops_common_init(struct vkd3d_meta_ops_common *meta_ops
{
VkResult vr;

if (device->vk_info.EXT_shader_viewport_index_layer)
if (device->device_info.vulkan_1_2_features.shaderOutputViewportIndex &&
device->device_info.vulkan_1_2_features.shaderOutputLayer)
{
if ((vr = vkd3d_meta_create_shader_module(device, SPIRV_CODE(vs_fullscreen_layer), &meta_ops_common->vk_module_fullscreen_vs)) < 0)
{
Expand Down
7 changes: 3 additions & 4 deletions libs/vkd3d/shaders/cs_resolve_binary_queries.comp
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
#version 450

#extension GL_ARB_gpu_shader_int64 : require
#extension GL_EXT_buffer_reference : require

layout(local_size_x = 64) in;

layout(std430, buffer_reference, buffer_reference_align = 8)
writeonly buffer dst_buffer_t {
uint64_t queries[];
uvec2 queries[];
};

layout(std430, buffer_reference, buffer_reference_align = 8)
readonly buffer src_buffer_t {
uint64_t queries[];
uvec2 queries[];
};

layout(push_constant)
Expand All @@ -26,5 +25,5 @@ void main() {
uint thread_id = gl_GlobalInvocationID.x;

if (thread_id < query_count)
dst_buffer.queries[thread_id] = min(src_buffer.queries[thread_id], uint64_t(1u));
dst_buffer.queries[thread_id] = any(notEqual(src_buffer.queries[thread_id], uvec2(0))) ? uvec2(1, 0) : uvec2(0);
}
18 changes: 12 additions & 6 deletions libs/vkd3d/shaders/cs_resolve_query.comp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#version 450

#extension GL_ARB_gpu_shader_int64 : require
#extension GL_EXT_buffer_reference : require

layout(local_size_x = 64) in;
Expand All @@ -9,12 +8,12 @@ layout(constant_id = 0) const uint c_field_count = 1;

layout(std430, buffer_reference, buffer_reference_align = 8)
buffer writeonly dst_queries_t {
uint64_t queries[];
uvec2 queries[];
};

layout(std430, buffer_reference, buffer_reference_align = 8)
readonly buffer src_queries_t {
uint64_t queries[];
uvec2 queries[];
};

struct query_map_entry_t {
Expand All @@ -36,6 +35,13 @@ uniform u_info_t {
uint query_count;
};

uvec2 uadd64(uvec2 a, uvec2 b) {
uint carry;
uint lo = uaddCarry(a.x, b.x, carry);
uint hi = a.y + b.y + carry;
return uvec2(lo, hi);
}

void main() {
uint thread_id = gl_GlobalInvocationID.x;

Expand All @@ -45,7 +51,7 @@ void main() {
// The query map is an array of linked lists, with the
// first query_count entries guaranteed to be list heads
query_map_entry_t entry = query_map.entries[thread_id];
uint64_t dst_data[c_field_count];
uvec2 dst_data[c_field_count];

// By copying the first query we get the reset for free
for (uint i = 0; i < c_field_count; i++)
Expand All @@ -56,10 +62,10 @@ void main() {
entry = query_map.entries[entry.next];

for (uint i = 0; i < c_field_count; i++)
dst_data[i] += src_buffer.queries[c_field_count * entry.src_index + i];
dst_data[i] = uadd64(dst_data[i], src_buffer.queries[c_field_count * entry.src_index + i]);
}

// dst_index has the same value for all entries in the list
for (uint i = 0; i < c_field_count; i++)
dst_buffer.queries[c_field_count * entry.dst_index + i] = dst_data[i];
}
}
3 changes: 1 addition & 2 deletions libs/vkd3d/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -4407,8 +4407,7 @@ static HRESULT d3d12_pipeline_state_init_graphics_create_info(struct d3d12_pipel
case D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA:
input_rate = VK_VERTEX_INPUT_RATE_INSTANCE;
instance_divisor = e->InstanceDataStepRate;
if (instance_divisor > vk_info->max_vertex_attrib_divisor
|| (!instance_divisor && !vk_info->vertex_attrib_zero_divisor))
if (instance_divisor > vk_info->max_vertex_attrib_divisor)
{
FIXME("Instance divisor %u not supported by Vulkan implementation.\n", instance_divisor);
instance_divisor = 1;
Expand Down
5 changes: 1 addition & 4 deletions libs/vkd3d/vkd3d_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ struct vkd3d_vulkan_info
bool EXT_image_view_min_lod;
bool EXT_robustness2;
bool EXT_shader_stencil_export;
bool EXT_shader_viewport_index_layer;
bool EXT_transform_feedback;
bool EXT_vertex_attribute_divisor;
bool EXT_extended_dynamic_state2;
Expand Down Expand Up @@ -170,9 +169,6 @@ struct vkd3d_vulkan_info
const char* const* extension_names;

bool rasterization_stream;
bool transform_feedback_queries;

bool vertex_attrib_zero_divisor;
unsigned int max_vertex_attrib_divisor;

VkPhysicalDeviceLimits device_limits;
Expand Down Expand Up @@ -3951,6 +3947,7 @@ struct vkd3d_physical_device_info
VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties;
VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT shader_module_identifier_properties;
VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_properties;
VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT graphics_pipeline_library_properties;

VkPhysicalDeviceProperties2KHR properties2;

Expand Down
Loading