Looks good to me, do you have tests?

Reviewed-by: Samuel Pitoiset <samuel.pitoi...@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;

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to