mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d: Implement instance data step rate.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b2dc48c611
commit
ebde6bd229
@ -905,6 +905,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|||||||
|
|
||||||
vulkan_info->device_limits = device_properties2.properties.limits;
|
vulkan_info->device_limits = device_properties2.properties.limits;
|
||||||
vulkan_info->sparse_properties = device_properties2.properties.sparseProperties;
|
vulkan_info->sparse_properties = device_properties2.properties.sparseProperties;
|
||||||
|
vulkan_info->max_vertex_attrib_divisor = max(vertex_divisor_properties.maxVertexAttribDivisor, 1);
|
||||||
|
|
||||||
device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
|
device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
|
||||||
device->feature_options.OutputMergerLogicOp = features->logicOp;
|
device->feature_options.OutputMergerLogicOp = features->logicOp;
|
||||||
|
@ -1866,7 +1866,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||||
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
|
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
VkVertexInputBindingDivisorDescriptionEXT *binding_divisor;
|
||||||
|
const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
|
||||||
const struct vkd3d_shader_compile_arguments *compile_args;
|
const struct vkd3d_shader_compile_arguments *compile_args;
|
||||||
|
uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT];
|
||||||
uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT];
|
uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT];
|
||||||
struct vkd3d_shader_compile_arguments ps_compile_args;
|
struct vkd3d_shader_compile_arguments ps_compile_args;
|
||||||
const struct d3d12_root_signature *root_signature;
|
const struct d3d12_root_signature *root_signature;
|
||||||
@ -1877,6 +1880,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
VkSampleCountFlagBits sample_count;
|
VkSampleCountFlagBits sample_count;
|
||||||
const struct vkd3d_format *format;
|
const struct vkd3d_format *format;
|
||||||
enum VkVertexInputRate input_rate;
|
enum VkVertexInputRate input_rate;
|
||||||
|
unsigned int instance_divisor;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
size_t rt_count;
|
size_t rt_count;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
@ -2106,6 +2110,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
if (FAILED(hr = compute_input_layout_offsets(&desc->InputLayout, aligned_offsets)))
|
if (FAILED(hr = compute_input_layout_offsets(&desc->InputLayout, aligned_offsets)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
graphics->instance_divisor_count = 0;
|
||||||
for (i = 0, j = 0, mask = 0; i < graphics->attribute_count; ++i)
|
for (i = 0, j = 0, mask = 0; i < graphics->attribute_count; ++i)
|
||||||
{
|
{
|
||||||
const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i];
|
const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i];
|
||||||
@ -2118,7 +2123,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->InputSlot >= ARRAY_SIZE(graphics->input_rates))
|
if (e->InputSlot >= ARRAY_SIZE(graphics->input_rates)
|
||||||
|
|| e->InputSlot >= ARRAY_SIZE(instance_divisors))
|
||||||
{
|
{
|
||||||
WARN("Invalid input slot %#x.\n", e->InputSlot);
|
WARN("Invalid input slot %#x.\n", e->InputSlot);
|
||||||
hr = E_INVALIDARG;
|
hr = E_INVALIDARG;
|
||||||
@ -2145,12 +2151,18 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
{
|
{
|
||||||
case D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA:
|
case D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA:
|
||||||
input_rate = VK_VERTEX_INPUT_RATE_VERTEX;
|
input_rate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
|
instance_divisor = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA:
|
case D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA:
|
||||||
if (e->InstanceDataStepRate != 1)
|
|
||||||
FIXME("Ignoring step rate %#x on input element %u.\n", e->InstanceDataStepRate, i);
|
|
||||||
input_rate = VK_VERTEX_INPUT_RATE_INSTANCE;
|
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))
|
||||||
|
{
|
||||||
|
FIXME("Instance divisor %u not supported by Vulkan implementation.\n", instance_divisor);
|
||||||
|
instance_divisor = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2159,14 +2171,25 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & (1u << e->InputSlot) && graphics->input_rates[e->InputSlot] != input_rate)
|
if (mask & (1u << e->InputSlot) && (graphics->input_rates[e->InputSlot] != input_rate
|
||||||
|
|| instance_divisors[e->InputSlot] != instance_divisor))
|
||||||
{
|
{
|
||||||
FIXME("Input slot class %#x on input element %u conflicts with earlier input slot class %#x.\n",
|
FIXME("Input slot rate %#x, instance divisor %u on input element %u conflicts "
|
||||||
e->InputSlotClass, e->InputSlot, graphics->input_rates[e->InputSlot]);
|
"with earlier input slot rate %#x, instance divisor %u.\n",
|
||||||
|
input_rate, instance_divisor, e->InputSlot,
|
||||||
|
graphics->input_rates[e->InputSlot], instance_divisors[e->InputSlot]);
|
||||||
hr = E_INVALIDARG;
|
hr = E_INVALIDARG;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics->input_rates[e->InputSlot] = input_rate;
|
graphics->input_rates[e->InputSlot] = input_rate;
|
||||||
|
instance_divisors[e->InputSlot] = instance_divisor;
|
||||||
|
if (instance_divisor != 1 && !(mask & (1u << e->InputSlot)))
|
||||||
|
{
|
||||||
|
binding_divisor = &graphics->instance_divisors[graphics->instance_divisor_count++];
|
||||||
|
binding_divisor->binding = e->InputSlot;
|
||||||
|
binding_divisor->divisor = instance_divisor;
|
||||||
|
}
|
||||||
mask |= 1u << e->InputSlot;
|
mask |= 1u << e->InputSlot;
|
||||||
}
|
}
|
||||||
graphics->attribute_count = j;
|
graphics->attribute_count = j;
|
||||||
@ -2331,6 +2354,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
|
|||||||
struct VkVertexInputBindingDescription bindings[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
struct VkVertexInputBindingDescription bindings[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
|
||||||
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
|
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
|
||||||
|
VkPipelineVertexInputDivisorStateCreateInfoEXT input_divisor_info;
|
||||||
struct VkPipelineVertexInputStateCreateInfo input_desc;
|
struct VkPipelineVertexInputStateCreateInfo input_desc;
|
||||||
struct VkPipelineInputAssemblyStateCreateInfo ia_desc;
|
struct VkPipelineInputAssemblyStateCreateInfo ia_desc;
|
||||||
struct VkPipelineColorBlendStateCreateInfo blend_desc;
|
struct VkPipelineColorBlendStateCreateInfo blend_desc;
|
||||||
@ -2414,6 +2438,15 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
|
|||||||
input_desc.vertexAttributeDescriptionCount = graphics->attribute_count;
|
input_desc.vertexAttributeDescriptionCount = graphics->attribute_count;
|
||||||
input_desc.pVertexAttributeDescriptions = graphics->attributes;
|
input_desc.pVertexAttributeDescriptions = graphics->attributes;
|
||||||
|
|
||||||
|
if (graphics->instance_divisor_count)
|
||||||
|
{
|
||||||
|
input_desc.pNext = &input_divisor_info;
|
||||||
|
input_divisor_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
|
||||||
|
input_divisor_info.pNext = NULL;
|
||||||
|
input_divisor_info.vertexBindingDivisorCount = graphics->instance_divisor_count;
|
||||||
|
input_divisor_info.pVertexBindingDivisors = graphics->instance_divisors;
|
||||||
|
}
|
||||||
|
|
||||||
ia_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
ia_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
ia_desc.pNext = NULL;
|
ia_desc.pNext = NULL;
|
||||||
ia_desc.flags = 0;
|
ia_desc.flags = 0;
|
||||||
|
@ -86,6 +86,7 @@ struct vkd3d_vulkan_info
|
|||||||
bool EXT_vertex_attribute_divisor;
|
bool EXT_vertex_attribute_divisor;
|
||||||
|
|
||||||
bool vertex_attrib_zero_divisor;
|
bool vertex_attrib_zero_divisor;
|
||||||
|
unsigned int max_vertex_attrib_divisor;
|
||||||
|
|
||||||
VkPhysicalDeviceLimits device_limits;
|
VkPhysicalDeviceLimits device_limits;
|
||||||
VkPhysicalDeviceSparseProperties sparse_properties;
|
VkPhysicalDeviceSparseProperties sparse_properties;
|
||||||
@ -513,6 +514,8 @@ struct d3d12_graphics_pipeline_state
|
|||||||
|
|
||||||
struct VkVertexInputAttributeDescription attributes[D3D12_VS_INPUT_REGISTER_COUNT];
|
struct VkVertexInputAttributeDescription attributes[D3D12_VS_INPUT_REGISTER_COUNT];
|
||||||
enum VkVertexInputRate input_rates[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
enum VkVertexInputRate input_rates[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
||||||
|
VkVertexInputBindingDivisorDescriptionEXT instance_divisors[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
|
||||||
|
size_t instance_divisor_count;
|
||||||
size_t attribute_count;
|
size_t attribute_count;
|
||||||
|
|
||||||
struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
|
struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
|
||||||
@ -767,7 +770,6 @@ struct d3d12_device
|
|||||||
struct vkd3d_fence_worker fence_worker;
|
struct vkd3d_fence_worker fence_worker;
|
||||||
|
|
||||||
pthread_mutex_t pipeline_cache_mutex;
|
pthread_mutex_t pipeline_cache_mutex;
|
||||||
struct rb_tree pipeline_cache;
|
|
||||||
VkPipelineCache vk_pipeline_cache;
|
VkPipelineCache vk_pipeline_cache;
|
||||||
|
|
||||||
/* A sampler used for SpvOpImageFetch. */
|
/* A sampler used for SpvOpImageFetch. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user