(count > 3) ? vtn_value(b, w[3], vtn_value_type_string)->str : "";
vtn_info("Parsing SPIR-V from %s %u source file %s", lang, version, file);
+
+ b->source_lang = w[1];
break;
}
case SpvCapabilityDemoteToHelperInvocationEXT:
spv_check_supported(demote_to_helper_invocation, cap);
+ b->uses_demote_to_helper_invocation = true;
break;
case SpvCapabilityShaderClockKHR:
goto fail;
}
- uint16_t generator_id = words[2] >> 16;
+ b->generator_id = words[2] >> 16;
uint16_t generator_version = words[2];
/* In GLSLang commit 8297936dd6eb3, their handling of barrier() was fixed
* GLSLang fix caused them to bump to generator version 3.
*/
b->wa_glslang_cs_barrier =
- (generator_id == vtn_generator_glslang_reference_front_end &&
+ (b->generator_id == vtn_generator_glslang_reference_front_end &&
generator_version < 3);
/* words[2] == generator magic */
words = vtn_foreach_instruction(b, words, word_end,
vtn_handle_preamble_instruction);
+ /* DirectXShaderCompiler and glslang/shaderc both create OpKill from HLSL's
+ * discard/clip, which uses demote semantics. DirectXShaderCompiler will use
+ * demote if the extension is enabled, so we disable this workaround in that
+ * case.
+ *
+ * Related glslang issue: https://github.com/KhronosGroup/glslang/issues/2416
+ */
+ bool glslang = b->generator_id == vtn_generator_glslang_reference_front_end ||
+ b->generator_id == vtn_generator_shaderc_over_glslang;
+ bool dxsc = b->generator_id == vtn_generator_spiregg;
+ b->convert_discard_to_demote = ((dxsc && !b->uses_demote_to_helper_invocation) ||
+ (glslang && b->source_lang == SpvSourceLanguageHLSL)) &&
+ options->caps.demote_to_helper_invocation;
+
if (!options->create_library && b->entry_point == NULL) {
vtn_fail("Entry point not found for %s shader \"%s\"",
_mesa_shader_stage_to_string(stage), entry_point_name);
nir_jump(&b->nb, nir_jump_return);
break;
case vtn_branch_type_discard: {
+ nir_intrinsic_op op =
+ b->convert_discard_to_demote ? nir_intrinsic_demote : nir_intrinsic_discard;
nir_intrinsic_instr *discard =
- nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_discard);
+ nir_intrinsic_instr_create(b->nb.shader, op);
nir_builder_instr_insert(&b->nb, &discard->instr);
break;
}
unsigned value_id_bound;
struct vtn_value *values;
+ /* Information on the origin of the SPIR-V */
+ enum vtn_generator generator_id;
+ SpvSourceLanguage source_lang;
+
/* True if we need to fix up CS OpControlBarrier */
bool wa_glslang_cs_barrier;
+ /* Workaround discard bugs in HLSL -> SPIR-V compilers */
+ bool uses_demote_to_helper_invocation;
+ bool convert_discard_to_demote;
+
gl_shader_stage entry_point_stage;
const char *entry_point_name;
struct vtn_value *entry_point;