microsoft/compiler: Take inputs from callers before providing nir options

The base nir options were assuming all bit sizes were supported at
shader model 6.2. Multiple callers were then changing properties
based on actual support.

Standardize behavior by providing the majority of things that can
impact nir options when getting them. Some callers (e.g. meta blit
shaders or libclc) don't bother, because they are known to have
contents that are unaffected by these options. Other callers might
munge more properties afterwards, but this minimizes that.

Note that lower_helper_invocation was incorrectly being turned off
for SM6.6+ by some callers, despite load_helper_invocation being
unimplemented by the backend.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22952>
This commit is contained in:
Jesse Natalie 2023-05-10 13:48:01 -07:00 committed by Marge Bot
parent f2945409b3
commit 217bbdc4fd
8 changed files with 73 additions and 42 deletions

View file

@ -1617,20 +1617,15 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
}
#endif
screen->nir_options = *dxil_get_nir_compiler_options();
static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull << 16;
if ((screen->vendor_id == HW_VENDOR_MICROSOFT &&
screen->driver_version < known_good_warp_version) ||
!screen->opts1.Int64ShaderOps) {
/* Work around old versions of WARP that are completely broken for 64bit shifts */
screen->nir_options.lower_pack_64_2x32_split = false;
screen->nir_options.lower_unpack_64_2x32_split = false;
screen->nir_options.lower_int64_options = (nir_lower_int64_options)~0;
}
if (!screen->opts.DoublePrecisionFloatShaderOps)
screen->nir_options.lower_doubles_options = (nir_lower_doubles_options)~0;
bool warp_with_broken_int64 =
(screen->vendor_id == HW_VENDOR_MICROSOFT && screen->driver_version < known_good_warp_version);
unsigned supported_int_sizes = 32 | (screen->opts1.Int64ShaderOps && !warp_with_broken_int64 ? 64 : 0);
unsigned supported_float_sizes = 32 | (screen->opts.DoublePrecisionFloatShaderOps ? 64 : 0);
dxil_get_nir_compiler_options(&screen->nir_options,
screen->max_shader_model,
supported_int_sizes,
supported_float_sizes);
const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
struct mesa_sha1 sha1_ctx;

View file

@ -594,7 +594,7 @@ clc_libclc_new_dxil(const struct clc_logger *logger,
{
struct clc_libclc_options clc_options = {
.optimize = options->optimize,
.nir_options = dxil_get_nir_compiler_options(),
.nir_options = dxil_get_base_nir_compiler_options(),
};
return clc_libclc_new(logger, &clc_options);
@ -645,17 +645,17 @@ clc_spirv_to_dxil(struct clc_libclc *lib,
.printf = true,
},
};
nir_shader_compiler_options nir_options =
*dxil_get_nir_compiler_options();
if (conf && conf->lower_bit_size & 64) {
nir_options.lower_pack_64_2x32_split = false;
nir_options.lower_unpack_64_2x32_split = false;
nir_options.lower_int64_options = ~0;
unsigned supported_int_sizes = (16 | 32 | 64);
unsigned supported_float_sizes = (16 | 32);
if (conf) {
supported_int_sizes &= ~conf->lower_bit_size;
supported_float_sizes &= ~conf->lower_bit_size;
}
if (conf && conf->lower_bit_size & 16)
nir_options.support_16bit_alu = true;
nir_shader_compiler_options nir_options;
dxil_get_nir_compiler_options(&nir_options,
conf ? conf->max_shader_model : SHADER_MODEL_6_2,
supported_int_sizes,
supported_float_sizes);
glsl_type_singleton_init_or_ref();

View file

@ -154,14 +154,33 @@ nir_options = {
.max_unroll_iterations = 32, /* arbitrary */
.force_indirect_unrolling = (nir_var_shader_in | nir_var_shader_out | nir_var_function_temp),
.lower_device_index_to_zero = true,
.linker_ignore_precision = true,
};
const nir_shader_compiler_options*
dxil_get_nir_compiler_options(void)
dxil_get_base_nir_compiler_options(void)
{
return &nir_options;
}
void
dxil_get_nir_compiler_options(nir_shader_compiler_options *options,
enum dxil_shader_model shader_model_max,
unsigned supported_int_sizes,
unsigned supported_float_sizes)
{
*options = nir_options;
if (!(supported_int_sizes & 64)) {
options->lower_pack_64_2x32_split = false;
options->lower_unpack_64_2x32_split = false;
options->lower_int64_options = ~0;
}
if (!(supported_float_sizes & 64))
options->lower_doubles_options = ~0;
if ((supported_int_sizes & 16) && (supported_float_sizes & 16))
options->support_16bit_alu = true;
}
static bool
emit_llvm_ident(struct dxil_module *m)
{

View file

@ -101,7 +101,13 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts,
const struct dxil_logger *logger, struct blob *blob);
const nir_shader_compiler_options*
dxil_get_nir_compiler_options(void);
dxil_get_base_nir_compiler_options(void);
void
dxil_get_nir_compiler_options(nir_shader_compiler_options *options,
enum dxil_shader_model shader_model_max,
unsigned supported_int_sizes,
unsigned supported_float_sizes);
#ifdef __cplusplus
}

View file

@ -176,11 +176,6 @@ main(int argc, char **argv)
};
gl_shader_stage shader_stage = MESA_SHADER_FRAGMENT;
nir_options = *dxil_get_nir_compiler_options();
// We will manually handle base_vertex when vertex_id and instance_id have
// have been already converted to zero-base.
nir_options.lower_base_vertex = false;
struct dxil_spirv_runtime_conf conf;
memset(&conf, 0, sizeof(conf));
conf.runtime_data_cbv.base_shader_register = 0;
@ -215,7 +210,6 @@ main(int argc, char **argv)
break;
case 'm':
conf.shader_model_max = SHADER_MODEL_6_0 + atoi(optarg);
nir_options.lower_helper_invocation = conf.shader_model_max < SHADER_MODEL_6_6;
break;
case 'x':
val_ver = DXIL_VALIDATOR_1_0 + atoi(optarg);
@ -232,6 +226,12 @@ main(int argc, char **argv)
}
}
const unsigned supported_bit_sizes = 16 | 32 | 64;
dxil_get_nir_compiler_options(&nir_options, conf.shader_model_max, supported_bit_sizes, supported_bit_sizes);
// We will manually handle base_vertex when vertex_id and instance_id have
// have been already converted to zero-base.
nir_options.lower_base_vertex = false;
if (!any_shaders) {
fprintf(stderr, "Specify a shader filename\n");
return 1;

View file

@ -64,11 +64,12 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
};
const struct spirv_to_nir_options *spirv_opts = dxil_spirv_nir_get_spirv_options();
struct nir_shader_compiler_options nir_options = *dxil_get_nir_compiler_options();
nir_shader_compiler_options nir_options;
const unsigned supported_bit_sizes = 16 | 32 | 64;
dxil_get_nir_compiler_options(&nir_options, conf->shader_model_max, supported_bit_sizes, supported_bit_sizes);
// We will manually handle base_vertex when vertex_id and instance_id have
// have been already converted to zero-base.
nir_options.lower_base_vertex = !conf->zero_based_vertex_instance_id;
nir_options.lower_helper_invocation = opts.shader_model_max < SHADER_MODEL_6_6;
nir_shader *nir = spirv_to_nir(
words, word_count, (struct nir_spirv_specialization *)specializations,

View file

@ -122,7 +122,7 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
nir_builder b =
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"dzn_meta_indirect_%s()",
type_str[type]);
b.shader->info.internal = true;
@ -312,7 +312,7 @@ dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size)
nir_builder b =
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"dzn_meta_triangle_prim_rewrite_index(old_index_size=%d)",
old_index_size);
b.shader->info.internal = true;
@ -475,7 +475,7 @@ dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size)
nir_builder b =
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"dzn_meta_triangle_rewrite_index(old_index_size=%d)",
old_index_size);
b.shader->info.internal = true;
@ -563,7 +563,7 @@ dzn_nir_blit_vs(void)
{
nir_builder b =
nir_builder_init_simple_shader(MESA_SHADER_VERTEX,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"dzn_meta_blit_vs()");
b.shader->info.internal = true;
@ -622,7 +622,7 @@ dzn_nir_blit_fs(const struct dzn_nir_blit_info *info)
nir_builder b =
nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"dzn_meta_blit_fs()");
b.shader->info.internal = true;
@ -851,7 +851,7 @@ dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, struct dzn_nir_
builder = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
dxil_get_nir_compiler_options(),
dxil_get_base_nir_compiler_options(),
"implicit_gs");
nir_shader *nir = b->shader;

View file

@ -404,6 +404,7 @@ dzn_pipeline_compile_shader(struct dzn_device *device,
container_of(device->vk.physical, struct dzn_physical_device, vk);
struct nir_to_dxil_options opts = {
.environment = DXIL_ENVIRONMENT_VULKAN,
.lower_int16 = !pdev->options4.Native16BitShaderOpsSupported,
.shader_model_max = dzn_get_shader_model(pdev),
.input_clip_size = input_clip_size,
#ifdef _WIN32
@ -730,6 +731,8 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device,
enum pipe_format *vi_conversions,
const VkGraphicsPipelineCreateInfo *info)
{
struct dzn_physical_device *pdev =
container_of(device->vk.physical, struct dzn_physical_device, vk);
const VkPipelineViewportStateCreateInfo *vp_info =
info->pRasterizationState->rasterizerDiscardEnable ?
NULL : info->pViewportState;
@ -854,7 +857,9 @@ dzn_graphics_pipeline_compile_shaders(struct dzn_device *device,
}
/* Second step: get NIR shaders for all stages. */
nir_shader_compiler_options nir_opts = *dxil_get_nir_compiler_options();
nir_shader_compiler_options nir_opts;
unsigned supported_bit_sizes = (pdev->options4.Native16BitShaderOpsSupported ? 16 : 0) | 32 | 64;
dxil_get_nir_compiler_options(&nir_opts, dzn_get_shader_model(pdev), supported_bit_sizes, supported_bit_sizes);
nir_opts.lower_base_vertex = true;
u_foreach_bit(stage, active_stage_mask) {
struct mesa_sha1 nir_hash_ctx;
@ -2414,6 +2419,8 @@ dzn_compute_pipeline_compile_shader(struct dzn_device *device,
D3D12_SHADER_BYTECODE *shader,
const VkComputePipelineCreateInfo *info)
{
struct dzn_physical_device *pdev =
container_of(device->vk.physical, struct dzn_physical_device, vk);
uint8_t spirv_hash[SHA1_DIGEST_LENGTH], pipeline_hash[SHA1_DIGEST_LENGTH], nir_hash[SHA1_DIGEST_LENGTH];
VkResult ret = VK_SUCCESS;
nir_shader *nir = NULL;
@ -2452,8 +2459,11 @@ dzn_compute_pipeline_compile_shader(struct dzn_device *device,
_mesa_sha1_update(&nir_hash_ctx, spirv_hash, sizeof(spirv_hash));
_mesa_sha1_final(&nir_hash_ctx, nir_hash);
}
nir_shader_compiler_options nir_opts;
const unsigned supported_bit_sizes = 16 | 32 | 64;
dxil_get_nir_compiler_options(&nir_opts, dzn_get_shader_model(pdev), supported_bit_sizes, supported_bit_sizes);
struct dzn_nir_options options = {
.nir_opts = dxil_get_nir_compiler_options(),
.nir_opts = &nir_opts,
.subgroup_size = subgroup_enum,
};
ret = dzn_pipeline_get_nir_shader(device, layout, cache, nir_hash,