Commit 790abf03 by Tim Van Patten Committed by Commit Bot

Vulkan: Support program interface queries for inputs

Program interface queries are a generic way to query attributes of the program like uniforms, samplers, attributes, etc. This change supports those queries for program inputs. Bug: angleproject:3596 Test: dEQP-GLES31.functional.program_interface_query.* Test: ProgramInterfaceTest.cpp Change-Id: Ie904274f4efd87357256f559b69e148e8eda6119 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1775458Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
parent d1c4a6d6
......@@ -1096,7 +1096,7 @@ GLuint ProgramState::getUniformIndexFromImageIndex(GLuint imageIndex) const
GLuint ProgramState::getAttributeLocation(const std::string &name) const
{
for (const sh::ShaderVariable &attribute : mAttributes)
for (const sh::ShaderVariable &attribute : mProgramInputs)
{
if (attribute.name == name)
{
......@@ -1119,6 +1119,24 @@ bool ProgramState::hasAttachedShader() const
return false;
}
ShaderType ProgramState::getFirstAttachedShaderStageType() const
{
for (const gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
{
if (hasLinkedShaderStage(shaderType))
{
return shaderType;
}
}
if (hasLinkedShaderStage(ShaderType::Compute))
{
return ShaderType::Compute;
}
return ShaderType::InvalidEnum;
}
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle)
: mProgram(factory->createProgram(mState)),
mValidated(false),
......@@ -1491,6 +1509,7 @@ angle::Result Program::link(const Context *context)
}
updateLinkedShaderStages();
mState.updateProgramInterfaceInputs();
mLinkingState.reset(new LinkingState());
mLinkingState->linkingFromBinary = false;
......@@ -1637,10 +1656,43 @@ void ProgramState::updateActiveImages()
}
}
void ProgramState::updateProgramInterfaceInputs()
{
const ShaderType firstAttachedShaderType = getFirstAttachedShaderStageType();
if (firstAttachedShaderType == ShaderType::Vertex)
{
// Vertex attributes are already what we need, so nothing to do
return;
}
Shader *shader = getAttachedShader(firstAttachedShaderType);
ASSERT(shader);
// Copy over each input varying, since the Shader could go away
for (const sh::ShaderVariable &varying : shader->getInputVaryings())
{
if (varying.isStruct())
{
for (const sh::ShaderVariable &field : varying.fields)
{
sh::ShaderVariable fieldVarying = sh::ShaderVariable(field);
fieldVarying.location = varying.location;
fieldVarying.name = varying.name + "." + field.name;
mProgramInputs.emplace_back(fieldVarying);
}
}
else
{
mProgramInputs.emplace_back(varying);
}
}
}
// Returns the program object to an unlinked state, before re-linking, or at destruction
void Program::unlink()
{
mState.mAttributes.clear();
mState.mProgramInputs.clear();
mState.mAttributesTypeMask.reset();
mState.mAttributesMask.reset();
mState.mActiveAttribLocationsMask.reset();
......@@ -1897,8 +1949,8 @@ void Program::getActiveAttribute(GLuint index,
return;
}
ASSERT(index < mState.mAttributes.size());
const sh::ShaderVariable &attrib = mState.mAttributes[index];
ASSERT(index < mState.mProgramInputs.size());
const sh::ShaderVariable &attrib = mState.mProgramInputs[index];
if (bufsize > 0)
{
......@@ -1918,7 +1970,7 @@ GLint Program::getActiveAttributeCount() const
return 0;
}
return static_cast<GLint>(mState.mAttributes.size());
return static_cast<GLint>(mState.mProgramInputs.size());
}
GLint Program::getActiveAttributeMaxLength() const
......@@ -1931,7 +1983,7 @@ GLint Program::getActiveAttributeMaxLength() const
size_t maxLength = 0;
for (const sh::ShaderVariable &attrib : mState.mAttributes)
for (const sh::ShaderVariable &attrib : mState.mProgramInputs)
{
maxLength = std::max(attrib.name.length() + 1, maxLength);
}
......@@ -1942,7 +1994,7 @@ GLint Program::getActiveAttributeMaxLength() const
const std::vector<sh::ShaderVariable> &Program::getAttributes() const
{
ASSERT(mLinkResolved);
return mState.mAttributes;
return mState.mProgramInputs;
}
const std::vector<SamplerBinding> &Program::getSamplerBindings() const
......@@ -1978,10 +2030,99 @@ GLint Program::getGeometryShaderMaxVertices() const
return mState.mGeometryShaderMaxVertices;
}
std::string Program::stripArraySubscriptFromName(const GLchar *name) const
{
std::string nameString = std::string(name);
std::size_t bracketPos = nameString.find('[');
if (bracketPos != std::string::npos)
{
nameString = nameString.substr(0, bracketPos);
}
return nameString;
}
int Program::getArrayIndexFromName(const GLchar *name) const
{
std::string nameString = std::string(name);
std::size_t openBracketPos = nameString.find('[');
if (openBracketPos != std::string::npos)
{
std::size_t closeBracketPos = nameString.find(']');
if (closeBracketPos != std::string::npos)
{
return std::stoi(
nameString.substr(openBracketPos + 1, closeBracketPos - openBracketPos - 1));
}
}
// An array variable name without any subscripting defaults to "[0]"
return 0;
}
const sh::ShaderVariable &Program::getInputResource(size_t index) const
{
ASSERT(mLinkResolved);
ASSERT(index < mState.mProgramInputs.size());
return mState.mProgramInputs[index];
}
GLuint Program::getInputResourceIndex(const GLchar *name) const
{
ASSERT(mLinkResolved);
return GetResourceIndexFromName(mState.mAttributes, std::string(name));
const std::string nameString = stripArraySubscriptFromName(name);
for (size_t index = 0; index < mState.mProgramInputs.size(); index++)
{
sh::ShaderVariable resource = getInputResource(index);
if (resource.name == nameString)
{
return static_cast<GLuint>(index);
}
}
return GL_INVALID_INDEX;
}
GLuint Program::getInputResourceMaxNameSize() const
{
GLint max = 0;
for (size_t index = 0; index < mState.mProgramInputs.size(); index++)
{
const sh::ShaderVariable &resource = getInputResource(index);
if (resource.isArray())
{
max = std::max(max, clampCast<GLint>((resource.name + "[0]").size()));
}
else
{
max = std::max(max, clampCast<GLint>((resource.name).size()));
}
}
return max;
}
GLuint Program::getInputResourceLocation(const GLchar *name) const
{
const GLuint index = getInputResourceIndex(name);
if (index == GL_INVALID_INDEX)
{
return index;
}
const sh::ShaderVariable &variable = getInputResource(index);
GLint location = variable.location;
if (variable.isArray())
{
location += getArrayIndexFromName(name);
}
return location;
}
GLuint Program::getOutputResourceIndex(const GLchar *name) const
......@@ -2002,12 +2143,10 @@ const std::vector<GLenum> &Program::getOutputVariableTypes() const
return mState.mOutputVariableTypes;
}
template <typename T>
void Program::getResourceName(GLuint index,
const std::vector<T> &resources,
void Program::getResourceName(const std::string name,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
GLchar *dest) const
{
if (length)
{
......@@ -2018,16 +2157,14 @@ void Program::getResourceName(GLuint index,
{
if (bufSize > 0)
{
name[0] = '\0';
dest[0] = '\0';
}
return;
}
ASSERT(index < resources.size());
const auto &resource = resources[index];
if (bufSize > 0)
{
CopyStringToBuffer(name, resource.name, bufSize, length);
CopyStringToBuffer(dest, name, bufSize, length);
}
}
......@@ -2037,7 +2174,7 @@ void Program::getInputResourceName(GLuint index,
GLchar *name) const
{
ASSERT(mLinkResolved);
getResourceName(index, mState.mAttributes, bufSize, length, name);
getResourceName(getInputResourceName(index), bufSize, length, name);
}
void Program::getOutputResourceName(GLuint index,
......@@ -2046,7 +2183,8 @@ void Program::getOutputResourceName(GLuint index,
GLchar *name) const
{
ASSERT(mLinkResolved);
getResourceName(index, mState.mOutputVariables, bufSize, length, name);
ASSERT(index < mState.mOutputVariables.size());
getResourceName(mState.mOutputVariables[index].name, bufSize, length, name);
}
void Program::getUniformResourceName(GLuint index,
......@@ -2055,7 +2193,8 @@ void Program::getUniformResourceName(GLuint index,
GLchar *name) const
{
ASSERT(mLinkResolved);
getResourceName(index, mState.mUniforms, bufSize, length, name);
ASSERT(index < mState.mUniforms.size());
getResourceName(mState.mUniforms[index].name, bufSize, length, name);
}
void Program::getBufferVariableResourceName(GLuint index,
......@@ -2064,14 +2203,23 @@ void Program::getBufferVariableResourceName(GLuint index,
GLchar *name) const
{
ASSERT(mLinkResolved);
getResourceName(index, mState.mBufferVariables, bufSize, length, name);
ASSERT(index < mState.mBufferVariables.size());
getResourceName(mState.mBufferVariables[index].name, bufSize, length, name);
}
const sh::ShaderVariable &Program::getInputResource(GLuint index) const
const std::string Program::getInputResourceName(GLuint index) const
{
ASSERT(mLinkResolved);
ASSERT(index < mState.mAttributes.size());
return mState.mAttributes[index];
const sh::ShaderVariable &resource = getInputResource(index);
std::string resourceName = resource.name;
if (resource.isArray())
{
resourceName += "[0]";
}
return resourceName;
}
const sh::ShaderVariable &Program::getOutputResource(GLuint index) const
......@@ -3321,19 +3469,19 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
// In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
// see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
// aliasing checks.
mState.mAttributes = vertexShader->getAllAttributes();
mState.mProgramInputs = vertexShader->getAllAttributes();
}
else
{
// In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
mState.mAttributes = vertexShader->getActiveAttributes();
mState.mProgramInputs = vertexShader->getActiveAttributes();
}
GLuint maxAttribs = caps.maxVertexAttributes;
std::vector<sh::ShaderVariable *> usedAttribMap(maxAttribs, nullptr);
// Assign locations to attributes that have a binding location and check for attribute aliasing.
for (sh::ShaderVariable &attribute : mState.mAttributes)
for (sh::ShaderVariable &attribute : mState.mProgramInputs)
{
// GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or
// structures, so we don't need to worry about adjusting their names or generating entries
......@@ -3389,7 +3537,7 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
}
// Assign locations to attributes that don't have a binding location.
for (sh::ShaderVariable &attribute : mState.mAttributes)
for (sh::ShaderVariable &attribute : mState.mProgramInputs)
{
// Not set by glBindAttribLocation or by location layout qualifier
if (attribute.location == -1)
......@@ -3414,8 +3562,8 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
// shader versions we're only processing active attributes to begin with.
if (shaderVersion >= 300)
{
for (auto attributeIter = mState.mAttributes.begin();
attributeIter != mState.mAttributes.end();)
for (auto attributeIter = mState.mProgramInputs.begin();
attributeIter != mState.mProgramInputs.end();)
{
if (attributeIter->active)
{
......@@ -3423,12 +3571,12 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
}
else
{
attributeIter = mState.mAttributes.erase(attributeIter);
attributeIter = mState.mProgramInputs.erase(attributeIter);
}
}
}
for (const sh::ShaderVariable &attribute : mState.mAttributes)
for (const sh::ShaderVariable &attribute : mState.mProgramInputs)
{
ASSERT(attribute.active);
ASSERT(attribute.location != -1);
......@@ -4682,8 +4830,8 @@ void Program::serialize(const Context *context, angle::MemoryBuffer *binaryOut)
stream.writeInt(mState.getActiveAttribLocationsMask().to_ulong());
stream.writeInt(mState.getAttributes().size());
for (const sh::ShaderVariable &attrib : mState.getAttributes())
stream.writeInt(mState.getProgramInputs().size());
for (const sh::ShaderVariable &attrib : mState.getProgramInputs())
{
WriteShaderVar(&stream, attrib);
stream.writeInt(attrib.location);
......@@ -4876,13 +5024,13 @@ angle::Result Program::deserialize(const Context *context,
mState.mActiveAttribLocationsMask = stream.readInt<gl::AttributesMask>();
unsigned int attribCount = stream.readInt<unsigned int>();
ASSERT(mState.mAttributes.empty());
ASSERT(mState.mProgramInputs.empty());
for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex)
{
sh::ShaderVariable attrib;
LoadShaderVar(&stream, &attrib);
attrib.location = stream.readInt<int>();
mState.mAttributes.push_back(attrib);
mState.mProgramInputs.push_back(attrib);
}
unsigned int uniformCount = stream.readInt<unsigned int>();
......
......@@ -321,7 +321,7 @@ class ProgramState final : angle::NonCopyable
{
return mActiveUniformBlockBindings;
}
const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; }
const AttributesMask &getActiveAttribLocationsMask() const
{
return mActiveAttribLocationsMask;
......@@ -400,6 +400,7 @@ class ProgramState final : angle::NonCopyable
{
return mActiveSamplerFormats[textureUnitIndex];
}
ShaderType getFirstAttachedShaderStageType() const;
private:
friend class MemoryProgramCache;
......@@ -408,6 +409,7 @@ class ProgramState final : angle::NonCopyable
void updateTransformFeedbackStrides();
void updateActiveSamplers();
void updateActiveImages();
void updateProgramInterfaceInputs();
// Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
......@@ -425,7 +427,8 @@ class ProgramState final : angle::NonCopyable
// For faster iteration on the blocks currently being bound.
UniformBlockBindingMask mActiveUniformBlockBindings;
std::vector<sh::ShaderVariable> mAttributes;
// Vertex attributes, Fragment input varyings, etc.
std::vector<sh::ShaderVariable> mProgramInputs;
angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
unsigned int mMaxActiveAttribLocation;
ComponentTypeMask mAttributesTypeMask;
......@@ -879,7 +882,10 @@ class Program final : angle::NonCopyable, public LabeledObject
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
const sh::ShaderVariable &getInputResource(GLuint index) const;
const sh::ShaderVariable &getInputResource(size_t index) const;
GLuint getInputResourceMaxNameSize() const;
GLuint getInputResourceLocation(const GLchar *name) const;
const std::string getInputResourceName(GLuint index) const;
const sh::ShaderVariable &getOutputResource(GLuint index) const;
const ProgramBindings &getAttributeBindings() const;
......@@ -936,6 +942,8 @@ class Program final : angle::NonCopyable, public LabeledObject
// Writes a program's binary to the output memory buffer.
void serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
int getArrayIndexFromName(const GLchar *name) const;
private:
struct LinkingState;
......@@ -1024,12 +1032,10 @@ class Program final : angle::NonCopyable, public LabeledObject
GLenum nativeType,
int components) const;
template <typename T>
void getResourceName(GLuint index,
const std::vector<T> &resources,
void getResourceName(const std::string name,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
GLchar *dest) const;
template <typename T>
GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const;
......@@ -1044,6 +1050,8 @@ class Program final : angle::NonCopyable, public LabeledObject
void postResolveLink(const gl::Context *context);
std::string stripArraySubscriptFromName(const GLchar *name) const;
ProgramState mState;
rx::ProgramImpl *mProgram;
......
......@@ -615,24 +615,32 @@ GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
{
const auto &attribute = program->getInputResource(index);
const sh::ShaderVariable &variable = program->getInputResource(index);
switch (prop)
{
case GL_TYPE:
case GL_ARRAY_SIZE:
return GetCommonVariableProperty(variable, prop);
case GL_NAME_LENGTH:
return GetCommonVariableProperty(attribute, prop);
return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
case GL_LOCATION:
return program->getAttributeLocation(attribute.name);
return variable.location;
// The query is targeted at the set of active input variables used by the first shader stage
// of program. If program contains multiple shader stages then input variables from any
// stage other than the first will not be enumerated. Since we found the variable to get
// this far, we know it exists in the first attached shader stage.
case GL_REFERENCED_BY_VERTEX_SHADER:
return 1;
return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
case GL_REFERENCED_BY_FRAGMENT_SHADER:
return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
case GL_REFERENCED_BY_COMPUTE_SHADER:
return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
return 0;
return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
default:
UNREACHABLE();
......@@ -698,7 +706,7 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra
switch (programInterface)
{
case GL_PROGRAM_INPUT:
return clampCast<GLint>(program->getAttributes().size());
return clampCast<GLint>(program->getState().getProgramInputs().size());
case GL_PROGRAM_OUTPUT:
return clampCast<GLint>(program->getState().getOutputVariables().size());
......@@ -744,7 +752,7 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI
switch (programInterface)
{
case GL_PROGRAM_INPUT:
maxNameLength = FindMaxSize(program->getAttributes(), &sh::ShaderVariable::name);
maxNameLength = program->getInputResourceMaxNameSize();
break;
case GL_PROGRAM_OUTPUT:
......@@ -1707,7 +1715,7 @@ GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLe
GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
{
const auto &bufferVariable = program->getBufferVariableByIndex(index);
const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index);
switch (prop)
{
case GL_TYPE:
......@@ -1836,7 +1844,7 @@ GLint QueryProgramResourceLocation(const Program *program,
switch (programInterface)
{
case GL_PROGRAM_INPUT:
return program->getAttributeLocation(name);
return program->getInputResourceLocation(name);
case GL_PROGRAM_OUTPUT:
return program->getFragDataLocation(name);
......@@ -1861,10 +1869,17 @@ void QueryProgramResourceiv(const Program *program,
{
if (!program->isLinked())
{
if (length != nullptr)
{
*length = 0;
}
return;
}
if (length != nullptr)
{
*length = 0;
}
if (bufSize == 0)
{
// No room to write the results
return;
}
......
......@@ -1557,7 +1557,7 @@ angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout(
// Generate new dynamic layout with attribute conversions
std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getAttributes());
mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getProgramInputs());
// Generate new vertex executable
ShaderExecutableD3D *vertexExecutable = nullptr;
......
......@@ -267,7 +267,7 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
}
// Bind attribute locations to match the GL layer.
for (const sh::ShaderVariable &attribute : mState.getAttributes())
for (const sh::ShaderVariable &attribute : mState.getProgramInputs())
{
if (!attribute.active || attribute.isBuiltIn())
{
......
......@@ -497,7 +497,7 @@ void AssignAttributeLocations(const gl::ProgramState &programState,
// Parse attribute locations and replace them in the vertex shader.
// See corresponding code in OutputVulkanGLSL.cpp.
for (const sh::ShaderVariable &attribute : programState.getAttributes())
for (const sh::ShaderVariable &attribute : programState.getProgramInputs())
{
// Warning: If we end up supporting ES 3.0 shaders and up, Program::linkAttributes is
// going to bring us all attributes in this list instead of only the active ones.
......
......@@ -267,7 +267,8 @@ bool ValidateProgramResourceIndex(const Program *programObject,
switch (programInterface)
{
case GL_PROGRAM_INPUT:
return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
return (index <
static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
case GL_PROGRAM_OUTPUT:
return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
......
......@@ -630,7 +630,6 @@
3520 VULKAN : dEQP-GLES31.functional.state_query.integer.max_uniform_locations* = FAIL
// Front-end query bugs:
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.resource_query = FAIL
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.resource_list.compute.empty = FAIL
3520 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL
......@@ -651,55 +650,15 @@
// SSBO and Image qualifiers:
3602 VULKAN : dEQP-GLES31.functional.synchronization.in_invocation.ssbo_alias_overwrite = FAIL
// Struct referenced by:
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.compute.uniform_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.compute.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_vertex.uniform_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_vertex.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_fragment.uniform_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.vertex_fragment_only_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.compute.named_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.compute.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_array_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_struct_array = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_struct_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.named_block.float_unsized_struct_array = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_vertex.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_vertex.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_fragment.named_block.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.vertex_fragment_only_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.*random* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_fragment.uniform_block.*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.separable_fragment.block_array.float_struct = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.resource_list.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.array_size.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.location.separable_fragment.var* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.name_length.separable_fragment.var* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.type.separable_fragment.* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_fragment.named_block.float*struct* = FAIL
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.buffer_variable.referenced_by.separable_fragment.block_array.float_struct = FAIL
// Separate shader objects:
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.referenced_by.referenced_by_separable_fragment = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_input.referenced_by.referenced_by_vertex_fragment = SKIP
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.resource_list.separable_vertex.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.array_size.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.location.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.name_length.separable_vertex.var* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.referenced_by.referenced_by_separable_vertex = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.referenced_by.referenced_by_vertex_fragment = SKIP
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.basic_type.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.array.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.program_output.type.separable_vertex.struct.* = FAIL
3570 VULKAN : dEQP-GLES31.functional.program_interface_query.uniform.random.* = FAIL
// Block name matching failure:
3459 VULKAN : dEQP-GLES31.functional.shaders.linkage.es31.shader_storage_block.mismatch_with_and_without_instance_name = FAIL
......
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