=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Implement instance data step rate.
Alexandre Julliard
julliard at winehq.org
Thu Oct 25 15:23:43 CDT 2018
Module: vkd3d
Branch: master
Commit: ebde6bd229d21af2ca732f2e8c1e8699d1bb9c9e
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=ebde6bd229d21af2ca732f2e8c1e8699d1bb9c9e
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Thu Oct 25 11:24:07 2018 +0200
vkd3d: Implement instance data step rate.
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
libs/vkd3d/device.c | 1 +
libs/vkd3d/state.c | 45 +++++++++++++++++++++++++++++++++++++++------
libs/vkd3d/vkd3d_private.h | 4 +++-
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 0adebcf..4f5cdd6 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -905,6 +905,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
vulkan_info->device_limits = device_properties2.properties.limits;
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.OutputMergerLogicOp = features->logicOp;
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 0deea28..7e0b1ee 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -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];
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
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;
+ uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT];
uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT];
struct vkd3d_shader_compile_arguments ps_compile_args;
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;
const struct vkd3d_format *format;
enum VkVertexInputRate input_rate;
+ unsigned int instance_divisor;
unsigned int i, j;
size_t rt_count;
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)))
goto fail;
+ graphics->instance_divisor_count = 0;
for (i = 0, j = 0, mask = 0; i < graphics->attribute_count; ++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;
}
- 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);
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:
input_rate = VK_VERTEX_INPUT_RATE_VERTEX;
+ instance_divisor = 1;
break;
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;
+ 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;
default:
@@ -2159,14 +2171,25 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
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",
- e->InputSlotClass, e->InputSlot, graphics->input_rates[e->InputSlot]);
+ FIXME("Input slot rate %#x, instance divisor %u on input element %u conflicts "
+ "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;
goto fail;
}
+
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;
}
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];
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
+ VkPipelineVertexInputDivisorStateCreateInfoEXT input_divisor_info;
struct VkPipelineVertexInputStateCreateInfo input_desc;
struct VkPipelineInputAssemblyStateCreateInfo ia_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.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.pNext = NULL;
ia_desc.flags = 0;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 3f53980..a2bf404 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -86,6 +86,7 @@ struct vkd3d_vulkan_info
bool EXT_vertex_attribute_divisor;
bool vertex_attrib_zero_divisor;
+ unsigned int max_vertex_attrib_divisor;
VkPhysicalDeviceLimits device_limits;
VkPhysicalDeviceSparseProperties sparse_properties;
@@ -513,6 +514,8 @@ struct d3d12_graphics_pipeline_state
struct VkVertexInputAttributeDescription attributes[D3D12_VS_INPUT_REGISTER_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;
struct VkAttachmentDescription attachments[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
@@ -767,7 +770,6 @@ struct d3d12_device
struct vkd3d_fence_worker fence_worker;
pthread_mutex_t pipeline_cache_mutex;
- struct rb_tree pipeline_cache;
VkPipelineCache vk_pipeline_cache;
/* A sampler used for SpvOpImageFetch. */
More information about the wine-cvs
mailing list