properties->vgprAllocationGranularity = 4;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
+ VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *properties =
+ (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
+ properties->maxVertexAttribDivisor = UINT32_MAX;
+ break;
+ }
default:
break;
}
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'),
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,
{
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)
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;
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;
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;