mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08: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->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;
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user