vkd3d: Disable primitive restart when using non-compatible topologies.
Primitive restart is only used for strip primitive types, and must be ignored for lists. Use and require extended_dynamic_state2 for this purpose. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
cfeaa18b09
commit
6f43f450c8
|
@ -29,6 +29,7 @@ There are some hard requirements on drivers to be able to implement D3D12 in a r
|
|||
- `VK_KHR_copy_commands2`
|
||||
- `VK_KHR_dynamic_rendering`
|
||||
- `VK_EXT_extended_dynamic_state`
|
||||
- `VK_EXT_extended_dynamic_state2`
|
||||
|
||||
Some notable extensions that **should** be supported for optimal or correct behavior.
|
||||
These extensions will likely become mandatory later.
|
||||
|
|
|
@ -5254,6 +5254,15 @@ static void d3d12_command_list_update_dynamic_state(struct d3d12_command_list *l
|
|||
dyn_state->vk_primitive_topology));
|
||||
}
|
||||
|
||||
if (dyn_state->dirty_flags & VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART)
|
||||
{
|
||||
/* The primitive restart dynamic state is only present if the PSO
|
||||
* has a strip cut value, so we only need to check if the
|
||||
* current primitive topology is a strip type. */
|
||||
VK_CALL(vkCmdSetPrimitiveRestartEnableEXT(list->vk_command_buffer,
|
||||
vk_primitive_topology_supports_restart(dyn_state->vk_primitive_topology)));
|
||||
}
|
||||
|
||||
if (dyn_state->dirty_flags & VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE)
|
||||
{
|
||||
update_vbos = (dyn_state->dirty_vbos | dyn_state->dirty_vbo_strides) & list->state->graphics.vertex_buffer_mask;
|
||||
|
@ -6796,7 +6805,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(d3d12_co
|
|||
dyn_state->primitive_topology = topology;
|
||||
dyn_state->vk_primitive_topology = vk_topology_from_d3d12_topology(topology);
|
||||
d3d12_command_list_invalidate_current_pipeline(list, false);
|
||||
dyn_state->dirty_flags |= VKD3D_DYNAMIC_STATE_TOPOLOGY;
|
||||
dyn_state->dirty_flags |= VKD3D_DYNAMIC_STATE_TOPOLOGY | VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART;
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(d3d12_command_list_iface *iface,
|
||||
|
|
|
@ -102,6 +102,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
|
|||
VK_EXTENSION(EXT_TRANSFORM_FEEDBACK, EXT_transform_feedback),
|
||||
VK_EXTENSION(EXT_VERTEX_ATTRIBUTE_DIVISOR, EXT_vertex_attribute_divisor),
|
||||
VK_EXTENSION(EXT_EXTENDED_DYNAMIC_STATE, EXT_extended_dynamic_state),
|
||||
VK_EXTENSION(EXT_EXTENDED_DYNAMIC_STATE_2, EXT_extended_dynamic_state2),
|
||||
VK_EXTENSION(EXT_EXTERNAL_MEMORY_HOST, EXT_external_memory_host),
|
||||
VK_EXTENSION(EXT_4444_FORMATS, EXT_4444_formats),
|
||||
VK_EXTENSION(EXT_SHADER_IMAGE_ATOMIC_INT64, EXT_shader_image_atomic_int64),
|
||||
|
@ -1253,6 +1254,12 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|||
vk_prepend_struct(&info->features2, &info->extended_dynamic_state_features);
|
||||
}
|
||||
|
||||
if (vulkan_info->EXT_extended_dynamic_state2)
|
||||
{
|
||||
info->extended_dynamic_state2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT;
|
||||
vk_prepend_struct(&info->features2, &info->extended_dynamic_state2_features);
|
||||
}
|
||||
|
||||
if (vulkan_info->EXT_external_memory_host)
|
||||
{
|
||||
info->external_memory_host_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT;
|
||||
|
@ -1920,6 +1927,10 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|||
acceleration_structure = &physical_device_info->acceleration_structure_features;
|
||||
acceleration_structure->accelerationStructureCaptureReplay = VK_FALSE;
|
||||
|
||||
/* Don't need or require these. */
|
||||
physical_device_info->extended_dynamic_state2_features.extendedDynamicState2LogicOp = VK_FALSE;
|
||||
physical_device_info->extended_dynamic_state2_features.extendedDynamicState2PatchControlPoints = VK_FALSE;
|
||||
|
||||
if (!physical_device_info->descriptor_indexing_properties.robustBufferAccessUpdateAfterBind)
|
||||
{
|
||||
/* Generally, we cannot enable robustness if this is not supported,
|
||||
|
@ -1991,6 +2002,12 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (!physical_device_info->extended_dynamic_state2_features.extendedDynamicState2)
|
||||
{
|
||||
ERR("EXT_extended_dynamic_state2 is not supported by this implementation. This is required for correct operation.\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -2822,6 +2822,7 @@ static uint32_t d3d12_graphics_pipeline_state_init_dynamic_state(struct d3d12_pi
|
|||
{ VKD3D_DYNAMIC_STATE_TOPOLOGY, VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE, VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT },
|
||||
{ VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR },
|
||||
{ VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART, VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT },
|
||||
};
|
||||
|
||||
dynamic_state_flags = 0;
|
||||
|
@ -2866,6 +2867,9 @@ static uint32_t d3d12_graphics_pipeline_state_init_dynamic_state(struct d3d12_pi
|
|||
if (d3d12_device_supports_variable_shading_rate_tier_1(state->device) && graphics->rt_count)
|
||||
dynamic_state_flags |= VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE;
|
||||
|
||||
if (graphics->index_buffer_strip_cut_value)
|
||||
dynamic_state_flags |= VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART;
|
||||
|
||||
/* Build dynamic state create info */
|
||||
for (i = 0, count = 0; i < ARRAY_SIZE(dynamic_state_list); i++)
|
||||
{
|
||||
|
@ -4144,7 +4148,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
|
|||
/* Try to keep as much dynamic state as possible so we don't have to rebind state unnecessarily. */
|
||||
|
||||
if (graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH &&
|
||||
graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)
|
||||
graphics->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED)
|
||||
pipeline_key.dynamic_topology = true;
|
||||
else
|
||||
pipeline_key.topology = dyn_state->primitive_topology;
|
||||
|
|
|
@ -149,6 +149,7 @@ struct vkd3d_vulkan_info
|
|||
bool EXT_transform_feedback;
|
||||
bool EXT_vertex_attribute_divisor;
|
||||
bool EXT_extended_dynamic_state;
|
||||
bool EXT_extended_dynamic_state2;
|
||||
bool EXT_external_memory_host;
|
||||
bool EXT_4444_formats;
|
||||
bool EXT_shader_image_atomic_int64;
|
||||
|
@ -1416,7 +1417,7 @@ HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device,
|
|||
VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count,
|
||||
const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout);
|
||||
|
||||
#define VKD3D_MAX_DYNAMIC_STATE_COUNT (7)
|
||||
#define VKD3D_MAX_DYNAMIC_STATE_COUNT (8)
|
||||
|
||||
enum vkd3d_dynamic_state_flag
|
||||
{
|
||||
|
@ -1429,6 +1430,7 @@ enum vkd3d_dynamic_state_flag
|
|||
VKD3D_DYNAMIC_STATE_VERTEX_BUFFER = (1 << 6),
|
||||
VKD3D_DYNAMIC_STATE_VERTEX_BUFFER_STRIDE = (1 << 7),
|
||||
VKD3D_DYNAMIC_STATE_FRAGMENT_SHADING_RATE = (1 << 8),
|
||||
VKD3D_DYNAMIC_STATE_PRIMITIVE_RESTART = (1 << 9),
|
||||
};
|
||||
|
||||
struct vkd3d_shader_debug_ring_spec_constants
|
||||
|
@ -1608,6 +1610,21 @@ HRESULT vkd3d_pipeline_state_desc_from_d3d12_compute_desc(struct d3d12_pipeline_
|
|||
HRESULT vkd3d_pipeline_state_desc_from_d3d12_stream_desc(struct d3d12_pipeline_state_desc *desc,
|
||||
const D3D12_PIPELINE_STATE_STREAM_DESC *d3d12_desc, VkPipelineBindPoint *vk_bind_point);
|
||||
|
||||
static inline bool vk_primitive_topology_supports_restart(VkPrimitiveTopology topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct vkd3d_pipeline_key
|
||||
{
|
||||
D3D12_PRIMITIVE_TOPOLOGY topology;
|
||||
|
@ -2958,6 +2975,7 @@ struct vkd3d_physical_device_info
|
|||
VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR subgroup_extended_types_features;
|
||||
VkPhysicalDeviceRobustness2FeaturesEXT robustness2_features;
|
||||
VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extended_dynamic_state_features;
|
||||
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT extended_dynamic_state2_features;
|
||||
VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE mutable_descriptor_features;
|
||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR ray_tracing_pipeline_features;
|
||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration_structure_features;
|
||||
|
|
|
@ -245,6 +245,9 @@ VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveTopologyEXT)
|
|||
VK_DEVICE_EXT_PFN(vkCmdSetScissorWithCountEXT)
|
||||
VK_DEVICE_EXT_PFN(vkCmdSetViewportWithCountEXT)
|
||||
|
||||
/* VK_EXT_extended_dynamic_state2 */
|
||||
VK_DEVICE_EXT_PFN(vkCmdSetPrimitiveRestartEnableEXT)
|
||||
|
||||
/* VK_EXT_external_memory_host */
|
||||
VK_DEVICE_EXT_PFN(vkGetMemoryHostPointerPropertiesEXT)
|
||||
|
||||
|
|
Loading…
Reference in New Issue