Commit 3a9090fa by Jiajia Qin Committed by Commit Bot

ES31: Add BUFFER_VARIABLE and SHADER_STORAGE_BLOCK program interfaces

This patch collects the shader storage block members information. It implements getShaderStorageBlockMemberInfo and getShaderStorageBlockSize for OpenGL backend. Meanwhile, it implements BUFFER_VARIABLE and SHADER_STORAGE_BLOCK interfaces for program query. BUG=angleproject:1920 TEST=angle_end2end_tests:ProgramInterfaceTest* dEQP-GLES31.functional.layout_binding.ssbo* dEQP-GLES31.functional.compute.basic.empty dEQP-GLES31.functional.compute.basic.ssbo_rw* dEQP-GLES31.functional.compute.basic.ssbo_local_barrier* dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small dEQP-GLES31.functional.compute.basic.shared_var* dEQP-GLES31.functional.compute.basic.ubo_to_ssbo* dEQP-GLES31.functional.compute.basic.write_multiple_arr* dEQP-GLES31.functional.compute.shared_var.basic_type.* dEQP-GLES31.functional.compute.shared_var.work_group_size.* dEQP-GLES31.functional.atomic_counter.* Change-Id: Ie8b81fde5a2e919aab77adb3d137c9ff2f193409 Reviewed-on: https://chromium-review.googlesource.com/712235Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 225bfa95
......@@ -25,7 +25,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 186
#define ANGLE_SH_VERSION 187
enum ShShaderSpec
{
......
......@@ -67,8 +67,8 @@ struct ShaderVariable
ShaderVariable(const ShaderVariable &other);
ShaderVariable &operator=(const ShaderVariable &other);
bool isArray() const { return arraySize > 0; }
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isArray() const { return arraySize > 0 || isUnsizedArray; }
unsigned int elementCount() const { return isUnsizedArray ? 0 : std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); }
// Array size 0 means not an array when passed to or returned from these functions.
......@@ -100,6 +100,7 @@ struct ShaderVariable
bool staticUse;
std::vector<ShaderVariable> fields;
std::string structName;
bool isUnsizedArray;
protected:
bool isSameVariableAtLinkTime(const ShaderVariable &other,
......
......@@ -86,6 +86,19 @@ void MarkStaticallyUsed(ShaderVariable *variable)
}
}
ShaderVariable *FindVariableInInterfaceBlock(const TString &name,
const TInterfaceBlock *interfaceBlock,
std::vector<InterfaceBlock> *infoList)
{
ASSERT(interfaceBlock);
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
ASSERT(namedBlock);
// Set static use on the parent interface block here
namedBlock->staticUse = true;
return FindVariable(name, &namedBlock->fields);
}
// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
// and interface blocks.
class CollectVariablesTraverser : public TIntermTraverser
......@@ -403,13 +416,7 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
if (interfaceBlock)
{
InterfaceBlock *namedBlock =
FindVariable(interfaceBlock->name(), mUniformBlocks);
ASSERT(namedBlock);
var = FindVariable(symbolName, &namedBlock->fields);
// Set static use on the parent interface block here
namedBlock->staticUse = true;
var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
}
else
{
......@@ -420,6 +427,13 @@ void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var);
}
break;
case EvqBuffer:
{
const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
var =
FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
}
break;
case EvqFragCoord:
recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
return;
......@@ -663,6 +677,7 @@ void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlock
setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable);
fieldVariable.isRowMajorLayout =
(fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
fieldVariable.isUnsizedArray = fieldType.isUnsizedArray();
interfaceBlock->fields.push_back(fieldVariable);
}
}
......
......@@ -30,17 +30,18 @@ bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
}
ShaderVariable::ShaderVariable() : type(0), precision(0), arraySize(0), staticUse(false)
ShaderVariable::ShaderVariable()
: type(0), precision(0), arraySize(0), staticUse(false), isUnsizedArray(false)
{
}
ShaderVariable::ShaderVariable(GLenum typeIn)
: type(typeIn), precision(0), arraySize(0), staticUse(false)
: type(typeIn), precision(0), arraySize(0), staticUse(false), isUnsizedArray(false)
{
}
ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
: type(typeIn), precision(0), arraySize(arraySizeIn), staticUse(false)
: type(typeIn), precision(0), arraySize(arraySizeIn), staticUse(false), isUnsizedArray(false)
{
ASSERT(arraySizeIn != 0);
}
......@@ -57,7 +58,8 @@ ShaderVariable::ShaderVariable(const ShaderVariable &other)
arraySize(other.arraySize),
staticUse(other.staticUse),
fields(other.fields),
structName(other.structName)
structName(other.structName),
isUnsizedArray(other.isUnsizedArray)
{
}
......@@ -71,6 +73,7 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
staticUse = other.staticUse;
fields = other.fields;
structName = other.structName;
isUnsizedArray = other.isUnsizedArray;
return *this;
}
......@@ -79,7 +82,7 @@ bool ShaderVariable::operator==(const ShaderVariable &other) const
if (type != other.type || precision != other.precision || name != other.name ||
mappedName != other.mappedName || arraySize != other.arraySize ||
staticUse != other.staticUse || fields.size() != other.fields.size() ||
structName != other.structName)
structName != other.structName || isUnsizedArray != other.isUnsizedArray)
{
return false;
}
......@@ -189,6 +192,10 @@ bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
}
if (structName != other.structName)
return false;
if (isUnsizedArray != other.isUnsizedArray)
{
return false;
}
return true;
}
......
......@@ -27,22 +27,44 @@ struct InterfaceBlock;
struct BlockMemberInfo
{
BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
BlockMemberInfo()
: offset(-1),
arrayStride(-1),
matrixStride(-1),
isRowMajorMatrix(false),
topLevelArrayStride(-1)
{
}
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
arrayStride(arrayStride),
matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix)
isRowMajorMatrix(isRowMajorMatrix),
topLevelArrayStride(-1)
{
}
BlockMemberInfo(int offset,
int arrayStride,
int matrixStride,
bool isRowMajorMatrix,
int topLevelArrayStride)
: offset(offset),
arrayStride(arrayStride),
matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix),
topLevelArrayStride(topLevelArrayStride)
{
}
static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false); }
static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false, -1); }
int offset;
int arrayStride;
int matrixStride;
bool isRowMajorMatrix;
int topLevelArrayStride; // Only used for shader storage block members.
};
class BlockLayoutEncoder
......
......@@ -90,6 +90,38 @@ void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *v
}
}
void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
{
WriteShaderVar(stream, var);
stream->writeInt(var.bufferIndex);
stream->writeInt(var.blockInfo.offset);
stream->writeInt(var.blockInfo.arrayStride);
stream->writeInt(var.blockInfo.matrixStride);
stream->writeInt(var.blockInfo.isRowMajorMatrix);
stream->writeInt(var.blockInfo.topLevelArrayStride);
stream->writeInt(var.topLevelArraySize);
stream->writeInt(var.vertexStaticUse);
stream->writeInt(var.fragmentStaticUse);
stream->writeInt(var.computeStaticUse);
}
void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
{
LoadShaderVar(stream, var);
var->bufferIndex = stream->readInt<int>();
var->blockInfo.offset = stream->readInt<int>();
var->blockInfo.arrayStride = stream->readInt<int>();
var->blockInfo.matrixStride = stream->readInt<int>();
var->blockInfo.isRowMajorMatrix = stream->readBool();
var->blockInfo.topLevelArrayStride = stream->readInt<int>();
var->topLevelArraySize = stream->readInt<int>();
var->vertexStaticUse = stream->readBool();
var->fragmentStaticUse = stream->readBool();
var->computeStaticUse = stream->readBool();
}
void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
{
stream->writeString(block.name);
......@@ -257,6 +289,15 @@ LinkResult MemoryProgramCache::Deserialize(const Context *context,
state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
}
unsigned int bufferVariableCount = stream.readInt<unsigned int>();
ASSERT(state->mBufferVariables.empty());
for (unsigned int index = 0; index < bufferVariableCount; ++index)
{
BufferVariable bufferVariable;
LoadBufferVariable(&stream, &bufferVariable);
state->mBufferVariables.push_back(bufferVariable);
}
unsigned int shaderStorageBlockCount = stream.readInt<unsigned int>();
ASSERT(state->mShaderStorageBlocks.empty());
for (unsigned int shaderStorageBlockIndex = 0;
......@@ -438,6 +479,12 @@ void MemoryProgramCache::Serialize(const Context *context,
WriteInterfaceBlock(&stream, uniformBlock);
}
stream.writeInt(state.getBufferVariables().size());
for (const BufferVariable &bufferVariable : state.getBufferVariables())
{
WriteBufferVariable(&stream, bufferVariable);
}
stream.writeInt(state.getShaderStorageBlocks().size());
for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks())
{
......
......@@ -258,6 +258,53 @@ bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
return true;
}
GLuint GetInterfaceBlockIndex(const std::vector<InterfaceBlock> &list, const std::string &name)
{
std::vector<unsigned int> subscripts;
std::string baseName = ParseResourceName(name, &subscripts);
unsigned int numBlocks = static_cast<unsigned int>(list.size());
for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++)
{
const auto &block = list[blockIndex];
if (block.name == baseName)
{
const bool arrayElementZero =
(subscripts.empty() && (!block.isArray || block.arrayElement == 0));
const bool arrayElementMatches =
(subscripts.size() == 1 && subscripts[0] == block.arrayElement);
if (arrayElementMatches || arrayElementZero)
{
return blockIndex;
}
}
}
return GL_INVALID_INDEX;
}
void GetInterfaceBlockName(const GLuint index,
const std::vector<InterfaceBlock> &list,
GLsizei bufSize,
GLsizei *length,
GLchar *name)
{
ASSERT(index < list.size());
const auto &block = list[index];
if (bufSize > 0)
{
std::string blockName = block.name;
if (block.isArray)
{
blockName += ArrayString(block.arrayElement);
}
CopyStringToBuffer(name, blockName, bufSize, length);
}
}
void InitUniformBlockLinker(const gl::Context *context,
const ProgramState &state,
UniformBlockLinker *blockLinker)
......@@ -440,6 +487,11 @@ GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
return GetResourceIndexFromName(mUniforms, name);
}
GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
{
return GetResourceIndexFromName(mBufferVariables, name);
}
GLuint ProgramState::getUniformIndexFromLocation(GLint location) const
{
ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformLocations.size());
......@@ -771,9 +823,10 @@ Error Program::link(const gl::Context *context)
return NoError();
}
ProgramLinkedResources resources = {{0, PackMode::ANGLE_RELAXED},
{&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks}};
ProgramLinkedResources resources = {
{0, PackMode::ANGLE_RELAXED},
{&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks, &mState.mBufferVariables}};
InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
......@@ -843,9 +896,10 @@ Error Program::link(const gl::Context *context)
auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT
: PackMode::ANGLE_RELAXED;
ProgramLinkedResources resources = {{data.getCaps().maxVaryingVectors, packMode},
{&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks}};
ProgramLinkedResources resources = {
{data.getCaps().maxVaryingVectors, packMode},
{&mState.mUniformBlocks, &mState.mUniforms},
{&mState.mShaderStorageBlocks, &mState.mBufferVariables}};
InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
......@@ -1248,6 +1302,14 @@ void Program::getUniformResourceName(GLuint index,
getResourceName(index, mState.mUniforms, bufSize, length, name);
}
void Program::getBufferVariableResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const
{
getResourceName(index, mState.mBufferVariables, bufSize, length, name);
}
const sh::Attribute &Program::getInputResource(GLuint index) const
{
ASSERT(index < mState.mAttributes.size());
......@@ -1316,6 +1378,11 @@ GLint Program::getActiveUniformCount() const
}
}
size_t Program::getActiveBufferVariableCount() const
{
return mLinked ? mState.mBufferVariables.size() : 0;
}
GLint Program::getActiveUniformMaxLength() const
{
size_t maxLength = 0;
......@@ -1369,6 +1436,12 @@ const LinkedUniform &Program::getUniformByIndex(GLuint index) const
return mState.mUniforms[index];
}
const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
{
ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
return mState.mBufferVariables[index];
}
GLint Program::getUniformLocation(const std::string &name) const
{
return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name);
......@@ -1690,24 +1763,21 @@ GLuint Program::getActiveShaderStorageBlockCount() const
return static_cast<GLuint>(mState.mShaderStorageBlocks.size());
}
void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
void Program::getActiveUniformBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const
{
ASSERT(
uniformBlockIndex <
mState.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
const InterfaceBlock &uniformBlock = mState.mUniformBlocks[uniformBlockIndex];
GetInterfaceBlockName(blockIndex, mState.mUniformBlocks, bufSize, length, blockName);
}
if (bufSize > 0)
{
std::string string = uniformBlock.name;
void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const
{
if (uniformBlock.isArray)
{
string += ArrayString(uniformBlock.arrayElement);
}
CopyStringToBuffer(uniformBlockName, string, bufSize, length);
}
GetInterfaceBlockName(blockIndex, mState.mShaderStorageBlocks, bufSize, length, blockName);
}
GLint Program::getActiveUniformBlockMaxLength() const
......@@ -1733,27 +1803,12 @@ GLint Program::getActiveUniformBlockMaxLength() const
GLuint Program::getUniformBlockIndex(const std::string &name) const
{
std::vector<unsigned int> subscripts;
std::string baseName = ParseResourceName(name, &subscripts);
unsigned int numUniformBlocks = static_cast<unsigned int>(mState.mUniformBlocks.size());
for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
{
const InterfaceBlock &uniformBlock = mState.mUniformBlocks[blockIndex];
if (uniformBlock.name == baseName)
{
const bool arrayElementZero =
(subscripts.empty() && (!uniformBlock.isArray || uniformBlock.arrayElement == 0));
const bool arrayElementMatches =
(subscripts.size() == 1 && subscripts[0] == uniformBlock.arrayElement);
if (arrayElementMatches || arrayElementZero)
{
return blockIndex;
}
}
}
return GetInterfaceBlockIndex(mState.mUniformBlocks, name);
}
return GL_INVALID_INDEX;
GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
{
return GetInterfaceBlockIndex(mState.mShaderStorageBlocks, name);
}
const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
......@@ -1762,6 +1817,12 @@ const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
return mState.mUniformBlocks[index];
}
const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
{
ASSERT(index < static_cast<GLuint>(mState.mShaderStorageBlocks.size()));
return mState.mShaderStorageBlocks[index];
}
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding;
......
......@@ -277,6 +277,7 @@ class ProgramState final : angle::NonCopyable
{
return mShaderStorageBlocks;
}
const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
......@@ -300,6 +301,8 @@ class ProgramState final : angle::NonCopyable
GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
GLuint getAttributeLocation(const std::string &name) const;
GLuint getBufferVariableIndexFromName(const std::string &name) const;
int getNumViews() const { return mNumViews; }
bool usesMultiview() const { return mNumViews != -1; }
......@@ -341,6 +344,7 @@ class ProgramState final : angle::NonCopyable
std::vector<VariableLocation> mUniformLocations;
std::vector<InterfaceBlock> mUniformBlocks;
std::vector<BufferVariable> mBufferVariables;
std::vector<InterfaceBlock> mShaderStorageBlocks;
std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
RangeUI mSamplerUniformRange;
......@@ -453,6 +457,7 @@ class Program final : angle::NonCopyable, public LabeledObject
GLenum *type,
GLchar *name) const;
GLint getActiveUniformCount() const;
size_t getActiveBufferVariableCount() const;
GLint getActiveUniformMaxLength() const;
bool isValidUniformLocation(GLint location) const;
const LinkedUniform &getUniformByLocation(GLint location) const;
......@@ -460,6 +465,8 @@ class Program final : angle::NonCopyable, public LabeledObject
const std::vector<VariableLocation> &getUniformLocations() const;
const LinkedUniform &getUniformByIndex(GLuint index) const;
const BufferVariable &getBufferVariableByIndex(GLuint index) const;
enum SetUniformResult
{
SamplerChanged,
......@@ -494,19 +501,28 @@ class Program final : angle::NonCopyable, public LabeledObject
void getUniformiv(const Context *context, GLint location, GLint *params) const;
void getUniformuiv(const Context *context, GLint location, GLuint *params) const;
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
void getActiveUniformBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const;
void getActiveShaderStorageBlockName(const GLuint blockIndex,
GLsizei bufSize,
GLsizei *length,
GLchar *blockName) const;
GLuint getActiveUniformBlockCount() const;
GLuint getActiveAtomicCounterBufferCount() const;
GLuint getActiveShaderStorageBlockCount() const;
GLint getActiveUniformBlockMaxLength() const;
GLuint getUniformBlockIndex(const std::string &name) const;
GLuint getShaderStorageBlockIndex(const std::string &name) const;
void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode);
void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const;
......@@ -560,6 +576,10 @@ class Program final : angle::NonCopyable, public LabeledObject
void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
void getBufferVariableResourceName(GLuint index,
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
const sh::Attribute &getInputResource(GLuint index) const;
const sh::OutputVariable &getOutputResource(GLuint index) const;
......
......@@ -660,6 +660,7 @@ void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
if (block.name == priorBlock.name)
{
priorBlock.setStaticUse(shaderType, true);
// TODO(jiajia.qin@intel.com): update the block members static use.
}
}
}
......@@ -678,7 +679,9 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
const std::vector<VarT> &fields,
const std::string &prefix,
const std::string &mappedPrefix,
int blockIndex) const
int blockIndex,
bool outsideTopLevelArray,
int topLevelArraySize) const
{
for (const VarT &field : fields)
{
......@@ -689,14 +692,26 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
if (field.isStruct())
{
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
int nextArraySize = topLevelArraySize;
unsigned int elementCount = field.elementCount();
if (outsideTopLevelArray)
{
nextArraySize = elementCount;
// In OpenGL ES 3.10 spec, session 7.3.1.1 'For an active shader storage block
// member declared as an array of an aggregate type, an entry will be generated only
// for the first array element, regardless of its type.'
elementCount = 1;
}
for (unsigned int arrayElement = 0; arrayElement < elementCount; arrayElement++)
{
const std::string elementName =
fullName + (field.isArray() ? ArrayString(arrayElement) : "");
const std::string elementMappedName =
fullMappedName + (field.isArray() ? ArrayString(arrayElement) : "");
defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName,
blockIndex);
blockIndex, false, nextArraySize);
}
}
else
......@@ -714,7 +729,8 @@ void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMembe
fullMappedName += "[0]";
}
defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo);
defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo,
topLevelArraySize);
}
}
}
......@@ -728,11 +744,12 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize
std::vector<unsigned int> blockIndexes;
int blockIndex = static_cast<int>(mBlocksOut->size());
// Track the first and last uniform index to determine the range of active uniforms in the
// block.
// Track the first and last block member index to determine the range of active block members in
// the block.
size_t firstBlockMemberIndex = getCurrentBlockMemberIndex();
defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(),
interfaceBlock.fieldMappedPrefix(), blockIndex);
interfaceBlock.fieldMappedPrefix(), blockIndex,
interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER, 1);
size_t lastBlockMemberIndex = getCurrentBlockMemberIndex();
for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex;
......@@ -748,23 +765,18 @@ void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize
for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
++arrayElement)
{
// We don't currently have the getBlockSize implemented for SSBOs.
// TODO(jiajia.qin@intel.com): Remove the if when we have getBlockSize for SSBOs.
if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
std::string blockArrayName = interfaceBlock.name;
std::string blockMappedArrayName = interfaceBlock.mappedName;
if (interfaceBlock.isArray())
{
std::string blockArrayName = interfaceBlock.name;
std::string blockMappedArrayName = interfaceBlock.mappedName;
if (interfaceBlock.isArray())
{
blockArrayName += ArrayString(arrayElement);
blockMappedArrayName += ArrayString(arrayElement);
}
blockArrayName += ArrayString(arrayElement);
blockMappedArrayName += ArrayString(arrayElement);
}
// Don't define this block at all if it's not active in the implementation.
if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
{
continue;
}
// Don't define this block at all if it's not active in the implementation.
if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
{
continue;
}
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
......@@ -795,11 +807,13 @@ void UniformBlockLinker::defineBlockMember(const sh::ShaderVariable &field,
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
const sh::BlockMemberInfo &memberInfo) const
const sh::BlockMemberInfo &memberInfo,
int /* topLevelArraySize */) const
{
LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, -1, -1, -1,
blockIndex, memberInfo);
newUniform.mappedName = fullMappedName;
// TODO(jiajia.qin@intel.com): update the block memeber static use.
// Since block uniforms have no location, we don't need to store them in the uniform locations
// list.
......@@ -812,8 +826,9 @@ size_t UniformBlockLinker::getCurrentBlockMemberIndex() const
}
// ShaderStorageBlockLinker implementation.
ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut)
: InterfaceBlockLinker(blocksOut)
ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
std::vector<BufferVariable> *bufferVariablesOut)
: InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut)
{
}
......@@ -825,15 +840,22 @@ void ShaderStorageBlockLinker::defineBlockMember(const sh::ShaderVariable &field
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
const sh::BlockMemberInfo &memberInfo) const
const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const
{
// TODO(jiajia.qin@intel.com): Add buffer variables support.
BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySize,
blockIndex, memberInfo);
newBufferVariable.mappedName = fullMappedName;
// TODO(jiajia.qin@intel.com): update the block memeber static use.
newBufferVariable.topLevelArraySize = topLevelArraySize;
mBufferVariablesOut->push_back(newBufferVariable);
}
size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
{
// TODO(jiajia.qin@intel.com): Add buffer variables support.
return 0;
return mBufferVariablesOut->size();
}
} // namespace gl
......@@ -147,13 +147,16 @@ class InterfaceBlockLinker : angle::NonCopyable
const std::vector<VarT> &fields,
const std::string &prefix,
const std::string &mappedPrefix,
int blockIndex) const;
int blockIndex,
bool outsideTopLevelArray,
int topLevelArraySize) const;
virtual void defineBlockMember(const sh::ShaderVariable &field,
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
const sh::BlockMemberInfo &memberInfo) const = 0;
const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const = 0;
virtual size_t getCurrentBlockMemberIndex() const = 0;
using ShaderBlocks = std::pair<GLenum, const std::vector<sh::InterfaceBlock> *>;
......@@ -174,16 +177,17 @@ class UniformBlockLinker final : public InterfaceBlockLinker
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
const sh::BlockMemberInfo &memberInfo) const override;
const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const override;
size_t getCurrentBlockMemberIndex() const override;
std::vector<LinkedUniform> *mUniformsOut;
};
// TODO(jiajia.qin@intel.com): Add buffer variables support.
class ShaderStorageBlockLinker final : public InterfaceBlockLinker
{
public:
ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut);
ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
std::vector<BufferVariable> *bufferVariablesOut);
virtual ~ShaderStorageBlockLinker();
private:
......@@ -191,8 +195,10 @@ class ShaderStorageBlockLinker final : public InterfaceBlockLinker
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
const sh::BlockMemberInfo &memberInfo) const override;
const sh::BlockMemberInfo &memberInfo,
int topLevelArraySize) const override;
size_t getCurrentBlockMemberIndex() const override;
std::vector<BufferVariable> *mBufferVariablesOut;
};
// The link operation is responsible for finishing the link of uniform and interface blocks.
......
......@@ -144,6 +144,29 @@ size_t LinkedUniform::getElementComponents() const
return typeInfo->componentCount;
}
BufferVariable::BufferVariable()
: bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()), topLevelArraySize(-1)
{
}
BufferVariable::BufferVariable(GLenum typeIn,
GLenum precisionIn,
const std::string &nameIn,
unsigned int arraySizeIn,
const int bufferIndexIn,
const sh::BlockMemberInfo &blockInfoIn)
: bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1)
{
type = typeIn;
precision = precisionIn;
name = nameIn;
arraySize = arraySizeIn;
}
BufferVariable::~BufferVariable()
{
}
ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0)
{
}
......
......@@ -69,6 +69,23 @@ struct LinkedUniform : public sh::Uniform, public StaticallyUsed
sh::BlockMemberInfo blockInfo;
};
struct BufferVariable : public sh::ShaderVariable, public StaticallyUsed
{
BufferVariable();
BufferVariable(GLenum type,
GLenum precision,
const std::string &name,
unsigned int arraySize,
const int bufferIndex,
const sh::BlockMemberInfo &blockInfo);
~BufferVariable();
int bufferIndex;
sh::BlockMemberInfo blockInfo;
int topLevelArraySize;
};
// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
// contain a group of shader variables, and have a GL buffer backed.
struct ShaderVariableBuffer : public StaticallyUsed
......
......@@ -539,10 +539,14 @@ GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum progra
case GL_ATOMIC_COUNTER_BUFFER:
return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
return clampCast<GLint>(program->getState().getBufferVariables().size());
case GL_SHADER_STORAGE_BLOCK:
return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED();
return 0;
......@@ -586,10 +590,18 @@ GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programI
FindMaxSize(program->getState().getUniformBlocks(), &InterfaceBlock::name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
maxNameLength =
FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
break;
case GL_SHADER_STORAGE_BLOCK:
maxNameLength =
FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
UNIMPLEMENTED();
return 0;
......@@ -612,10 +624,9 @@ GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum
return FindMaxSize(program->getState().getAtomicCounterBuffers(),
&AtomicCounterBuffer::memberIndexes);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
return 0;
return FindMaxSize(program->getState().getShaderStorageBlocks(),
&InterfaceBlock::memberIndexes);
default:
UNREACHABLE();
......@@ -747,6 +758,19 @@ void GetUniformBlockResourceProperty(const Program *program,
GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
}
void GetShaderStorageBlockResourceProperty(const Program *program,
GLuint blockIndex,
GLenum pname,
GLint *params,
GLsizei bufSize,
GLsizei *outputPosition)
{
ASSERT(*outputPosition < bufSize);
const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
}
void GetAtomicCounterBufferResourceProperty(const Program *program,
GLuint index,
GLenum pname,
......@@ -1383,6 +1407,57 @@ 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);
switch (prop)
{
case GL_TYPE:
return clampCast<GLint>(bufferVariable.type);
case GL_ARRAY_SIZE:
return clampCast<GLint>(bufferVariable.elementCount());
case GL_BLOCK_INDEX:
return bufferVariable.bufferIndex;
case GL_NAME_LENGTH:
// ES31 spec p84: This counts the terminating null char.
return clampCast<GLint>(bufferVariable.name.size() + 1u);
case GL_OFFSET:
return bufferVariable.blockInfo.offset;
case GL_ARRAY_STRIDE:
return bufferVariable.blockInfo.arrayStride;
case GL_MATRIX_STRIDE:
return bufferVariable.blockInfo.matrixStride;
case GL_IS_ROW_MAJOR:
return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
case GL_REFERENCED_BY_VERTEX_SHADER:
return bufferVariable.vertexStaticUse;
case GL_REFERENCED_BY_FRAGMENT_SHADER:
return bufferVariable.fragmentStaticUse;
case GL_REFERENCED_BY_COMPUTE_SHADER:
return bufferVariable.computeStaticUse;
case GL_TOP_LEVEL_ARRAY_SIZE:
return bufferVariable.topLevelArraySize;
case GL_TOP_LEVEL_ARRAY_STRIDE:
return bufferVariable.blockInfo.topLevelArrayStride;
default:
UNREACHABLE();
return 0;
}
}
GLuint QueryProgramResourceIndex(const Program *program,
GLenum programInterface,
const GLchar *name)
......@@ -1398,13 +1473,17 @@ GLuint QueryProgramResourceIndex(const Program *program,
case GL_UNIFORM:
return program->getState().getUniformIndexFromName(name);
case GL_BUFFER_VARIABLE:
return program->getState().getBufferVariableIndexFromName(name);
case GL_SHADER_STORAGE_BLOCK:
return program->getShaderStorageBlockIndex(name);
case GL_UNIFORM_BLOCK:
return program->getUniformBlockIndex(name);
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
return GL_INVALID_INDEX;
......@@ -1435,14 +1514,20 @@ void QueryProgramResourceName(const Program *program,
program->getUniformResourceName(index, bufSize, length, name);
break;
case GL_BUFFER_VARIABLE:
program->getBufferVariableResourceName(index, bufSize, length, name);
break;
case GL_SHADER_STORAGE_BLOCK:
program->getActiveShaderStorageBlockName(index, bufSize, length, name);
break;
case GL_UNIFORM_BLOCK:
program->getActiveUniformBlockName(index, bufSize, length, name);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
break;
......@@ -1509,18 +1594,27 @@ void QueryProgramResourceiv(const Program *program,
params[i] = GetUniformResourceProperty(program, index, props[i]);
++pos;
break;
case GL_BUFFER_VARIABLE:
params[i] = GetBufferVariableResourceProperty(program, index, props[i]);
++pos;
break;
case GL_UNIFORM_BLOCK:
GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos);
break;
case GL_SHADER_STORAGE_BLOCK:
GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize,
&pos);
break;
case GL_ATOMIC_COUNTER_BUFFER:
GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
&pos);
break;
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
params[i] = GL_INVALID_VALUE;
break;
......
......@@ -580,6 +580,60 @@ bool ProgramGL::getUniformBlockMemberInfo(const std::string & /* memberUniformNa
return true;
}
bool ProgramGL::getShaderStorageBlockMemberInfo(const std::string & /* memberName */,
const std::string &memberUniformMappedName,
sh::BlockMemberInfo *memberInfoOut) const
{
const GLchar *memberNameGLStr = memberUniformMappedName.c_str();
GLuint index =
mFunctions->getProgramResourceIndex(mProgramID, GL_BUFFER_VARIABLE, memberNameGLStr);
if (index == GL_INVALID_INDEX)
{
*memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
return false;
}
constexpr int kPropCount = 5;
std::array<GLenum, kPropCount> props = {
{GL_ARRAY_STRIDE, GL_IS_ROW_MAJOR, GL_MATRIX_STRIDE, GL_OFFSET, GL_TOP_LEVEL_ARRAY_STRIDE}};
std::array<GLint, kPropCount> params;
GLsizei length;
mFunctions->getProgramResourceiv(mProgramID, GL_BUFFER_VARIABLE, index, kPropCount,
props.data(), kPropCount, &length, params.data());
ASSERT(kPropCount == length);
memberInfoOut->arrayStride = params[0];
memberInfoOut->isRowMajorMatrix = params[1];
memberInfoOut->matrixStride = params[2];
memberInfoOut->offset = params[3];
memberInfoOut->topLevelArrayStride = params[4];
return true;
}
bool ProgramGL::getShaderStorageBlockSize(const std::string &name,
const std::string &mappedName,
size_t *sizeOut) const
{
const GLchar *nameGLStr = mappedName.c_str();
GLuint index =
mFunctions->getProgramResourceIndex(mProgramID, GL_SHADER_STORAGE_BLOCK, nameGLStr);
if (index == GL_INVALID_INDEX)
{
*sizeOut = 0;
return false;
}
GLenum prop = GL_BUFFER_DATA_SIZE;
GLsizei length = 0;
GLint dataSize = 0;
mFunctions->getProgramResourceiv(mProgramID, GL_SHADER_STORAGE_BLOCK, index, 1, &prop, 1,
&length, &dataSize);
*sizeOut = static_cast<size_t>(dataSize);
return true;
}
void ProgramGL::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
......@@ -822,18 +876,16 @@ void ProgramGL::linkResources(const gl::ProgramLinkedResources &resources)
resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
// TODO(jiajia.qin@intel.com): Determine correct shader storage block info.
auto getShaderStorageBlockSize = [](const std::string &name, const std::string &mappedName,
size_t *sizeOut) {
*sizeOut = 0;
return true;
auto getShaderStorageBlockSize = [this](const std::string &name, const std::string &mappedName,
size_t *sizeOut) {
return this->getShaderStorageBlockSize(name, mappedName, sizeOut);
};
auto getShaderStorageBlockMemberInfo =
[](const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut) {
*infoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
return true;
};
auto getShaderStorageBlockMemberInfo = [this](const std::string &name,
const std::string &mappedName,
sh::BlockMemberInfo *infoOut) {
return this->getShaderStorageBlockMemberInfo(name, mappedName, infoOut);
};
resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
getShaderStorageBlockMemberInfo);
}
......
......@@ -96,6 +96,12 @@ class ProgramGL : public ProgramImpl
bool getUniformBlockMemberInfo(const std::string &memberUniformName,
const std::string &memberUniformMappedName,
sh::BlockMemberInfo *memberInfoOut) const;
bool getShaderStorageBlockMemberInfo(const std::string &memberName,
const std::string &memberMappedName,
sh::BlockMemberInfo *memberInfoOut) const;
bool getShaderStorageBlockSize(const std::string &blockName,
const std::string &blockMappedName,
size_t *sizeOut) const;
void linkResources(const gl::ProgramLinkedResources &resources);
// Helper function, makes it simpler to type.
......
......@@ -260,6 +260,12 @@ bool ValidateProgramResourceIndex(const Program *programObject,
case GL_UNIFORM:
return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
case GL_BUFFER_VARIABLE:
return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
case GL_SHADER_STORAGE_BLOCK:
return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
case GL_UNIFORM_BLOCK:
return (index < programObject->getActiveUniformBlockCount());
......@@ -268,8 +274,6 @@ bool ValidateProgramResourceIndex(const Program *programObject,
// TODO(jie.a.chen@intel.com): more interfaces.
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_BUFFER_VARIABLE:
case GL_SHADER_STORAGE_BLOCK:
UNIMPLEMENTED();
return false;
......
......@@ -66,6 +66,31 @@
1442 D3D11 : dEQP-GLES31.functional.state_query.internal_format.renderbuffer.* = FAIL
1679 D3D11 : dEQP-GLES31.functional.state_query.texture_level.texture_2d_multisample.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.state_query.program.compute_work_group_size_get_programiv = FAIL
1442 D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.empty = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_invocations = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_groups = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.shared_var.basic_type.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.compute.shared_var.work_group_size.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.texture.texparameter* = SKIP
1442 D3D11 : dEQP-GLES31.functional.debug.negative_coverage.log.texture.texparameter* = SKIP
......@@ -1153,38 +1178,17 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_count = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_constants.core.max_compute_work_group_size = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.empty = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ubo_to_ssbo_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_rw_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_unsized_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_local_barrier_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_single = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.ssbo_cmd_barrier_multiple = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_var_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_invocation = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.shared_atomic_op_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_large = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_large = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_single = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.image_barrier_multiple = FAIL
......@@ -1192,7 +1196,7 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_single_group = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_invocations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.shared_var.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.shared_var.atomic.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_array.* = FAIL
......@@ -1213,7 +1217,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.22 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.37 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_shared_buffer.38 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.atomic_counter.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_2d_array = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.stencil_texturing.format.depth32f_stencil8_cube = FAIL
......@@ -1307,6 +1310,5 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
......@@ -580,6 +580,221 @@ TEST_P(ProgramInterfaceTestES31, QueryAtomicCounteBuffer)
EXPECT_EQ(0, params[4]); // referenced_by_compute_shader
}
// Tests the resource property query for buffer variable can be done correctly.
TEST_P(ProgramInterfaceTestES31, GetBufferVariableProperties)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"struct S {\n"
" vec3 a;\n"
" ivec2 b[4];\n"
"};\n"
"layout(std140) buffer blockName0 {\n"
" S s0;\n"
" vec2 v0;\n"
" S s1[2];\n"
" uint u0;\n"
"};\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"void main()\n"
"{\n"
" gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
"}\n";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
" oColor = vec4(instanceName1[0].f1, 0, 0, 1);\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockName1.f1");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
GLchar name[64];
GLsizei length;
glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_EQ("blockName1.f1", std::string(name));
GLenum props[] = {GL_ARRAY_SIZE,
GL_ARRAY_STRIDE,
GL_BLOCK_INDEX,
GL_IS_ROW_MAJOR,
GL_MATRIX_STRIDE,
GL_NAME_LENGTH,
GL_OFFSET,
GL_REFERENCED_BY_VERTEX_SHADER,
GL_REFERENCED_BY_FRAGMENT_SHADER,
GL_REFERENCED_BY_COMPUTE_SHADER,
GL_TOP_LEVEL_ARRAY_SIZE,
GL_TOP_LEVEL_ARRAY_STRIDE,
GL_TYPE};
GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
constexpr int kBufSize = 256;
GLint params[kBufSize];
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(1, params[0]); // array_size
EXPECT_LE(0, params[1]); // array_stride
EXPECT_LE(0, params[2]); // block_index
EXPECT_EQ(0, params[3]); // is_row_major
EXPECT_EQ(0, params[4]); // matrix_stride
EXPECT_EQ(14, params[5]); // name_length
EXPECT_LE(0, params[6]); // offset
// TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
// EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
// EXPECT_EQ(1, params[8]); // referenced_by_fragment_shader
// EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
EXPECT_EQ(1, params[10]); // top_level_array_size
EXPECT_LE(0, params[11]); // top_level_array_stride
EXPECT_EQ(GL_FLOAT, params[12]); // type
index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "s1[0].a");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(7, length);
EXPECT_EQ("s1[0].a", std::string(name));
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(propCount, length);
EXPECT_EQ(1, params[0]); // array_size
EXPECT_LE(0, params[1]); // array_stride
EXPECT_LE(0, params[2]); // block_index
EXPECT_EQ(0, params[3]); // is_row_major
EXPECT_EQ(0, params[4]); // matrix_stride
EXPECT_EQ(8, params[5]); // name_length
EXPECT_LE(0, params[6]); // offset
// TODO(jiajia.qin@intel.com): Enable them once the block member staticUse are implemented.
// EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
// EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
// EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
EXPECT_EQ(2, params[10]); // top_level_array_size
EXPECT_EQ(80, params[11]); // top_level_array_stride
EXPECT_EQ(GL_FLOAT_VEC3, params[12]); // type
}
// Tests the resource property query for shader storage block can be done correctly.
TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties)
{
const std::string &vertexShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"struct S {\n"
" vec3 a;\n"
" ivec2 b[4];\n"
"};\n"
"layout(std140) buffer blockName0 {\n"
" S s0;\n"
" vec2 v0;\n"
" S s1[2];\n"
" uint u0;\n"
"};\n"
"layout(binding = 1) buffer blockName1 {\n"
" uint u1[2];\n"
" float f1;\n"
"} instanceName1[2];\n"
"layout(binding = 2) buffer blockName2 {\n"
" uint u2;\n"
" float f2;\n"
"};\n"
"void main()\n"
"{\n"
" gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
"}\n";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"precision highp float;\n"
"uniform vec4 color;\n"
"out vec4 oColor;\n"
"void main()\n"
"{\n"
" oColor = color;\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
GLuint index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName0");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
GLchar name[64];
GLsizei length;
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(10, length);
EXPECT_EQ("blockName0", std::string(name));
GLenum props[] = {GL_ACTIVE_VARIABLES,
GL_BUFFER_BINDING,
GL_NUM_ACTIVE_VARIABLES,
GL_BUFFER_DATA_SIZE,
GL_NAME_LENGTH,
GL_REFERENCED_BY_VERTEX_SHADER,
GL_REFERENCED_BY_FRAGMENT_SHADER,
GL_REFERENCED_BY_COMPUTE_SHADER};
GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
constexpr int kBufSize = 256;
GLint params[kBufSize];
glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, index, propCount, props, kBufSize,
&length, params);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_LE(0, params[0]); // active_variables s0.a
EXPECT_LE(0, params[1]); // active_variables s0.b
EXPECT_LE(0, params[2]); // active_variables v0
EXPECT_LE(0, params[3]); // active_variables s1[0].a
EXPECT_LE(0, params[4]); // active_variables s1[0].b
EXPECT_LE(0, params[5]); // active_variables u0
EXPECT_EQ(0, params[6]); // buffer_binding
EXPECT_EQ(6, params[7]); // num_active_variables
EXPECT_LE(0, params[8]); // buffer_data_size
EXPECT_EQ(11, params[9]); // name_length
EXPECT_EQ(1, params[10]); // referenced_by_vertex_shader
EXPECT_EQ(0, params[11]); // referenced_by_fragment_shader
EXPECT_EQ(0, params[12]); // referenced_by_compute_shader
index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName1");
EXPECT_GL_NO_ERROR();
EXPECT_NE(GL_INVALID_INDEX, index);
glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
EXPECT_GL_NO_ERROR();
EXPECT_EQ(13, length);
EXPECT_EQ("blockName1[0]", std::string(name));
}
ANGLE_INSTANTIATE_TEST(ProgramInterfaceTestES31, ES31_OPENGL(), ES31_OPENGLES());
} // anonymous namespace
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