vkImageWithMemory.hpp
vkShaderProgram.cpp
vkShaderProgram.hpp
+ vkValidatorOptions.hpp
vkYCbCrImageWithMemory.cpp
vkYCbCrImageWithMemory.hpp
vkObjUtil.cpp
#if defined(DEQP_HAVE_SPIRV_TOOLS)
-void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramInfo* buildInfo, deUint32 vulkanVersion, const SpirvVersion spirvVersion, const bool relaxedLayout)
+void validateCompiledBinary(const vector<deUint32>& binary, glu::ShaderProgramInfo* buildInfo, const SpirvValidatorOptions& options)
{
std::ostringstream validationLog;
- if (!validateSpirV(binary.size(), &binary[0], &validationLog, vulkanVersion, spirvVersion, relaxedLayout))
+ if (!validateSpirV(binary.size(), &binary[0], &validationLog, options))
{
buildInfo->program.linkOk = false;
buildInfo->program.infoLog += "\n" + validationLog.str();
if (validateBinary)
{
- const bool relaxedLayout = program.buildOptions.flags & ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS;
- validateCompiledBinary(binary, buildInfo, program.buildOptions.vulkanVersion, spirvVersion, relaxedLayout);
+ validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
}
if (optimizationRecipe != 0)
if (validateBinary)
{
- const bool relaxedLayout = program.buildOptions.flags & ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS;
- validateCompiledBinary(binary, buildInfo, program.buildOptions.vulkanVersion, spirvVersion, relaxedLayout);
+ validateCompiledBinary(binary, buildInfo, program.buildOptions.getSpirvValidatorOptions());
}
if (optimizationRecipe != 0)
if (validateBinary)
{
std::ostringstream validationLog;
- const bool relaxedLayout = false;
- if (!validateSpirV(binary.size(), &binary[0], &validationLog, program.buildOptions.vulkanVersion, spirvVersion, relaxedLayout))
+ if (!validateSpirV(binary.size(), &binary[0], &validationLog, program.buildOptions.getSpirvValidatorOptions()))
{
buildInfo->compileOk = false;
buildInfo->infoLog += "\n" + validationLog.str();
TCU_THROW(NotSupportedError, "Unsupported program format");
}
-bool validateProgram (const ProgramBinary& program, std::ostream* dst, deUint32 vulkanVersion, bool relaxedLayout)
+bool validateProgram (const ProgramBinary& program, std::ostream* dst, const SpirvValidatorOptions& options)
{
if (program.getFormat() == PROGRAM_FORMAT_SPIRV)
{
}
if (isNativeSpirVBinaryEndianness())
- return validateSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst,
- vulkanVersion, extractSpirvVersion(program), relaxedLayout);
+ return validateSpirV(program.getSize()/sizeof(deUint32), (const deUint32*)program.getBinary(), dst, options);
else
TCU_THROW(InternalError, "SPIR-V endianness translation not supported");
}
ProgramBinary* buildProgram (const HlslSource& program, glu::ShaderProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
ProgramBinary* assembleProgram (const vk::SpirVAsmSource& program, SpirVProgramInfo* buildInfo, const tcu::CommandLine& commandLine);
void disassembleProgram (const ProgramBinary& program, std::ostream* dst);
-bool validateProgram (const ProgramBinary& program, std::ostream* dst, deUint32 vulkanVersion, bool relaxedLayout);
+bool validateProgram (const ProgramBinary& program, std::ostream* dst, const SpirvValidatorOptions&);
Move<VkShaderModule> createShaderModule (const DeviceInterface& deviceInterface, VkDevice device, const ProgramBinary& binary, VkShaderModuleCreateFlags flags);
#include "vkDefs.hpp"
#include "gluShaderProgram.hpp"
+#include "vkValidatorOptions.hpp"
#include <string>
enum Flags
{
FLAG_USE_STORAGE_BUFFER_STORAGE_CLASS = (1u<<0),
- FLAG_ALLOW_RELAXED_OFFSETS = (1u<<1) // allow block offsets to follow VK_KHR_relaxed_block_layout
+ FLAG_ALLOW_RELAXED_OFFSETS = (1u<<1), // allow block offsets to follow VK_KHR_relaxed_block_layout
+ FLAG_ALLOW_SCALAR_OFFSETS = (1u<<2) // allow block offsets to follow VK_EXT_scalar_block_layout
};
deUint32 vulkanVersion;
, targetVersion (SPIRV_VERSION_1_0)
, flags (0u)
{}
+
+ SpirvValidatorOptions getSpirvValidatorOptions() const
+ {
+ SpirvValidatorOptions::BlockLayoutRules rules = SpirvValidatorOptions::kDefaultBlockLayout;
+
+ if (flags & FLAG_ALLOW_SCALAR_OFFSETS)
+ {
+ rules = SpirvValidatorOptions::kScalarBlockLayout;
+ }
+ else if (flags & FLAG_ALLOW_RELAXED_OFFSETS)
+ {
+ rules = SpirvValidatorOptions::kRelaxedBlockLayout;
+ }
+
+ return SpirvValidatorOptions(vulkanVersion, rules);
+ }
};
enum ShaderLanguage
}
}
-bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, deUint32 vulkanVersion, SpirvVersion, bool relaxedLayout)
+bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, const SpirvValidatorOptions &val_options)
{
- const spv_context context = spvContextCreate(mapVulkanVersionToSpirvToolsEnv(vulkanVersion));
+ const spv_context context = spvContextCreate(mapVulkanVersionToSpirvToolsEnv(val_options.vulkanVersion));
spv_diagnostic diagnostic = DE_NULL;
try
{
spv_const_binary_t cbinary = { binary, binarySizeInWords };
- spv_validator_options options = spvValidatorOptionsCreate();
- spvValidatorOptionsSetRelaxBlockLayout(options, relaxedLayout);
+ spv_validator_options options = spvValidatorOptionsCreate();
+
+ switch (val_options.blockLayout)
+ {
+ case SpirvValidatorOptions::kDefaultBlockLayout:
+ break;
+ case SpirvValidatorOptions::kNoneBlockLayout:
+ spvValidatorOptionsSetSkipBlockLayout(options, true);
+ break;
+ case SpirvValidatorOptions::kRelaxedBlockLayout:
+ spvValidatorOptionsSetRelaxBlockLayout(options, true);
+ break;
+ case SpirvValidatorOptions::kScalarBlockLayout:
+ spvValidatorOptionsSetScalarBlockLayout(options, true);
+ break;
+ }
const spv_result_t valid = spvValidateWithOptions(context, options, &cbinary, &diagnostic);
const bool passed = (valid == SPV_SUCCESS);
void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* dst, SpirvVersion spirvVersion);
//! Validate SPIR-V binary, returning true if validation succeeds. Will fail with NotSupportedError if compiler is not available.
-bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, deUint32 vulkanVersion, SpirvVersion spirvVersion, bool relaxedLayout);
+bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, const SpirvValidatorOptions&);
} // vk
#include "vkDefs.hpp"
#include "deStringUtil.hpp"
+#include "vkValidatorOptions.hpp"
#include <string>
: vulkanVersion (VK_MAKE_VERSION(1, 0, 0))
, targetVersion (SPIRV_VERSION_1_0)
{}
+
+ SpirvValidatorOptions getSpirvValidatorOptions() const
+ {
+ return SpirvValidatorOptions(vulkanVersion);
+ }
};
struct SpirVAsmSource
--- /dev/null
+#ifndef _VKVALIDATOROPTIONS_HPP
+#define _VKVALIDATOROPTIONS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan CTS Framework
+ * --------------------
+ *
+ * Copyright (c) 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief SPIR-V validator options
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+namespace vk
+{
+
+struct SpirvValidatorOptions
+{
+ enum BlockLayoutRules
+ {
+ // The default for the target Vulkan environment.
+ kDefaultBlockLayout,
+ // Don't check block layout
+ kNoneBlockLayout,
+ // VK_KHR_relaxed_block_layout
+ kRelaxedBlockLayout,
+ // VK_EXT_scalar_block_layout
+ kScalarBlockLayout
+ };
+
+ SpirvValidatorOptions(deUint32 the_vulkan_version = VK_MAKE_VERSION(1, 0, 0), BlockLayoutRules the_layout = kDefaultBlockLayout)
+ : vulkanVersion(the_vulkan_version), blockLayout(the_layout) {}
+
+ // The target Vulkan version. This determines the SPIR-V environment rules to
+ // be checked. The bit pattern is as produced by VK_MAKE_VERSION.
+ deUint32 vulkanVersion;
+
+ // The block layout rules to enforce.
+ BlockLayoutRules blockLayout;
+};
+
+} // namespace vk
+
+#endif // _VKVALIDATOROPTIONS_HPP
{
DE_ASSERT(!m_computeShaderSrc.empty());
- if (usesRelaxedLayout(m_interface))
+ // Valid scalar layouts are a superset of valid relaxed layouts. So check scalar layout first.
+ if (usesScalarLayout(m_interface))
+ {
+ programCollection.glslSources.add("compute") << glu::ComputeSource(m_computeShaderSrc)
+ << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS);
+ }
+ else if (usesRelaxedLayout(m_interface))
{
programCollection.glslSources.add("compute") << glu::ComputeSource(m_computeShaderSrc)
<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_0, vk::ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS);
return *m_uniformBlocks.back();
}
+bool ShaderInterface::usesBlockLayout (UniformFlags layoutFlag) const
+{
+ for (int i = 0, num_blocks = getNumUniformBlocks() ; i < num_blocks ; i++)
+ {
+ if (m_uniformBlocks[i]->getFlags() & layoutFlag)
+ return true;
+ }
+ return false;
+}
+
namespace // Utilities
{
DE_ASSERT(!m_vertShaderSource.empty());
DE_ASSERT(!m_fragShaderSource.empty());
- programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource);
- programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource);
+ vk::ShaderBuildOptions::Flags flags = vk::ShaderBuildOptions::Flags(0);
+ // TODO(dneto): If these tests ever use LAYOUT_RELAXED, then add support
+ // here as well.
+ if (usesBlockLayout(UniformFlags(LAYOUT_SCALAR | LAYOUT_STD430)))
+ {
+ flags = vk::ShaderBuildOptions::FLAG_ALLOW_SCALAR_OFFSETS;
+ }
+
+ programCollection.glslSources.add("vert") << glu::VertexSource(m_vertShaderSource)
+ << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::getBaselineSpirvVersion(programCollection.usedVulkanVersion), flags);
+
+ programCollection.glslSources.add("frag") << glu::FragmentSource(m_fragShaderSource)
+ << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::getBaselineSpirvVersion(programCollection.usedVulkanVersion), flags);
}
TestInstance* UniformBlockCase::createInstance (Context& context) const
int getNumUniformBlocks (void) const { return (int)m_uniformBlocks.size(); }
const UniformBlock& getUniformBlock (int ndx) const { return *m_uniformBlocks[ndx]; }
+ bool usesBlockLayout (UniformFlags layoutFlag) const;
private:
std::vector<StructTypeSP> m_structs;
virtual void initPrograms (vk::SourceCollections& programCollection) const;
virtual TestInstance* createInstance (Context& context) const;
+ bool usesBlockLayout (UniformFlags layoutFlag) const { return m_interface.usesBlockLayout(layoutFlag); }
protected:
void init (void);
Status validationStatus;
std::string validationLog;
- deUint32 vulkanVersion; // Target Vulkan environment.
- vk::SpirvVersion spirvVersion;
- bool relaxedLayout; // Uses VK_KHR_relaxed_block_layout?
+ vk::SpirvValidatorOptions validatorOptions;
- explicit Program (const vk::ProgramIdentifier& id_, deUint32 vulkanVersion_, const vk::SpirvVersion spirvVersion_, const bool relaxedLayout_)
+ explicit Program (const vk::ProgramIdentifier& id_, const vk::SpirvValidatorOptions& valOptions_)
: id (id_)
, buildStatus (STATUS_NOT_COMPLETED)
, validationStatus (STATUS_NOT_COMPLETED)
- , vulkanVersion (vulkanVersion_)
- , spirvVersion (spirvVersion_)
- , relaxedLayout (relaxedLayout_)
+ , validatorOptions (valOptions_)
{}
Program (void)
: id ("", "")
, buildStatus (STATUS_NOT_COMPLETED)
, validationStatus (STATUS_NOT_COMPLETED)
- , vulkanVersion (VK_MAKE_VERSION(1, 0, 0))
- , spirvVersion (vk::SPIRV_VERSION_LAST)
- , relaxedLayout (false)
+ , validatorOptions()
{}
};
DE_ASSERT(m_commandLine != DE_NULL);
m_program->binary = ProgramBinarySp(vk::buildProgram(m_source, &buildInfo, *m_commandLine));
m_program->buildStatus = Program::STATUS_PASSED;
- m_program->relaxedLayout = m_source.buildOptions.flags & vk::ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS;
+ m_program->validatorOptions = m_source.buildOptions.getSpirvValidatorOptions();
}
catch (const tcu::Exception&)
{
std::ostringstream validationLogStream;
- if (vk::validateProgram(*m_program->binary, &validationLogStream, m_program->vulkanVersion, m_program->relaxedLayout))
+ if (vk::validateProgram(*m_program->binary, &validationLogStream, m_program->validatorOptions))
m_program->validationStatus = Program::STATUS_PASSED;
else
m_program->validationStatus = Program::STATUS_FAILED;
if (progIter.getProgram().buildOptions.targetVersion > maxSpirvVersion)
continue;
- const bool relaxedLayout = progIter.getProgram().buildOptions.flags & vk::ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS;
- programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.vulkanVersion, progIter.getProgram().buildOptions.targetVersion, relaxedLayout));
+ programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.getSpirvValidatorOptions()));
buildGlslTasks.pushBack(BuildHighLevelShaderTask<vk::GlslSource>(progIter.getProgram(), &programs.back()));
buildGlslTasks.back().setCommandline(testCtx.getCommandLine());
executor.submit(&buildGlslTasks.back());
if (progIter.getProgram().buildOptions.targetVersion > maxSpirvVersion)
continue;
- const bool relaxedLayout = progIter.getProgram().buildOptions.flags & vk::ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS;
- programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.vulkanVersion, progIter.getProgram().buildOptions.targetVersion, relaxedLayout));
+ programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.getSpirvValidatorOptions()));
buildHlslTasks.pushBack(BuildHighLevelShaderTask<vk::HlslSource>(progIter.getProgram(), &programs.back()));
buildHlslTasks.back().setCommandline(testCtx.getCommandLine());
executor.submit(&buildHlslTasks.back());
if (progIter.getProgram().buildOptions.targetVersion > maxSpirvVersion)
continue;
- programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.vulkanVersion, progIter.getProgram().buildOptions.targetVersion, false));
+ programs.pushBack(Program(vk::ProgramIdentifier(casePath, progIter.getName()), progIter.getProgram().buildOptions.getSpirvValidatorOptions()));
buildSpirvAsmTasks.pushBack(BuildSpirVAsmTask(progIter.getProgram(), &programs.back()));
buildSpirvAsmTasks.back().setCommandline(testCtx.getCommandLine());
executor.submit(&buildSpirvAsmTasks.back());