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
......@@ -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