Commit 4e712be2 by Jamie Madill Committed by Commit Bot

Refactor BlockLayoutEncoder APIs for std430.

This splits HLSL SSBO access into two steps. First we compute a mapping from the collected SSBO variable names to TField pointers. Then during tree traversal we use a block encoding visitor class that uses the shader names to store BlockMemberInfo structures for the structures and variables. Each nested structure is traversed separately so that the BlockMemberInfo offsets are relative to the structure start rather than the enclosing block. The array stride for a structure is the size of the struct after all the alignment is included. This gives the correct results for the SSBO access chain in the HLSL code. It also will allow us to use the same encoding and visiting logic for SSBOs on the API side. Bug: angleproject:3024 Change-Id: I42b1db0e7547782ae77fe5f64a797f803f203f45 Reviewed-on: https://chromium-review.googlesource.com/c/1352731 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent f83a28a6
...@@ -235,7 +235,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -235,7 +235,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
sh::WorkGroupSize workGroupSize, sh::WorkGroupSize workGroupSize,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
PerformanceDiagnostics *perfDiagnostics) PerformanceDiagnostics *perfDiagnostics,
const std::vector<InterfaceBlock> &shaderStorageBlocks)
: TIntermTraverser(true, true, true, symbolTable), : TIntermTraverser(true, true, true, symbolTable),
mShaderType(shaderType), mShaderType(shaderType),
mShaderVersion(shaderVersion), mShaderVersion(shaderVersion),
...@@ -303,7 +304,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, ...@@ -303,7 +304,8 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
// Reserve registers for the default uniform block and driver constants // Reserve registers for the default uniform block and driver constants
mResourcesHLSL->reserveUniformBlockRegisters(2); mResourcesHLSL->reserveUniformBlockRegisters(2);
mSSBOOutputHLSL = new ShaderStorageBlockOutputHLSL(this, symbolTable, mResourcesHLSL); mSSBOOutputHLSL =
new ShaderStorageBlockOutputHLSL(this, symbolTable, mResourcesHLSL, shaderStorageBlocks);
} }
OutputHLSL::~OutputHLSL() OutputHLSL::~OutputHLSL()
......
...@@ -47,7 +47,8 @@ class OutputHLSL : public TIntermTraverser ...@@ -47,7 +47,8 @@ class OutputHLSL : public TIntermTraverser
ShCompileOptions compileOptions, ShCompileOptions compileOptions,
sh::WorkGroupSize workGroupSize, sh::WorkGroupSize workGroupSize,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
PerformanceDiagnostics *perfDiagnostics); PerformanceDiagnostics *perfDiagnostics,
const std::vector<InterfaceBlock> &shaderStorageBlocks);
~OutputHLSL(); ~OutputHLSL();
......
...@@ -34,12 +34,15 @@ using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>; ...@@ -34,12 +34,15 @@ using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
// Used to save shader storage block field member information. // Used to save shader storage block field member information.
using BlockMemberInfoMap = std::map<const TField *, BlockMemberInfo>; using BlockMemberInfoMap = std::map<const TField *, BlockMemberInfo>;
using ShaderVarToFieldMap = std::map<std::string, const TField *>;
class ShaderStorageBlockOutputHLSL : public TIntermTraverser class ShaderStorageBlockOutputHLSL : public TIntermTraverser
{ {
public: public:
ShaderStorageBlockOutputHLSL(OutputHLSL *outputHLSL, ShaderStorageBlockOutputHLSL(OutputHLSL *outputHLSL,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
ResourcesHLSL *resourcesHLSL); ResourcesHLSL *resourcesHLSL,
const std::vector<InterfaceBlock> &shaderStorageBlocks);
~ShaderStorageBlockOutputHLSL(); ~ShaderStorageBlockOutputHLSL();
...@@ -82,6 +85,7 @@ class ShaderStorageBlockOutputHLSL : public TIntermTraverser ...@@ -82,6 +85,7 @@ class ShaderStorageBlockOutputHLSL : public TIntermTraverser
ReferencedInterfaceBlocks mReferencedShaderStorageBlocks; ReferencedInterfaceBlocks mReferencedShaderStorageBlocks;
BlockMemberInfoMap mBlockMemberInfoMap; BlockMemberInfoMap mBlockMemberInfoMap;
const std::vector<InterfaceBlock> &mShaderStorageBlocks;
}; };
} // namespace sh } // namespace sh
......
...@@ -138,7 +138,7 @@ void TranslatorHLSL::translate(TIntermBlock *root, ...@@ -138,7 +138,7 @@ void TranslatorHLSL::translate(TIntermBlock *root,
sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), getSourcePath(), getOutputType(), numRenderTargets, getUniforms(),
compileOptions, getComputeShaderLocalSize(), &getSymbolTable(), compileOptions, getComputeShaderLocalSize(), &getSymbolTable(),
perfDiagnostics); perfDiagnostics, mShaderStorageBlocks);
outputHLSL.output(root, getInfoSink().obj); outputHLSL.output(root, getInfoSink().obj);
......
...@@ -66,6 +66,11 @@ struct BlockMemberInfo ...@@ -66,6 +66,11 @@ struct BlockMemberInfo
int topLevelArrayStride = -1; int topLevelArrayStride = -1;
}; };
constexpr size_t ComponentAlignment(size_t numComponents)
{
return (numComponents == 3u ? 4u : numComponents);
}
constexpr BlockMemberInfo kDefaultBlockMemberInfo; constexpr BlockMemberInfo kDefaultBlockMemberInfo;
class BlockLayoutEncoder class BlockLayoutEncoder
...@@ -78,13 +83,11 @@ class BlockLayoutEncoder ...@@ -78,13 +83,11 @@ class BlockLayoutEncoder
const std::vector<unsigned int> &arraySizes, const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix); bool isRowMajorMatrix);
size_t getBlockSize() const { return mCurrentOffset * kBytesPerComponent; } size_t getCurrentOffset() const { return mCurrentOffset * kBytesPerComponent; }
size_t getStructureBaseAlignment() const { return mStructureBaseAlignment; }
void increaseCurrentOffset(size_t offsetInBytes);
void setStructureBaseAlignment(size_t baseAlignment);
virtual void enterAggregateType() = 0; // Called when entering/exiting a structure variable.
virtual void exitAggregateType() = 0; virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
virtual void exitAggregateType(const ShaderVariable &structVar) = 0;
static constexpr size_t kBytesPerComponent = 4u; static constexpr size_t kBytesPerComponent = 4u;
static constexpr unsigned int kComponentsPerRegister = 4u; static constexpr unsigned int kComponentsPerRegister = 4u;
...@@ -93,10 +96,7 @@ class BlockLayoutEncoder ...@@ -93,10 +96,7 @@ class BlockLayoutEncoder
static size_t GetBlockRegisterElement(const BlockMemberInfo &info); static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
protected: protected:
size_t mCurrentOffset; void align(size_t baseAlignment);
size_t mStructureBaseAlignment;
virtual void nextRegister();
virtual void getBlockLayoutInfo(GLenum type, virtual void getBlockLayoutInfo(GLenum type,
const std::vector<unsigned int> &arraySizes, const std::vector<unsigned int> &arraySizes,
...@@ -108,6 +108,8 @@ class BlockLayoutEncoder ...@@ -108,6 +108,8 @@ class BlockLayoutEncoder
bool isRowMajorMatrix, bool isRowMajorMatrix,
int arrayStride, int arrayStride,
int matrixStride) = 0; int matrixStride) = 0;
size_t mCurrentOffset;
}; };
// Will return default values for everything. // Will return default values for everything.
...@@ -116,8 +118,8 @@ class DummyBlockEncoder : public BlockLayoutEncoder ...@@ -116,8 +118,8 @@ class DummyBlockEncoder : public BlockLayoutEncoder
public: public:
DummyBlockEncoder() = default; DummyBlockEncoder() = default;
void enterAggregateType() override {} void enterAggregateType(const ShaderVariable &structVar) override {}
void exitAggregateType() override {} void exitAggregateType(const ShaderVariable &structVar) override {}
protected: protected:
void getBlockLayoutInfo(GLenum type, void getBlockLayoutInfo(GLenum type,
...@@ -146,8 +148,8 @@ class Std140BlockEncoder : public BlockLayoutEncoder ...@@ -146,8 +148,8 @@ class Std140BlockEncoder : public BlockLayoutEncoder
public: public:
Std140BlockEncoder(); Std140BlockEncoder();
void enterAggregateType() override; void enterAggregateType(const ShaderVariable &structVar) override;
void exitAggregateType() override; void exitAggregateType(const ShaderVariable &structVar) override;
protected: protected:
void getBlockLayoutInfo(GLenum type, void getBlockLayoutInfo(GLenum type,
...@@ -160,6 +162,16 @@ class Std140BlockEncoder : public BlockLayoutEncoder ...@@ -160,6 +162,16 @@ class Std140BlockEncoder : public BlockLayoutEncoder
bool isRowMajorMatrix, bool isRowMajorMatrix,
int arrayStride, int arrayStride,
int matrixStride) override; int matrixStride) override;
virtual size_t getBaseAlignment(const ShaderVariable &variable) const
{
return kComponentsPerRegister;
}
virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const
{
return kComponentsPerRegister;
}
}; };
class Std430BlockEncoder : public Std140BlockEncoder class Std430BlockEncoder : public Std140BlockEncoder
...@@ -168,12 +180,8 @@ class Std430BlockEncoder : public Std140BlockEncoder ...@@ -168,12 +180,8 @@ class Std430BlockEncoder : public Std140BlockEncoder
Std430BlockEncoder(); Std430BlockEncoder();
protected: protected:
void nextRegister() override; size_t getBaseAlignment(const ShaderVariable &variable) const override;
void getBlockLayoutInfo(GLenum type, size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
const std::vector<unsigned int> &arraySizes,
bool isRowMajorMatrix,
int *arrayStrideOut,
int *matrixStrideOut) override;
}; };
using BlockLayoutMap = std::map<std::string, BlockMemberInfo>; using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
...@@ -197,8 +205,8 @@ class ShaderVariableVisitor ...@@ -197,8 +205,8 @@ class ShaderVariableVisitor
virtual void enterStruct(const ShaderVariable &structVar) {} virtual void enterStruct(const ShaderVariable &structVar) {}
virtual void exitStruct(const ShaderVariable &structVar) {} virtual void exitStruct(const ShaderVariable &structVar) {}
virtual void enterStructAccess(const ShaderVariable &structVar) {} virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
virtual void exitStructAccess(const ShaderVariable &structVar) {} virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
virtual void enterArray(const ShaderVariable &arrayVar) {} virtual void enterArray(const ShaderVariable &arrayVar) {}
virtual void exitArray(const ShaderVariable &arrayVar) {} virtual void exitArray(const ShaderVariable &arrayVar) {}
...@@ -222,8 +230,8 @@ class VariableNameVisitor : public ShaderVariableVisitor ...@@ -222,8 +230,8 @@ class VariableNameVisitor : public ShaderVariableVisitor
void enterStruct(const ShaderVariable &structVar) override; void enterStruct(const ShaderVariable &structVar) override;
void exitStruct(const ShaderVariable &structVar) override; void exitStruct(const ShaderVariable &structVar) override;
void enterStructAccess(const ShaderVariable &structVar) override; void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
void exitStructAccess(const ShaderVariable &structVar) override; void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
void enterArray(const ShaderVariable &arrayVar) override; void enterArray(const ShaderVariable &arrayVar) override;
void exitArray(const ShaderVariable &arrayVar) override; void exitArray(const ShaderVariable &arrayVar) override;
void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override; void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
...@@ -243,11 +251,12 @@ class VariableNameVisitor : public ShaderVariableVisitor ...@@ -243,11 +251,12 @@ class VariableNameVisitor : public ShaderVariableVisitor
const std::string &name, const std::string &name,
const std::string &mappedName) = 0; const std::string &mappedName) = 0;
std::string collapseNameStack() const;
std::string collapseMappedNameStack() const;
private: private:
void visitSampler(const sh::ShaderVariable &sampler) final; void visitSampler(const sh::ShaderVariable &sampler) final;
void visitVariable(const ShaderVariable &variable, bool isRowMajor) final; void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
std::string collapseNameStack() const;
std::string collapseMappedNameStack() const;
std::vector<std::string> mNameStack; std::vector<std::string> mNameStack;
std::vector<std::string> mMappedNameStack; std::vector<std::string> mMappedNameStack;
...@@ -261,8 +270,8 @@ class BlockEncoderVisitor : public VariableNameVisitor ...@@ -261,8 +270,8 @@ class BlockEncoderVisitor : public VariableNameVisitor
BlockLayoutEncoder *encoder); BlockLayoutEncoder *encoder);
~BlockEncoderVisitor(); ~BlockEncoderVisitor();
void enterStructAccess(const ShaderVariable &structVar) override; void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
void exitStructAccess(const ShaderVariable &structVar) override; void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
void visitNamedVariable(const ShaderVariable &variable, void visitNamedVariable(const ShaderVariable &variable,
bool isRowMajor, bool isRowMajor,
......
...@@ -19,12 +19,12 @@ HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool trans ...@@ -19,12 +19,12 @@ HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool trans
: mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices) : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
{} {}
void HLSLBlockEncoder::enterAggregateType() void HLSLBlockEncoder::enterAggregateType(const ShaderVariable &structVar)
{ {
nextRegister(); align(kComponentsPerRegister);
} }
void HLSLBlockEncoder::exitAggregateType() {} void HLSLBlockEncoder::exitAggregateType(const ShaderVariable &structVar) {}
void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
const std::vector<unsigned int> &arraySizes, const std::vector<unsigned int> &arraySizes,
...@@ -45,7 +45,7 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, ...@@ -45,7 +45,7 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
// register // register
if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty()) if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
{ {
nextRegister(); align(kComponentsPerRegister);
} }
if (gl::IsMatrixType(type)) if (gl::IsMatrixType(type))
...@@ -67,7 +67,7 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, ...@@ -67,7 +67,7 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
int numComponents = gl::VariableComponentCount(type); int numComponents = gl::VariableComponentCount(type);
if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister) if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister)
{ {
nextRegister(); align(kComponentsPerRegister);
} }
} }
...@@ -134,14 +134,14 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder * ...@@ -134,14 +134,14 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *
{ {
for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++) for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
{ {
encoder->enterAggregateType(); encoder->enterAggregateType(variable);
for (size_t fieldIndex = 0; fieldIndex < variable.fields.size(); fieldIndex++) for (const ShaderVariable &field : variable.fields)
{ {
HLSLVariableRegisterCount(variable.fields[fieldIndex], encoder); HLSLVariableRegisterCount(field, encoder);
} }
encoder->exitAggregateType(); encoder->exitAggregateType(variable);
} }
} }
else else
...@@ -157,7 +157,7 @@ unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput o ...@@ -157,7 +157,7 @@ unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput o
HLSLVariableRegisterCount(variable, &encoder); HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister); const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister);
return static_cast<unsigned int>(rx::roundUp<size_t>(encoder.getBlockSize(), registerBytes) / return static_cast<unsigned int>(
registerBytes); rx::roundUp<size_t>(encoder.getCurrentOffset(), registerBytes) / registerBytes);
} }
} // namespace sh } // namespace sh
...@@ -35,8 +35,8 @@ class HLSLBlockEncoder : public BlockLayoutEncoder ...@@ -35,8 +35,8 @@ class HLSLBlockEncoder : public BlockLayoutEncoder
HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices); HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices);
void enterAggregateType() override; void enterAggregateType(const ShaderVariable &structVar) override;
void exitAggregateType() override; void exitAggregateType(const ShaderVariable &structVar) override;
void skipRegisters(unsigned int numRegisters); void skipRegisters(unsigned int numRegisters);
bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; } bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
......
...@@ -350,16 +350,16 @@ class ShaderStorageBlockVisitor : public sh::VariableNameVisitor ...@@ -350,16 +350,16 @@ class ShaderStorageBlockVisitor : public sh::VariableNameVisitor
sh::VariableNameVisitor::exitArrayElement(arrayVar, arrayElement); sh::VariableNameVisitor::exitArrayElement(arrayVar, arrayElement);
} }
void enterStructAccess(const sh::ShaderVariable &structVar) override void enterStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
{ {
mStructStackSize++; mStructStackSize++;
sh::VariableNameVisitor::enterStructAccess(structVar); sh::VariableNameVisitor::enterStructAccess(structVar, isRowMajor);
} }
void exitStructAccess(const sh::ShaderVariable &structVar) override void exitStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
{ {
mStructStackSize--; mStructStackSize--;
sh::VariableNameVisitor::exitStructAccess(structVar); sh::VariableNameVisitor::exitStructAccess(structVar, isRowMajor);
} }
void visitNamedVariable(const sh::ShaderVariable &variable, void visitNamedVariable(const sh::ShaderVariable &variable,
...@@ -560,16 +560,16 @@ class FlattenUniformVisitor : public sh::VariableNameVisitor ...@@ -560,16 +560,16 @@ class FlattenUniformVisitor : public sh::VariableNameVisitor
} }
} }
void enterStructAccess(const sh::ShaderVariable &structVar) override void enterStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
{ {
mStructStackSize++; mStructStackSize++;
sh::VariableNameVisitor::enterStructAccess(structVar); sh::VariableNameVisitor::enterStructAccess(structVar, isRowMajor);
} }
void exitStructAccess(const sh::ShaderVariable &structVar) override void exitStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
{ {
mStructStackSize--; mStructStackSize--;
sh::VariableNameVisitor::exitStructAccess(structVar); sh::VariableNameVisitor::exitStructAccess(structVar, isRowMajor);
} }
ShaderUniformCount getCounts() const { return mUniformCount; } ShaderUniformCount getCounts() const { return mUniformCount; }
......
...@@ -210,7 +210,7 @@ size_t InterfaceBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock ...@@ -210,7 +210,7 @@ size_t InterfaceBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock
sh::GetInterfaceBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, sh::GetInterfaceBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
&mBlockLayout); &mBlockLayout);
return encoder->getBlockSize(); return encoder->getCurrentOffset();
} }
bool InterfaceBlockInfo::getBlockSize(const std::string &name, bool InterfaceBlockInfo::getBlockSize(const std::string &name,
......
...@@ -40,7 +40,7 @@ void InitDefaultUniformBlock(const std::vector<sh::Uniform> &uniforms, ...@@ -40,7 +40,7 @@ void InitDefaultUniformBlock(const std::vector<sh::Uniform> &uniforms,
sh::Std140BlockEncoder blockEncoder; sh::Std140BlockEncoder blockEncoder;
sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut); sh::GetUniformBlockInfo(uniforms, "", &blockEncoder, blockLayoutMapOut);
size_t blockSize = blockEncoder.getBlockSize(); size_t blockSize = blockEncoder.getCurrentOffset();
// TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized. // TODO(jmadill): I think we still need a valid block for the pipeline even if zero sized.
if (blockSize == 0) if (blockSize == 0)
......
...@@ -93,15 +93,18 @@ class ShaderStorageBufferTest31 : public ANGLETest ...@@ -93,15 +93,18 @@ class ShaderStorageBufferTest31 : public ANGLETest
const GLfloat *ptr = reinterpret_cast<const GLfloat *>( const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0,
matrixCase.mRows * matrixCase.mMatrixStride, GL_MAP_READ_BIT)); matrixCase.mRows * matrixCase.mMatrixStride, GL_MAP_READ_BIT));
for (unsigned int idx = 0; idx < matrixCase.mRows; idx++)
for (unsigned int row = 0; row < matrixCase.mRows; row++)
{ {
for (unsigned int idy = 0; idy < matrixCase.mColumns; idy++) for (unsigned int col = 0; col < matrixCase.mColumns; col++)
{ {
EXPECT_EQ(matrixCase.mInputdata[idx * (matrixCase.mMatrixStride / GLfloat expected = matrixCase.mInputdata[row * (matrixCase.mMatrixStride /
matrixCase.kBytesPerComponent) + matrixCase.kBytesPerComponent) +
idy], col];
*(ptr + idx * (matrixCase.mMatrixStride / matrixCase.kBytesPerComponent) + GLfloat actual =
idy)); *(ptr + row * (matrixCase.mMatrixStride / matrixCase.kBytesPerComponent) + col);
EXPECT_EQ(expected, actual) << " at row " << row << " and column " << col;
} }
} }
......
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