[Mesa-dev] [PATCH] radv: Implement VK_EXT_vertex_attribute_divisor.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Thu Apr 12 21:01:31 UTC 2018


Test test to the list.

On Thu, Apr 12, 2018 at 9:28 AM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Looks good to me, do you have tests?
>
> Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>
>
> On 04/12/2018 01:45 AM, Bas Nieuwenhuizen wrote:
>>
>> Pretty straight forward, just pass the divisors through the shader
>> key and then do a LLVM divide.
>> ---
>>   src/amd/vulkan/radv_device.c      |  6 ++++++
>>   src/amd/vulkan/radv_extensions.py |  1 +
>>   src/amd/vulkan/radv_nir_to_llvm.c | 26 +++++++++++++++++++-------
>>   src/amd/vulkan/radv_pipeline.c    | 26 ++++++++++++++++++++++----
>>   src/amd/vulkan/radv_private.h     |  1 +
>>   src/amd/vulkan/radv_shader.h      |  1 +
>>   6 files changed, 50 insertions(+), 11 deletions(-)
>>
>> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
>> index 41f8242754c..4cd24eb2e96 100644
>> --- a/src/amd/vulkan/radv_device.c
>> +++ b/src/amd/vulkan/radv_device.c
>> @@ -961,6 +961,12 @@ void radv_GetPhysicalDeviceProperties2(
>>                         properties->filterMinmaxSingleComponentFormats =
>> true;
>>                         break;
>>                 }
>> +               case
>> VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
>> +
>> VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *properties =
>> +
>> (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
>> +                       properties->maxVertexAttribDivisor = UINT32_MAX;
>> +                       break;
>> +               }
>>                 default:
>>                         break;
>>                 }
>> diff --git a/src/amd/vulkan/radv_extensions.py
>> b/src/amd/vulkan/radv_extensions.py
>> index bc63a34896a..48cf3ccd992 100644
>> --- a/src/amd/vulkan/radv_extensions.py
>> +++ b/src/amd/vulkan/radv_extensions.py
>> @@ -93,6 +93,7 @@ EXTENSIONS = [
>>       Extension('VK_EXT_global_priority',                   1,
>> 'device->rad_info.has_ctx_priority'),
>>       Extension('VK_EXT_sampler_filter_minmax',             1,
>> 'device->rad_info.chip_class >= CIK'),
>>       Extension('VK_EXT_shader_viewport_index_layer',       1, True),
>> +    Extension('VK_EXT_vertex_attribute_divisor',          1, True),
>>       Extension('VK_AMD_draw_indirect_count',               1, True),
>>       Extension('VK_AMD_gcn_shader',                        1, True),
>>       Extension('VK_AMD_rasterization_order',               1,
>> 'device->has_out_of_order_rast'),
>> diff --git a/src/amd/vulkan/radv_nir_to_llvm.c
>> b/src/amd/vulkan/radv_nir_to_llvm.c
>> index 2f0864da462..a6b48e297da 100644
>> --- a/src/amd/vulkan/radv_nir_to_llvm.c
>> +++ b/src/amd/vulkan/radv_nir_to_llvm.c
>> @@ -1794,14 +1794,26 @@ handle_vs_input_decl(struct radv_shader_context
>> *ctx,
>>         for (unsigned i = 0; i < attrib_count; ++i, ++idx) {
>>                 if (ctx->options->key.vs.instance_rate_inputs & (1u <<
>> (index + i))) {
>> -                       buffer_index = LLVMBuildAdd(ctx->ac.builder,
>> ctx->abi.instance_id,
>> -
>> ctx->abi.start_instance, "");
>> -                       if (ctx->options->key.vs.as_ls) {
>> -                               ctx->shader_info->vs.vgpr_comp_cnt =
>> -                                       MAX2(2,
>> ctx->shader_info->vs.vgpr_comp_cnt);
>> +                       uint32_t divisor =
>> ctx->options->key.vs.instance_rate_divisors[index + i];
>> +
>> +                       if (divisor) {
>> +                               buffer_index =
>> LLVMBuildAdd(ctx->ac.builder, ctx->abi.instance_id,
>> +
>> ctx->abi.start_instance, "");
>> +
>> +                               if (divisor != 1) {
>> +                                       buffer_index =
>> LLVMBuildUDiv(ctx->ac.builder, buffer_index,
>> +
>> LLVMConstInt(ctx->ac.i32, divisor, 0), "");
>> +                               }
>> +
>> +                               if (ctx->options->key.vs.as_ls) {
>> +                                       ctx->shader_info->vs.vgpr_comp_cnt
>> =
>> +                                               MAX2(2,
>> ctx->shader_info->vs.vgpr_comp_cnt);
>> +                               } else {
>> +                                       ctx->shader_info->vs.vgpr_comp_cnt
>> =
>> +                                               MAX2(1,
>> ctx->shader_info->vs.vgpr_comp_cnt);
>> +                               }
>>                         } else {
>> -                               ctx->shader_info->vs.vgpr_comp_cnt =
>> -                                       MAX2(1,
>> ctx->shader_info->vs.vgpr_comp_cnt);
>> +                               buffer_index = ctx->ac.i32_0;
>>                         }
>>                 } else
>>                         buffer_index = LLVMBuildAdd(ctx->ac.builder,
>> ctx->abi.vertex_id,
>> diff --git a/src/amd/vulkan/radv_pipeline.c
>> b/src/amd/vulkan/radv_pipeline.c
>> index 08abb9dbc47..91baac431b8 100644
>> --- a/src/amd/vulkan/radv_pipeline.c
>> +++ b/src/amd/vulkan/radv_pipeline.c
>> @@ -1743,22 +1743,38 @@ radv_generate_graphics_pipeline_key(struct
>> radv_pipeline *pipeline,
>>   {
>>         const VkPipelineVertexInputStateCreateInfo *input_state =
>>
>> pCreateInfo->pVertexInputState;
>> +       const VkPipelineVertexInputDivisorStateCreateInfoEXT
>> *divisor_state =
>> +               vk_find_struct_const(input_state->pNext,
>> PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
>> +
>>         struct radv_pipeline_key key;
>>         memset(&key, 0, sizeof(key));
>>         key.has_multiview_view_index = has_view_index;
>>         uint32_t binding_input_rate = 0;
>> +       uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
>>         for (unsigned i = 0; i <
>> input_state->vertexBindingDescriptionCount; ++i) {
>> -               if (input_state->pVertexBindingDescriptions[i].inputRate)
>> -                       binding_input_rate |= 1u <<
>> input_state->pVertexBindingDescriptions[i].binding;
>> +               if (input_state->pVertexBindingDescriptions[i].inputRate)
>> {
>> +                       unsigned binding =
>> input_state->pVertexBindingDescriptions[i].binding;
>> +                       binding_input_rate |= 1u << binding;
>> +                       instance_rate_divisors[binding] = 1;
>> +               }
>> +       }
>> +       if (divisor_state) {
>> +               for (unsigned i = 0; i <
>> divisor_state->vertexBindingDivisorCount; ++i) {
>> +
>> instance_rate_divisors[divisor_state->pVertexBindingDivisors[i].binding] =
>> +
>> divisor_state->pVertexBindingDivisors[i].divisor;
>> +               }
>>         }
>>         for (unsigned i = 0; i <
>> input_state->vertexAttributeDescriptionCount; ++i) {
>>                 unsigned binding;
>>                 binding =
>> input_state->pVertexAttributeDescriptions[i].binding;
>> -               if (binding_input_rate & (1u << binding))
>> -                       key.instance_rate_inputs |= 1u <<
>> input_state->pVertexAttributeDescriptions[i].location;
>> +               if (binding_input_rate & (1u << binding)) {
>> +                       unsigned location =
>> input_state->pVertexAttributeDescriptions[i].location;
>> +                       key.instance_rate_inputs |= 1u << location;
>> +                       key.instance_rate_divisors[location] =
>> instance_rate_divisors[binding];
>> +               }
>>         }
>>         if (pCreateInfo->pTessellationState)
>> @@ -1787,6 +1803,8 @@ radv_fill_shader_keys(struct radv_shader_variant_key
>> *keys,
>>                         nir_shader **nir)
>>   {
>>         keys[MESA_SHADER_VERTEX].vs.instance_rate_inputs =
>> key->instance_rate_inputs;
>> +       for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
>> +               keys[MESA_SHADER_VERTEX].vs.instance_rate_divisors[i] =
>> key->instance_rate_divisors[i];
>>         if (nir[MESA_SHADER_TESS_CTRL]) {
>>                 keys[MESA_SHADER_VERTEX].vs.as_ls = true;
>> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
>> index 9e655af844e..fb2e9d621b2 100644
>> --- a/src/amd/vulkan/radv_private.h
>> +++ b/src/amd/vulkan/radv_private.h
>> @@ -347,6 +347,7 @@ struct radv_pipeline_cache {
>>     struct radv_pipeline_key {
>>         uint32_t instance_rate_inputs;
>> +       uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
>>         unsigned tess_input_vertices;
>>         uint32_t col_format;
>>         uint32_t is_int8;
>> diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
>> index ae30d6125b1..f1fcb3754f1 100644
>> --- a/src/amd/vulkan/radv_shader.h
>> +++ b/src/amd/vulkan/radv_shader.h
>> @@ -55,6 +55,7 @@ struct radv_shader_module {
>>     struct radv_vs_variant_key {
>>         uint32_t instance_rate_inputs;
>> +       uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
>>         uint32_t as_es:1;
>>         uint32_t as_ls:1;
>>         uint32_t export_prim_id:1;
>>
>


More information about the mesa-dev mailing list