radv: Refactor required subgroup size in pipeline key.
This is to allow setting required subgroup size and full subgroups on more than just the compute stage. Use an enum (not the actual subgroup size integer) so that we can have some bits reserved there for future use. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23925>
This commit is contained in:
@@ -139,6 +139,7 @@ radv_pipeline_init_scratch(const struct radv_device *device, struct radv_pipelin
|
||||
|
||||
struct radv_pipeline_key
|
||||
radv_generate_pipeline_key(const struct radv_device *device, const struct radv_pipeline *pipeline,
|
||||
const VkPipelineShaderStageCreateInfo *stages, const unsigned num_stages,
|
||||
VkPipelineCreateFlags flags)
|
||||
{
|
||||
struct radv_pipeline_key key;
|
||||
@@ -155,6 +156,26 @@ radv_generate_pipeline_key(const struct radv_device *device, const struct radv_p
|
||||
|
||||
key.tex_non_uniform = device->instance->tex_non_uniform;
|
||||
|
||||
for (unsigned i = 0; i < num_stages; ++i) {
|
||||
const VkPipelineShaderStageCreateInfo *const stage = &stages[i];
|
||||
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *const subgroup_size =
|
||||
vk_find_struct_const(stage->pNext, PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
|
||||
const gl_shader_stage s = vk_to_mesa_shader_stage(stage->stage);
|
||||
|
||||
if (subgroup_size) {
|
||||
if (subgroup_size->requiredSubgroupSize == 32)
|
||||
key.subgroups[s].required_size = RADV_REQUIRED_WAVE32;
|
||||
else if (subgroup_size->requiredSubgroupSize == 64)
|
||||
key.subgroups[s].required_size = RADV_REQUIRED_WAVE64;
|
||||
else
|
||||
unreachable("Unsupported required subgroup size.");
|
||||
}
|
||||
|
||||
if (stage->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT) {
|
||||
key.subgroups[s].require_full = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
@@ -116,20 +116,7 @@ static struct radv_pipeline_key
|
||||
radv_generate_compute_pipeline_key(const struct radv_device *device, struct radv_compute_pipeline *pipeline,
|
||||
const VkComputePipelineCreateInfo *pCreateInfo)
|
||||
{
|
||||
const VkPipelineShaderStageCreateInfo *stage = &pCreateInfo->stage;
|
||||
struct radv_pipeline_key key = radv_generate_pipeline_key(device, &pipeline->base, pCreateInfo->flags);
|
||||
|
||||
const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *subgroup_size =
|
||||
vk_find_struct_const(stage->pNext, PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
|
||||
|
||||
if (subgroup_size) {
|
||||
assert(subgroup_size->requiredSubgroupSize == 32 || subgroup_size->requiredSubgroupSize == 64);
|
||||
key.cs.compute_subgroup_size = subgroup_size->requiredSubgroupSize;
|
||||
} else if (stage->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT) {
|
||||
key.cs.require_full_subgroups = true;
|
||||
}
|
||||
|
||||
return key;
|
||||
return radv_generate_pipeline_key(device, &pipeline->base, &pCreateInfo->stage, 1, pCreateInfo->flags);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -1814,7 +1814,8 @@ radv_generate_graphics_pipeline_key(const struct radv_device *device, const stru
|
||||
VkGraphicsPipelineLibraryFlagBitsEXT lib_flags)
|
||||
{
|
||||
const struct radv_physical_device *pdevice = device->physical_device;
|
||||
struct radv_pipeline_key key = radv_generate_pipeline_key(device, &pipeline->base, pCreateInfo->flags);
|
||||
struct radv_pipeline_key key = radv_generate_pipeline_key(device, &pipeline->base, pCreateInfo->pStages,
|
||||
pCreateInfo->stageCount, pCreateInfo->flags);
|
||||
|
||||
key.lib_flags = lib_flags;
|
||||
key.has_multiview_view_index = state->rp ? !!state->rp->view_mask : 0;
|
||||
|
@@ -549,7 +549,8 @@ radv_rt_pipeline_create(VkDevice _device, VkPipelineCache _cache, const VkRayTra
|
||||
pipeline->stages = stages;
|
||||
pipeline->groups = groups;
|
||||
|
||||
struct radv_pipeline_key key = radv_generate_pipeline_key(device, &pipeline->base.base, pCreateInfo->flags);
|
||||
struct radv_pipeline_key key = radv_generate_pipeline_key(device, &pipeline->base.base, pCreateInfo->pStages,
|
||||
pCreateInfo->stageCount, pCreateInfo->flags);
|
||||
|
||||
radv_rt_fill_stage_info(device, pCreateInfo, stages, &key);
|
||||
result = radv_rt_fill_group_info(device, pCreateInfo, stages, pipeline->groups);
|
||||
|
@@ -2430,7 +2430,9 @@ struct radv_graphics_pipeline_create_info {
|
||||
};
|
||||
|
||||
struct radv_pipeline_key radv_generate_pipeline_key(const struct radv_device *device,
|
||||
const struct radv_pipeline *pipeline, VkPipelineCreateFlags flags);
|
||||
const struct radv_pipeline *pipeline,
|
||||
const VkPipelineShaderStageCreateInfo *stages,
|
||||
const unsigned num_stages, VkPipelineCreateFlags flags);
|
||||
|
||||
void radv_pipeline_init(struct radv_device *device, struct radv_pipeline *pipeline, enum radv_pipeline_type type);
|
||||
|
||||
|
@@ -332,13 +332,14 @@ radv_shader_spirv_to_nir(struct radv_device *device, const struct radv_pipeline_
|
||||
const struct radv_pipeline_key *key, bool is_internal)
|
||||
{
|
||||
unsigned subgroup_size = 64, ballot_bit_size = 64;
|
||||
if (key->cs.compute_subgroup_size) {
|
||||
/* Only compute shaders currently support requiring a
|
||||
const unsigned required_subgroup_size = key->subgroups[stage->stage].required_size * 32;
|
||||
if (required_subgroup_size) {
|
||||
/* Only compute/mesh/task shaders currently support requiring a
|
||||
* specific subgroup size.
|
||||
*/
|
||||
assert(stage->stage >= MESA_SHADER_COMPUTE);
|
||||
subgroup_size = key->cs.compute_subgroup_size;
|
||||
ballot_bit_size = key->cs.compute_subgroup_size;
|
||||
subgroup_size = required_subgroup_size;
|
||||
ballot_bit_size = required_subgroup_size;
|
||||
}
|
||||
|
||||
nir_shader *nir;
|
||||
|
@@ -49,6 +49,17 @@ struct radv_shader_args;
|
||||
struct radv_vs_input_state;
|
||||
struct radv_shader_args;
|
||||
|
||||
enum radv_required_subgroup_size {
|
||||
RADV_REQUIRED_NONE = 0,
|
||||
RADV_REQUIRED_WAVE32 = 1,
|
||||
RADV_REQUIRED_WAVE64 = 2,
|
||||
};
|
||||
|
||||
struct radv_required_subgroup_info {
|
||||
uint8_t required_size : 2; /* radv_required_subgroup_size */
|
||||
uint8_t require_full : 1; /* whether full subgroups are required */
|
||||
};
|
||||
|
||||
struct radv_ps_epilog_key {
|
||||
uint32_t spi_shader_col_format;
|
||||
|
||||
@@ -81,6 +92,8 @@ struct radv_pipeline_key {
|
||||
uint32_t enable_remove_point_size : 1;
|
||||
uint32_t unknown_rast_prim : 1;
|
||||
|
||||
struct radv_required_subgroup_info subgroups[MESA_VULKAN_SHADER_STAGES];
|
||||
|
||||
struct {
|
||||
uint32_t instance_rate_inputs;
|
||||
uint32_t instance_rate_divisors[MAX_VERTEX_ATTRIBS];
|
||||
@@ -115,14 +128,6 @@ struct radv_pipeline_key {
|
||||
|
||||
bool line_smooth_enabled;
|
||||
} ps;
|
||||
|
||||
struct {
|
||||
/* Non-zero if a required subgroup size is specified via
|
||||
* VK_EXT_subgroup_size_control.
|
||||
*/
|
||||
uint8_t compute_subgroup_size;
|
||||
bool require_full_subgroups;
|
||||
} cs;
|
||||
};
|
||||
|
||||
struct radv_nir_compiler_options {
|
||||
|
@@ -712,12 +712,14 @@ gather_shader_info_cs(struct radv_device *device, const nir_shader *nir, const s
|
||||
/* Games don't always request full subgroups when they should, which can cause bugs if cswave32
|
||||
* is enabled.
|
||||
*/
|
||||
bool require_full_subgroups =
|
||||
pipeline_key->cs.require_full_subgroups ||
|
||||
const bool require_full_subgroups =
|
||||
pipeline_key->subgroups[MESA_SHADER_COMPUTE].require_full ||
|
||||
(default_wave_size == 32 && nir->info.uses_wide_subgroup_intrinsics && local_size % RADV_SUBGROUP_SIZE == 0);
|
||||
|
||||
if (pipeline_key->cs.compute_subgroup_size) {
|
||||
info->cs.subgroup_size = pipeline_key->cs.compute_subgroup_size;
|
||||
const unsigned required_subgroup_size = pipeline_key->subgroups[MESA_SHADER_COMPUTE].required_size * 32;
|
||||
|
||||
if (required_subgroup_size) {
|
||||
info->cs.subgroup_size = required_subgroup_size;
|
||||
} else if (require_full_subgroups) {
|
||||
info->cs.subgroup_size = RADV_SUBGROUP_SIZE;
|
||||
} else if (device->physical_device->rad_info.gfx_level >= GFX10 && local_size <= 32) {
|
||||
|
Reference in New Issue
Block a user