Run validation before optimization.
authorSteven Perron <stevenperron@google.com>
Tue, 11 Dec 2018 15:59:56 +0000 (10:59 -0500)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Tue, 8 Jan 2019 15:03:41 +0000 (10:03 -0500)
The optimizer runs is own pass of the validator as a safety check.
However, that call to the validator does not get the any validatoin options passed in.
This causes problems with the memory layout tests.

The solution we will be to diable the call to the validator in the
optimizer.  Instead the will be an explict call to validate the binary
before optimization starts, reusing functions that already exist to do
that.

At the same time, the run of the validator that is done with
--deqp-validation=enable will be moved so that it runs after
optimization.  This way it will validate the output instead of the
input, and it will not be a redundant check.

VK-GL-CTS issue: 1503

Components: Vulkan, Framework

Affects: dEQP-VK.ssbo.layout.random.relaxed.*

Change-Id: Ib52fa97505855316739e07e472d23fcab4ac2beb

external/vulkancts/framework/vulkan/vkPrograms.cpp

index e07d690..6366166 100644 (file)
@@ -285,7 +285,9 @@ void optimizeCompiledBinary (vector<deUint32>& binary, int optimizationRecipe, c
                        TCU_THROW(InternalError, "Unknown optimization recipe requested");
        }
 
-       const bool ok = optimizer.Run(binary.data(), binary.size(), &binary);
+       spvtools::OptimizerOptions optimizer_options;
+       optimizer_options.set_run_validator(false);
+       const bool ok = optimizer.Run(binary.data(), binary.size(), &binary, optimizer_options);
 
        if (!ok)
                TCU_THROW(InternalError, "Optimizer call failed");
@@ -351,6 +353,19 @@ void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramIn
        }
 }
 
+void validateCompiledBinary(const vector<deUint32>& binary, SpirVProgramInfo* buildInfo, const SpirvValidatorOptions& options)
+{
+       std::ostringstream validationLog;
+
+       if (!validateSpirV(binary.size(), &binary[0], &validationLog, options))
+       {
+               buildInfo->compileOk = false;
+               buildInfo->infoLog += "\n" + validationLog.str();
+
+               TCU_THROW(InternalError, "Validation failed for compiled SPIR-V binary");
+       }
+}
+
 de::Mutex                                                      cacheFileMutex;
 map<deUint32, vector<deUint32> >       cacheFileIndex;
 bool                                                           cacheFileFirstRun = true;
@@ -601,13 +616,16 @@ ProgramBinary* buildProgram (const GlslSource& program, glu::ShaderProgramInfo*
                        TCU_CHECK_INTERNAL(!binary.empty());
                }
 
-               if (validateBinary)
+               if (optimizationRecipe != 0)
                {
                        validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
                }
 
-               if (optimizationRecipe != 0)
-                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
+               if (validateBinary)
+               {
+                       validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+               }
 
                res = createProgramBinaryFromSpirV(binary);
                if (commandLine.isShadercacheEnabled())
@@ -683,13 +701,16 @@ ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo*
                        TCU_CHECK_INTERNAL(!binary.empty());
                }
 
-               if (validateBinary)
+               if (optimizationRecipe != 0)
                {
                        validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
                }
 
-               if (optimizationRecipe != 0)
-                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
+               if (validateBinary)
+               {
+                       validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+               }
 
                res = createProgramBinaryFromSpirV(binary);
                if (commandLine.isShadercacheEnabled())
@@ -740,21 +761,16 @@ ProgramBinary* assembleProgram (const SpirVAsmSource& program, SpirVProgramInfo*
                if (!assembleSpirV(&program, &binary, buildInfo, spirvVersion))
                        TCU_THROW(InternalError, "Failed to assemble SPIR-V");
 
-               if (validateBinary)
+               if (optimizationRecipe != 0)
                {
-                       std::ostringstream      validationLog;
-
-                       if (!validateSpirV(binary.size(), &binary[0], &validationLog, program.buildOptions.getSpirvValidatorOptions()))
-                       {
-                               buildInfo->compileOk = false;
-                               buildInfo->infoLog += "\n" + validationLog.str();
-
-                               TCU_THROW(InternalError, "Validation failed for assembled SPIR-V binary");
-                       }
+                       validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
                }
 
-               if (optimizationRecipe != 0)
-                       optimizeCompiledBinary(binary, optimizationRecipe, spirvVersion);
+               if (validateBinary)
+               {
+                       validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
+               }
 
                res = createProgramBinaryFromSpirV(binary);
                if (commandLine.isShadercacheEnabled())