[MESA_SHADER_COMPUTE] = DEBUG_CS,
};
+struct anv_spirv_debug_data {
+ struct anv_device *device;
+ const struct anv_shader_module *module;
+};
+
+static void anv_spirv_nir_debug(void *private_data,
+ enum nir_spirv_debug_level level,
+ size_t spirv_offset,
+ const char *message)
+{
+ struct anv_spirv_debug_data *debug_data = private_data;
+ static const VkDebugReportFlagsEXT vk_flags[] = {
+ [NIR_SPIRV_DEBUG_LEVEL_INFO] = VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
+ [NIR_SPIRV_DEBUG_LEVEL_WARNING] = VK_DEBUG_REPORT_WARNING_BIT_EXT,
+ [NIR_SPIRV_DEBUG_LEVEL_ERROR] = VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ };
+ char buffer[256];
+
+ snprintf(buffer, sizeof(buffer), "SPIR-V offset %lu: %s", (unsigned long) spirv_offset, message);
+
+ vk_debug_report(&debug_data->device->instance->debug_report_callbacks,
+ vk_flags[level],
+ VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
+ (uint64_t) (uintptr_t) debug_data->module,
+ 0, 0, "anv", buffer);
+}
+
/* Eventually, this will become part of anv_CreateShader. Unfortunately,
* we can't do that yet because we don't have the ability to copy nir.
*/
}
}
+ struct anv_spirv_debug_data spirv_debug_data = {
+ .device = device,
+ .module = module,
+ };
struct spirv_to_nir_options spirv_options = {
.lower_workgroup_access_to_offsets = true,
.caps = {
+ .demote_to_helper_invocation = true,
.derivative_group = true,
.descriptor_array_dynamic_indexing = true,
.descriptor_array_non_uniform_indexing = true,
* with certain code / code generators.
*/
.shared_addr_format = nir_address_format_32bit_offset,
+ .debug = {
+ .func = anv_spirv_nir_debug,
+ .private_data = &spirv_debug_data,
+ },
};
NIR_PASS_V(nir, nir_remove_dead_variables,
nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
- NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_global,
- nir_address_format_64bit_global);
-
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_lower_io_to_temporaries,
nir_shader_get_entrypoint(nir), true, false);
/* Vulkan uses the separate-shader linking model */
nir->info.separate_shader = true;
- nir = brw_preprocess_nir(compiler, nir, NULL);
+ brw_preprocess_nir(compiler, nir, NULL);
return nir;
}
}
}
+static void
+populate_base_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
+ struct brw_base_prog_key *key)
+{
+ if (flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT)
+ key->subgroup_size_type = BRW_SUBGROUP_SIZE_VARYING;
+ else
+ key->subgroup_size_type = BRW_SUBGROUP_SIZE_API_CONSTANT;
+
+ populate_sampler_prog_key(devinfo, &key->tex);
+}
+
static void
populate_vs_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
struct brw_vs_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
/* XXX: Handle vertex input work-arounds */
static void
populate_tcs_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
unsigned input_vertices,
struct brw_tcs_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
key->input_vertices = input_vertices;
}
static void
populate_tes_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
struct brw_tes_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
}
static void
populate_gs_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
struct brw_gs_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
}
static void
populate_wm_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
const struct anv_subpass *subpass,
const VkPipelineMultisampleStateCreateInfo *ms_info,
struct brw_wm_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
/* We set this to 0 here and set to the actual value before we call
* brw_compile_fs.
static void
populate_cs_prog_key(const struct gen_device_info *devinfo,
+ VkPipelineShaderStageCreateFlags flags,
+ const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *rss_info,
struct brw_cs_prog_key *key)
{
memset(key, 0, sizeof(*key));
- populate_sampler_prog_key(devinfo, &key->tex);
+ populate_base_prog_key(devinfo, flags, &key->base);
+
+ if (rss_info) {
+ assert(key->base.subgroup_size_type != BRW_SUBGROUP_SIZE_VARYING);
+
+ /* These enum values are expressly chosen to be equal to the subgroup
+ * size that they require.
+ */
+ assert(rss_info->requiredSubgroupSize == 8 ||
+ rss_info->requiredSubgroupSize == 16 ||
+ rss_info->requiredSubgroupSize == 32);
+ key->base.subgroup_size_type = rss_info->requiredSubgroupSize;
+ } else if (flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT) {
+ /* If the client expressly requests full subgroups and they don't
+ * specify a subgroup size, we need to pick one. If they're requested
+ * varying subgroup sizes, we set it to UNIFORM and let the back-end
+ * compiler pick. Otherwise, we specify the API value of 32.
+ * Performance will likely be terrible in this case but there's nothing
+ * we can do about that. The client should have chosen a size.
+ */
+ if (flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT)
+ key->base.subgroup_size_type = BRW_SUBGROUP_SIZE_UNIFORM;
+ else
+ key->base.subgroup_size_type = BRW_SUBGROUP_SIZE_REQUIRE_32;
+ }
}
struct anv_pipeline_stage {
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS_V(nir, nir_lower_wpos_center, pipeline->sample_shading_enable);
- NIR_PASS_V(nir, anv_nir_lower_input_attachments);
+ NIR_PASS_V(nir, nir_lower_input_attachments, false);
}
NIR_PASS_V(nir, anv_nir_lower_ycbcr_textures, layout);
NIR_PASS_V(nir, brw_nir_lower_image_load_store, compiler->devinfo);
+ NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_global,
+ nir_address_format_64bit_global);
+
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
if (layout) {
anv_nir_apply_pipeline_layout(pdevice,
struct anv_pipeline_stage *next_stage)
{
if (next_stage)
- brw_nir_link_shaders(compiler, &vs_stage->nir, &next_stage->nir);
+ brw_nir_link_shaders(compiler, vs_stage->nir, next_stage->nir);
}
static const unsigned *
{
assert(tes_stage && tes_stage->stage == MESA_SHADER_TESS_EVAL);
- brw_nir_link_shaders(compiler, &tcs_stage->nir, &tes_stage->nir);
+ brw_nir_link_shaders(compiler, tcs_stage->nir, tes_stage->nir);
nir_lower_patch_vertices(tes_stage->nir,
tcs_stage->nir->info.tess.tcs_vertices_out,
struct anv_pipeline_stage *next_stage)
{
if (next_stage)
- brw_nir_link_shaders(compiler, &tes_stage->nir, &next_stage->nir);
+ brw_nir_link_shaders(compiler, tes_stage->nir, next_stage->nir);
}
static const unsigned *
struct anv_pipeline_stage *next_stage)
{
if (next_stage)
- brw_nir_link_shaders(compiler, &gs_stage->nir, &next_stage->nir);
+ brw_nir_link_shaders(compiler, gs_stage->nir, next_stage->nir);
}
static const unsigned *
const struct gen_device_info *devinfo = &pipeline->device->info;
switch (stage) {
case MESA_SHADER_VERTEX:
- populate_vs_prog_key(devinfo, &stages[stage].key.vs);
+ populate_vs_prog_key(devinfo, sinfo->flags, &stages[stage].key.vs);
break;
case MESA_SHADER_TESS_CTRL:
- populate_tcs_prog_key(devinfo,
+ populate_tcs_prog_key(devinfo, sinfo->flags,
info->pTessellationState->patchControlPoints,
&stages[stage].key.tcs);
break;
case MESA_SHADER_TESS_EVAL:
- populate_tes_prog_key(devinfo, &stages[stage].key.tes);
+ populate_tes_prog_key(devinfo, sinfo->flags, &stages[stage].key.tes);
break;
case MESA_SHADER_GEOMETRY:
- populate_gs_prog_key(devinfo, &stages[stage].key.gs);
+ populate_gs_prog_key(devinfo, sinfo->flags, &stages[stage].key.gs);
break;
case MESA_SHADER_FRAGMENT:
- populate_wm_prog_key(devinfo, pipeline->subpass,
+ populate_wm_prog_key(devinfo, sinfo->flags,
+ pipeline->subpass,
info->pMultisampleState,
&stages[stage].key.wm);
break;
struct anv_shader_bin *bin = NULL;
- populate_cs_prog_key(&pipeline->device->info, &stage.key.cs);
+ const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT *rss_info =
+ vk_find_struct_const(info->stage.pNext,
+ PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT);
+
+ populate_cs_prog_key(&pipeline->device->info, info->stage.flags,
+ rss_info, &stage.key.cs);
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);