No error report for variable image offset when before-legal-hlsl is on (#4316)

PR #4118 (d71ac38b8e) let spirv-val report a validation error when we
use offset for an OpImage* instruction instead of ConstantOffset. Since
some compilers like DXC rely on spirv-opt for function inlining or loop
unrolling, the spirv-val change broke some working shaders when the
shader developers disable the optimization (spirv-opt).

For example, DXC recently got this issue from a few users e.g.,
https://github.com/microsoft/DirectXShaderCompiler/issues/3807

Since this error is reported only when the spirv-opt is disabled, it
looks like the exact case that we have to skip spirv-val when
`--before-legalize-hlsl` is given. Moreover, avoiding the error using
`--before-legalize-hlsl` on DXC is exactly what FXC and DXC's DXIL
do (they do not report the error if the offset becomes a constant after
function inlining or loop unrolling).
This commit is contained in:
Jaebaek Seo 2021-06-08 09:35:27 -04:00 коммит произвёл GitHub
Родитель 87a2867976
Коммит fb02131cb4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 16 добавлений и 1 удалений

Просмотреть файл

@ -442,7 +442,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
<< " components, but given " << offset_size;
}
if (spvIsVulkanEnv(_.context()->target_env)) {
if (!_.options()->before_hlsl_legalization &&
spvIsVulkanEnv(_.context()->target_env)) {
if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather &&
opcode != SpvOpImageSparseGather &&
opcode != SpvOpImageSparseDrefGather) {

Просмотреть файл

@ -1791,6 +1791,20 @@ TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongSize) {
"OpImage*Gather operations"));
}
TEST_F(ValidateImage, SampleImplicitLodVulkanOffsetWrongBeforeLegalization) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
%sampler = OpLoad %type_sampler %uniform_sampler
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
%res4 = OpImageSampleImplicitLod %f32vec4 %simg %f32vec4_0000 Offset %s32vec2_01
)";
CompileSuccessfully(
GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
getValidatorOptions()->before_hlsl_legalization = true;
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
TEST_F(ValidateImage, SampleImplicitLodMoreThanOneOffset) {
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001