Commit e5385ea9 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Compile shaders at link time

Since line raster emulation was changed to use specialization constants, it has been possible to compile shaders at link time. However, program pipeline objects would have required keeping the shader sources around for recompilation. Now that all necessary decorations are modified directly in SPIR-V, it's possible to compile the shaders at link time and forget about their sources. Program pipeline objects then simply "reconfigure" the generated SPIR-V. A next step could be to also create the Vulkan pipeline object at link time. A number of failures due to gaps in CTS testing prevent that work currently. In particular, in some situations the generated SPIR-V is not per spec, for example it may contain vertex attributes with aliasing locations, or have transform feedback capture of array elements misconfigured. Bug: angleproject:3394 Bug: angleproject:4253 Change-Id: I54c0884cf056b511a4a306225cc6ed2cef84d257 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2023186 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent f1b2c4be
...@@ -186,8 +186,10 @@ class BinaryOutputStream : angle::NonCopyable ...@@ -186,8 +186,10 @@ class BinaryOutputStream : angle::NonCopyable
template <class IntT> template <class IntT>
void writeInt(IntT param) void writeInt(IntT param)
{ {
ASSERT(angle::IsValueInRangeForNumericType<int>(param)); using PromotedIntT =
int intValue = static_cast<int>(param); typename std::conditional<std::is_signed<IntT>::value, int, unsigned>::type;
ASSERT(angle::IsValueInRangeForNumericType<PromotedIntT>(param));
PromotedIntT intValue = static_cast<PromotedIntT>(param);
write(&intValue, 1); write(&intValue, 1);
} }
......
...@@ -1610,7 +1610,7 @@ angle::Result Program::link(const Context *context) ...@@ -1610,7 +1610,7 @@ angle::Result Program::link(const Context *context)
} }
if (!resources->varyingPacking.collectAndPackUserVaryings( if (!resources->varyingPacking.collectAndPackUserVaryings(
mInfoLog, mergedVaryings, mState.getTransformFeedbackVaryingNames())) mInfoLog, mergedVaryings, mState.getTransformFeedbackVaryingNames(), isSeparable()))
{ {
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -433,7 +433,8 @@ void VaryingPacking::packUserVaryingFieldTF(const ProgramVaryingRef &ref, ...@@ -433,7 +433,8 @@ void VaryingPacking::packUserVaryingFieldTF(const ProgramVaryingRef &ref,
bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
const ProgramMergedVaryings &mergedVaryings, const ProgramMergedVaryings &mergedVaryings,
const std::vector<std::string> &tfVaryings) const std::vector<std::string> &tfVaryings,
const bool isSeparableProgram)
{ {
VaryingUniqueFullNames uniqueFullNames; VaryingUniqueFullNames uniqueFullNames;
mPackedVaryings.clear(); mPackedVaryings.clear();
...@@ -450,7 +451,8 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, ...@@ -450,7 +451,8 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
// optimizations" may be used to make vertex shader outputs fit. // optimizations" may be used to make vertex shader outputs fit.
if ((input && output && output->staticUse) || if ((input && output && output->staticUse) ||
(input && input->isBuiltIn() && input->active) || (input && input->isBuiltIn() && input->active) ||
(output && output->isBuiltIn() && output->active)) (output && output->isBuiltIn() && output->active) ||
(isSeparableProgram && ((input && input->active) || (output && output->active))))
{ {
const sh::ShaderVariable *varying = output ? output : input; const sh::ShaderVariable *varying = output ? output : input;
...@@ -485,7 +487,7 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, ...@@ -485,7 +487,7 @@ bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
} }
// If the varying is not used in the input, we know it is inactive. // If the varying is not used in the input, we know it is inactive.
if (!input) if (!input && !isSeparableProgram)
{ {
mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName); mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName);
continue; continue;
......
...@@ -72,7 +72,11 @@ struct PackedVarying : angle::NonCopyable ...@@ -72,7 +72,11 @@ struct PackedVarying : angle::NonCopyable
PackedVarying &operator=(PackedVarying &&other); PackedVarying &operator=(PackedVarying &&other);
bool isStructField() const { return !frontVarying.parentStructName.empty(); } bool isStructField() const
{
return frontVarying.varying ? !frontVarying.parentStructName.empty()
: !backVarying.parentStructName.empty();
}
bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; } bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; }
...@@ -190,7 +194,8 @@ class VaryingPacking final : angle::NonCopyable ...@@ -190,7 +194,8 @@ class VaryingPacking final : angle::NonCopyable
bool collectAndPackUserVaryings(gl::InfoLog &infoLog, bool collectAndPackUserVaryings(gl::InfoLog &infoLog,
const ProgramMergedVaryings &mergedVaryings, const ProgramMergedVaryings &mergedVaryings,
const std::vector<std::string> &tfVaryings); const std::vector<std::string> &tfVaryings,
const bool isSeparableProgram);
struct Register struct Register
{ {
......
...@@ -964,8 +964,7 @@ bool ValidateSpirv(const std::vector<uint32_t> &spirvBlob) ...@@ -964,8 +964,7 @@ bool ValidateSpirv(const std::vector<uint32_t> &spirvBlob)
if (!result) if (!result)
{ {
std::string readableSpirv; std::string readableSpirv;
result = spirvTools.Disassemble(spirvBlob, &readableSpirv, spirvTools.Disassemble(spirvBlob, &readableSpirv, SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
WARN() << "Invalid SPIR-V:\n" << readableSpirv; WARN() << "Invalid SPIR-V:\n" << readableSpirv;
} }
......
...@@ -132,7 +132,9 @@ class ProgramMtl : public ProgramImpl ...@@ -132,7 +132,9 @@ class ProgramMtl : public ProgramImpl
void reset(ContextMtl *context); void reset(ContextMtl *context);
void linkResources(const gl::ProgramLinkedResources &resources); void linkResources(const gl::ProgramLinkedResources &resources);
angle::Result linkImpl(const gl::Context *glContext, gl::InfoLog &infoLog); angle::Result linkImpl(const gl::Context *glContext,
const gl::ProgramLinkedResources &resources,
gl::InfoLog &infoLog);
angle::Result convertToMsl(const gl::Context *glContext, angle::Result convertToMsl(const gl::Context *glContext,
gl::ShaderType shaderType, gl::ShaderType shaderType,
gl::InfoLog &infoLog, gl::InfoLog &infoLog,
...@@ -161,10 +163,6 @@ class ProgramMtl : public ProgramImpl ...@@ -161,10 +163,6 @@ class ProgramMtl : public ProgramImpl
gl::ShaderBitSet mSamplerBindingsDirty; gl::ShaderBitSet mSamplerBindingsDirty;
gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks; gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
// We keep the translated linked shader sources to use with shader draw call patching.
gl::ShaderMap<std::string> mShaderSource;
ShaderInterfaceVariableInfoMap mVariableInfoMap;
mtl::RenderPipelineCache mMetalRenderPipelineCache; mtl::RenderPipelineCache mMetalRenderPipelineCache;
}; };
......
...@@ -295,13 +295,13 @@ std::unique_ptr<LinkEvent> ProgramMtl::link(const gl::Context *context, ...@@ -295,13 +295,13 @@ std::unique_ptr<LinkEvent> ProgramMtl::link(const gl::Context *context,
// assignment done in that function. // assignment done in that function.
linkResources(resources); linkResources(resources);
mtl::GlslangGetShaderSource(mState, resources, &mShaderSource, &mVariableInfoMap);
// NOTE(hqle): Parallelize linking. // NOTE(hqle): Parallelize linking.
return std::make_unique<LinkEventDone>(linkImpl(context, infoLog)); return std::make_unique<LinkEventDone>(linkImpl(context, resources, infoLog));
} }
angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, gl::InfoLog &infoLog) angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
const gl::ProgramLinkedResources &resources,
gl::InfoLog &infoLog)
{ {
ContextMtl *contextMtl = mtl::GetImpl(glContext); ContextMtl *contextMtl = mtl::GetImpl(glContext);
// NOTE(hqle): No transform feedbacks for now, since we only support ES 2.0 atm // NOTE(hqle): No transform feedbacks for now, since we only support ES 2.0 atm
...@@ -310,10 +310,15 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, gl::InfoLog &in ...@@ -310,10 +310,15 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, gl::InfoLog &in
ANGLE_TRY(initDefaultUniformBlocks(glContext)); ANGLE_TRY(initDefaultUniformBlocks(glContext));
// Gather variable info and transform sources.
gl::ShaderMap<std::string> shaderSources;
ShaderInterfaceVariableInfoMap variableInfoMap;
mtl::GlslangGetShaderSource(mState, resources, &shaderSources, &variableInfoMap);
// Convert GLSL to spirv code // Convert GLSL to spirv code
gl::ShaderMap<std::vector<uint32_t>> shaderCodes; gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
ANGLE_TRY(mtl::GlslangGetShaderSpirvCode(contextMtl, contextMtl->getCaps(), mShaderSource, ANGLE_TRY(mtl::GlslangGetShaderSpirvCode(contextMtl, contextMtl->getCaps(), shaderSources,
mVariableInfoMap, &shaderCodes)); variableInfoMap, &shaderCodes));
// Convert spirv code to MSL // Convert spirv code to MSL
ANGLE_TRY(convertToMsl(glContext, gl::ShaderType::Vertex, infoLog, ANGLE_TRY(convertToMsl(glContext, gl::ShaderType::Vertex, infoLog,
......
...@@ -367,13 +367,12 @@ ProgramVk::ShaderInfo::~ShaderInfo() = default; ...@@ -367,13 +367,12 @@ ProgramVk::ShaderInfo::~ShaderInfo() = default;
angle::Result ProgramVk::ShaderInfo::initShaders( angle::Result ProgramVk::ShaderInfo::initShaders(
ContextVk *contextVk, ContextVk *contextVk,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap)
gl::ShaderMap<SpirvBlob> *spirvBlobsOut)
{ {
ASSERT(!valid()); ASSERT(!valid());
ANGLE_TRY(GlslangWrapperVk::GetShaderCode(contextVk, contextVk->getCaps(), shaderSources, ANGLE_TRY(GlslangWrapperVk::GetShaderCode(contextVk, contextVk->getCaps(), shaderSources,
variableInfoMap, spirvBlobsOut)); variableInfoMap, &mSpirvBlobs));
mIsInitialized = true; mIsInitialized = true;
return angle::Result::Continue; return angle::Result::Continue;
...@@ -388,6 +387,34 @@ void ProgramVk::ShaderInfo::release(ContextVk *contextVk) ...@@ -388,6 +387,34 @@ void ProgramVk::ShaderInfo::release(ContextVk *contextVk)
mIsInitialized = false; mIsInitialized = false;
} }
void ProgramVk::ShaderInfo::load(gl::BinaryInputStream *stream)
{
// Read in shader codes for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{
SpirvBlob *spirvBlob = &mSpirvBlobs[shaderType];
// Read the SPIR-V
stream->readIntVector<uint32_t>(spirvBlob);
}
mIsInitialized = true;
}
void ProgramVk::ShaderInfo::save(gl::BinaryOutputStream *stream)
{
ASSERT(valid());
// Write out shader codes for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{
const SpirvBlob &spirvBlob = mSpirvBlobs[shaderType];
// Write the SPIR-V
stream->writeIntVector(spirvBlob);
}
}
// ProgramVk::ProgramInfo implementation. // ProgramVk::ProgramInfo implementation.
ProgramVk::ProgramInfo::ProgramInfo() {} ProgramVk::ProgramInfo::ProgramInfo() {}
...@@ -432,78 +459,6 @@ void ProgramVk::ProgramInfo::release(ContextVk *contextVk) ...@@ -432,78 +459,6 @@ void ProgramVk::ProgramInfo::release(ContextVk *contextVk)
} }
} }
angle::Result ProgramVk::loadSpirvBlob(ContextVk *contextVk, gl::BinaryInputStream *stream)
{
// Read in shader codes for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{
// Read the shader source
mShaderSources[shaderType] = stream->readString();
SpirvBlob *spirvBlob = &mShaderInfo.getSpirvBlobs()[shaderType];
// Read the SPIR-V
stream->readIntVector<uint32_t>(spirvBlob);
}
// Read the expected bindings
size_t infoCount = stream->readInt<size_t>();
for (size_t i = 0; i < infoCount; ++i)
{
std::string varName = stream->readString();
ShaderInterfaceVariableInfo info;
info.descriptorSet = stream->readInt<uint32_t>();
info.binding = stream->readInt<uint32_t>();
info.activeStages = gl::ShaderBitSet(static_cast<uint8_t>(stream->readInt<uint32_t>()));
info.xfbBuffer = stream->readInt<uint32_t>();
info.xfbOffset = stream->readInt<uint32_t>();
info.xfbStride = stream->readInt<uint32_t>();
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
info.location[shaderType] = stream->readInt<uint32_t>();
info.component[shaderType] = stream->readInt<uint32_t>();
}
mVariableInfoMap[varName] = info;
}
return angle::Result::Continue;
}
void ProgramVk::saveSpirvBlob(gl::BinaryOutputStream *stream)
{
// Write out shader codes for all shader types
for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{
// Write the shader source
stream->writeString(mShaderSources[shaderType]);
const SpirvBlob &spirvBlob = mShaderInfo.getSpirvBlobs()[shaderType];
// Write the SPIR-V
stream->writeIntVector(spirvBlob);
}
// Write the expected bindings
stream->writeInt(mVariableInfoMap.size());
for (const auto &nameInfo : mVariableInfoMap)
{
stream->writeString(nameInfo.first);
stream->writeIntOrNegOne(nameInfo.second.descriptorSet);
stream->writeIntOrNegOne(nameInfo.second.binding);
stream->writeIntOrNegOne(nameInfo.second.activeStages.bits());
stream->writeIntOrNegOne(nameInfo.second.xfbBuffer);
stream->writeIntOrNegOne(nameInfo.second.xfbOffset);
stream->writeIntOrNegOne(nameInfo.second.xfbStride);
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{
stream->writeIntOrNegOne(nameInfo.second.location[shaderType]);
stream->writeIntOrNegOne(nameInfo.second.component[shaderType]);
}
}
}
// ProgramVk implementation. // ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() {} ProgramVk::DefaultUniformBlock::DefaultUniformBlock() {}
...@@ -571,11 +526,9 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context, ...@@ -571,11 +526,9 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context,
gl::ShaderMap<size_t> requiredBufferSize; gl::ShaderMap<size_t> requiredBufferSize;
requiredBufferSize.fill(0); requiredBufferSize.fill(0);
angle::Result status = loadSpirvBlob(contextVk, stream); reset(contextVk);
if (status != angle::Result::Continue)
{ mShaderInfo.load(stream);
return std::make_unique<LinkEventDone>(status);
}
// Deserializes the uniformLayout data of mDefaultUniformBlocks // Deserializes the uniformLayout data of mDefaultUniformBlocks
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
...@@ -595,10 +548,8 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context, ...@@ -595,10 +548,8 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context,
requiredBufferSize[shaderType] = stream->readInt<size_t>(); requiredBufferSize[shaderType] = stream->readInt<size_t>();
} }
reset(contextVk);
// Initialize and resize the mDefaultUniformBlocks' memory // Initialize and resize the mDefaultUniformBlocks' memory
status = resizeUniformBlockMemory(contextVk, requiredBufferSize); angle::Result status = resizeUniformBlockMemory(contextVk, requiredBufferSize);
if (status != angle::Result::Continue) if (status != angle::Result::Continue)
{ {
return std::make_unique<LinkEventDone>(status); return std::make_unique<LinkEventDone>(status);
...@@ -609,9 +560,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context, ...@@ -609,9 +560,7 @@ std::unique_ptr<rx::LinkEvent> ProgramVk::load(const gl::Context *context,
void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream) void ProgramVk::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{ {
// (geofflang): Look into saving shader modules in ShaderInfo objects (keep in mind that we mShaderInfo.save(stream);
// compile shaders lazily)
saveSpirvBlob(stream);
// Serializes the uniformLayout data of mDefaultUniformBlocks // Serializes the uniformLayout data of mDefaultUniformBlocks
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
...@@ -652,12 +601,22 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, ...@@ -652,12 +601,22 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
// assignment done in that function. // assignment done in that function.
linkResources(resources); linkResources(resources);
reset(contextVk);
// Gather variable info and transform sources.
gl::ShaderMap<std::string> shaderSources;
ShaderInterfaceVariableInfoMap variableInfoMap;
GlslangWrapperVk::GetShaderSource(contextVk->getRenderer()->getFeatures(), mState, resources, GlslangWrapperVk::GetShaderSource(contextVk->getRenderer()->getFeatures(), mState, resources,
&mShaderSources, &mVariableInfoMap); &shaderSources, &variableInfoMap);
reset(contextVk); // Compile the shaders.
angle::Result status = mShaderInfo.initShaders(contextVk, shaderSources, variableInfoMap);
if (status != angle::Result::Continue)
{
return std::make_unique<LinkEventDone>(status);
}
angle::Result status = initDefaultUniformBlocks(context); status = initDefaultUniformBlocks(context);
if (status != angle::Result::Continue) if (status != angle::Result::Continue)
{ {
return std::make_unique<LinkEventDone>(status); return std::make_unique<LinkEventDone>(status);
......
...@@ -219,13 +219,6 @@ class ProgramVk : public ProgramImpl ...@@ -219,13 +219,6 @@ class ProgramVk : public ProgramImpl
ProgramInfo *programInfo, ProgramInfo *programInfo,
vk::ShaderProgramHelper **shaderProgramOut) vk::ShaderProgramHelper **shaderProgramOut)
{ {
// Compile shaders if not already. This is done only once regardless of specialization
// constants.
if (!mShaderInfo.valid())
{
ANGLE_TRY(mShaderInfo.initShaders(contextVk, mShaderSources, mVariableInfoMap,
&mShaderInfo.getSpirvBlobs()));
}
ASSERT(mShaderInfo.valid()); ASSERT(mShaderInfo.valid());
// Create the program pipeline. This is done lazily and once per combination of // Create the program pipeline. This is done lazily and once per combination of
...@@ -258,10 +251,6 @@ class ProgramVk : public ProgramImpl ...@@ -258,10 +251,6 @@ class ProgramVk : public ProgramImpl
return initProgram(contextVk, false, &mDefaultProgramInfo, shaderProgramOut); return initProgram(contextVk, false, &mDefaultProgramInfo, shaderProgramOut);
} }
// Save and load implementation for GLES Program Binary support.
angle::Result loadSpirvBlob(ContextVk *contextVk, gl::BinaryInputStream *stream);
void saveSpirvBlob(gl::BinaryOutputStream *stream);
// State for the default uniform blocks. // State for the default uniform blocks.
struct DefaultUniformBlock final : private angle::NonCopyable struct DefaultUniformBlock final : private angle::NonCopyable
{ {
...@@ -314,15 +303,17 @@ class ProgramVk : public ProgramImpl ...@@ -314,15 +303,17 @@ class ProgramVk : public ProgramImpl
angle::Result initShaders(ContextVk *contextVk, angle::Result initShaders(ContextVk *contextVk,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap);
gl::ShaderMap<SpirvBlob> *spirvBlobsOut);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
ANGLE_INLINE bool valid() const { return mIsInitialized; } ANGLE_INLINE bool valid() const { return mIsInitialized; }
gl::ShaderMap<SpirvBlob> &getSpirvBlobs() { return mSpirvBlobs; }
const gl::ShaderMap<SpirvBlob> &getSpirvBlobs() const { return mSpirvBlobs; } const gl::ShaderMap<SpirvBlob> &getSpirvBlobs() const { return mSpirvBlobs; }
// Save and load implementation for GLES Program Binary support.
void load(gl::BinaryInputStream *stream);
void save(gl::BinaryOutputStream *stream);
private: private:
gl::ShaderMap<SpirvBlob> mSpirvBlobs; gl::ShaderMap<SpirvBlob> mSpirvBlobs;
bool mIsInitialized = false; bool mIsInitialized = false;
...@@ -351,12 +342,6 @@ class ProgramVk : public ProgramImpl ...@@ -351,12 +342,6 @@ class ProgramVk : public ProgramImpl
ProgramInfo mDefaultProgramInfo; ProgramInfo mDefaultProgramInfo;
ProgramInfo mLineRasterProgramInfo; ProgramInfo mLineRasterProgramInfo;
// We keep the translated linked shader sources and the expected location/set/binding mapping to
// use with shader draw call compilation.
// TODO(syoussefi): Remove when shader compilation is done at link time.
// http://anglebug.com/3394
gl::ShaderMap<std::string> mShaderSources;
ShaderInterfaceVariableInfoMap mVariableInfoMap;
// We keep the SPIR-V code to use for draw call pipeline creation. // We keep the SPIR-V code to use for draw call pipeline creation.
ShaderInfo mShaderInfo; ShaderInfo mShaderInfo;
......
...@@ -534,11 +534,6 @@ ...@@ -534,11 +534,6 @@
// General Vulkan failures // General Vulkan failures
// ANGLEPosition location assignment overlaps other varyings. This only affects platforms that
// don't support the bresenham line raster extension, which in turn also depends on the driver
// versions.
4251 VULKAN NVIDIA : dEQP-GLES3.functional.shaders.linkage.varying.struct.float_uvec2_vec3 = FAIL
// Tests failing due to the "flat" qualifier in the shader: // Tests failing due to the "flat" qualifier in the shader:
3677 VULKAN : dEQP-GLES3.functional.fragment_out.basic.int.* = FAIL 3677 VULKAN : dEQP-GLES3.functional.fragment_out.basic.int.* = FAIL
3677 VULKAN : dEQP-GLES3.functional.fragment_out.basic.uint.* = FAIL 3677 VULKAN : dEQP-GLES3.functional.fragment_out.basic.uint.* = FAIL
......
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
// --gtest_filter=dEQP.KHR_GLES31/core_texture_storage_multisample_FunctionalTests_verify_sample_masking_for_non_integer_color_renderable_internalformats* --use-angle=swiftshader // --gtest_filter=dEQP.KHR_GLES31/core_texture_storage_multisample_FunctionalTests_verify_sample_masking_for_non_integer_color_renderable_internalformats* --use-angle=swiftshader
4259 SWIFTSHADER : KHR-GLES31.core.texture_storage_multisample.FunctionalTests.verify_sample_masking_for_non_integer_color_renderable_internalformats = FAIL 4259 SWIFTSHADER : KHR-GLES31.core.texture_storage_multisample.FunctionalTests.verify_sample_masking_for_non_integer_color_renderable_internalformats = FAIL
// Swiftshader uses "old" sampler rewrite that doesn't support array of arrays
4071 SWIFTSHADER : KHR-GLES31.core.arrays_of_arrays.* = SKIP
//// ////
//// General Vulkan expectations //// General Vulkan expectations
...@@ -135,3 +137,6 @@ ...@@ -135,3 +137,6 @@
// Fails on Pixel2 and Pixel2 XL // Fails on Pixel2 and Pixel2 XL
4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-elements = FAIL 4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-elements = FAIL
4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays = FAIL 4159 VULKAN PIXEL2ORXL : KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays = FAIL
// Android uses "old" sampler rewrite that doesn't support array of arrays
2703 VULKAN ANDROID : KHR-GLES31.core.arrays_of_arrays.* = SKIP
...@@ -2246,20 +2246,21 @@ TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2) ...@@ -2246,20 +2246,21 @@ TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2)
TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters) TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
{ {
std::stringstream vertexShaderStream; std::stringstream vertexShaderStream;
const unsigned int paramCount = 1024u; // Note: SPIR-V doesn't allow more than 255 parameters to a function.
const unsigned int paramCount = IsVulkan() ? 255u : 1024u;
vertexShaderStream << "#version 300 es\n" vertexShaderStream << "#version 300 es\n"
"precision highp float;\n" "precision highp float;\n"
"in vec4 a_vec;\n" "in vec4 a_vec;\n"
"vec4 lotsOfVec4Parameters("; "vec4 lotsOfVec4Parameters(";
for (unsigned int i = 0; i < paramCount; ++i) for (unsigned int i = 0; i < paramCount - 1; ++i)
{ {
vertexShaderStream << "vec4 a" << i << ", "; vertexShaderStream << "vec4 a" << i << ", ";
} }
vertexShaderStream << "vec4 aLast)\n" vertexShaderStream << "vec4 aLast)\n"
"{\n" "{\n"
" vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);\n"; " vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);\n";
for (unsigned int i = 0; i < paramCount; ++i) for (unsigned int i = 0; i < paramCount - 1; ++i)
{ {
vertexShaderStream << " sum += a" << i << ";\n"; vertexShaderStream << " sum += a" << i << ";\n";
} }
...@@ -2269,7 +2270,7 @@ TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters) ...@@ -2269,7 +2270,7 @@ TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters)
"void main()\n" "void main()\n"
"{\n" "{\n"
" gl_Position = lotsOfVec4Parameters("; " gl_Position = lotsOfVec4Parameters(";
for (unsigned int i = 0; i < paramCount; ++i) for (unsigned int i = 0; i < paramCount - 1; ++i)
{ {
vertexShaderStream << "a_vec, "; vertexShaderStream << "a_vec, ";
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment