Commit d93b9559 by Xinghua Cao Committed by Commit Bot

Translate uniform block with large matrix array to StructuredBuffer

There is a slow compiling issue if translate a uniform block with a large matrix array member to cbuffer, so translate the uniform block to StructuredBuffer. But pack_matrix pragma directive is invalid for matrix element of StructuredBuffer, so pack the matrix into a structure firstly, and then specifies packing alignment for the matrix in this structure, last the structure is used as StructuredBuffer element. Bug: angleproject:4206 Change-Id: I5a2a512e57b37dcdb88c3060d0d078b46f72eb5e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2154525 Commit-Queue: Xinghua Cao <xinghua.cao@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent 853a03f9
...@@ -86,28 +86,31 @@ bool IsInStd140UniformBlock(TIntermTyped *node) ...@@ -86,28 +86,31 @@ bool IsInStd140UniformBlock(TIntermTyped *node)
return false; return false;
} }
bool IsInstanceUniformBlock(TIntermTyped *node) const TInterfaceBlock *GetInterfaceBlockOfUniformBlockNearestIndexOperator(TIntermTyped *node)
{ {
TIntermBinary *binaryNode = node->getAsBinaryNode(); const TIntermBinary *binaryNode = node->getAsBinaryNode();
if (binaryNode) if (binaryNode)
{ {
return IsInstanceUniformBlock(binaryNode->getLeft()); if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{
return binaryNode->getLeft()->getType().getInterfaceBlock();
}
} }
const TVariable &variable = node->getAsSymbolNode()->variable(); const TIntermSymbol *symbolNode = node->getAsSymbolNode();
const TType &variableType = variable.getType(); if (symbolNode)
const TType &type = node->getType();
if (type.getQualifier() == EvqUniform)
{ {
// determine if it is instance uniform block. const TVariable &variable = symbolNode->variable();
const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); const TType &variableType = variable.getType();
return interfaceBlock && variableType.isInterfaceBlock();
if (variableType.getQualifier() == EvqUniform &&
variable.symbolType() == SymbolType::UserDefined)
{
return variableType.getInterfaceBlock();
}
} }
return false; return nullptr;
} }
const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op) const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op)
...@@ -1634,6 +1637,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1634,6 +1637,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
else else
{ {
outputTriplet(out, visit, "", "[", "]"); outputTriplet(out, visit, "", "[", "]");
if (visit == PostVisit)
{
const TInterfaceBlock *interfaceBlock =
GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
if (interfaceBlock &&
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock))
{
const TField *field = interfaceBlock->fields()[0];
if (field->type()->isMatrix())
{
out << "._matrix_" << Decorate(field->name());
}
}
}
} }
} }
break; break;
...@@ -1650,6 +1668,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1650,6 +1668,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
else else
{ {
outputTriplet(out, visit, "", "[", "]"); outputTriplet(out, visit, "", "[", "]");
if (visit == PostVisit)
{
const TInterfaceBlock *interfaceBlock =
GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
if (interfaceBlock &&
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock))
{
const TField *field = interfaceBlock->fields()[0];
if (field->type()->isMatrix())
{
out << "._matrix_" << Decorate(field->name());
}
}
}
} }
break; break;
} }
...@@ -1707,11 +1740,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1707,11 +1740,8 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
node->getLeft()->getType().getInterfaceBlock(); node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)]; const TField *field = interfaceBlock->fields()[index->getIConst(0)];
bool instanceUniformBlock = IsInstanceUniformBlock(node->getLeft());
if (structInStd140UniformBlock || if (structInStd140UniformBlock ||
(instanceUniformBlock && mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
mResourcesHLSL->shouldTranslateUniformBlockToStructuredBuffer(
*interfaceBlock)))
{ {
out << "_"; out << "_";
} }
...@@ -3621,5 +3651,4 @@ const char *OutputHLSL::generateOutputCall() const ...@@ -3621,5 +3651,4 @@ const char *OutputHLSL::generateOutputCall() const
return "generateOutput()"; return "generateOutput()";
} }
} }
} // namespace sh } // namespace sh
...@@ -779,7 +779,17 @@ TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString( ...@@ -779,7 +779,17 @@ TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString(
const TField &field = *interfaceBlock.fields()[0]; const TField &field = *interfaceBlock.fields()[0];
const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
typeString = InterfaceBlockFieldTypeString(field, blockStorage, true); typeString = InterfaceBlockFieldTypeString(field, blockStorage, true);
const TType &fieldType = *field.type();
if (fieldType.isMatrix())
{
if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
{
hlsl += "struct matrix" + Decorate(field.name()) + " { " + typeString + " _matrix_" +
Decorate(field.name()) + "; };\n";
}
typeString = "matrix" + Decorate(field.name());
}
if (instanceVariable != nullptr) if (instanceVariable != nullptr)
{ {
...@@ -879,11 +889,10 @@ bool ResourcesHLSL::shouldTranslateUniformBlockToStructuredBuffer( ...@@ -879,11 +889,10 @@ bool ResourcesHLSL::shouldTranslateUniformBlockToStructuredBuffer(
{ {
const TType &fieldType = *interfaceBlock.fields()[0]->type(); const TType &fieldType = *interfaceBlock.fields()[0]->type();
// TODO(anglebug.com/4206): Support uniform block contains only a matrix array member,
// and fix row-major/column-major conversion issue.
return (mCompileOptions & SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER) == 0 && return (mCompileOptions & SH_DONT_TRANSLATE_UNIFORM_BLOCK_TO_STRUCTUREDBUFFER) == 0 &&
mSRVRegister < kMaxInputResourceSlotCount && interfaceBlock.fields().size() == 1u && mSRVRegister < kMaxInputResourceSlotCount && interfaceBlock.fields().size() == 1u &&
fieldType.getStruct() != nullptr && fieldType.getNumArraySizes() == 1u && (fieldType.getStruct() != nullptr || fieldType.isMatrix()) &&
fieldType.getNumArraySizes() == 1u &&
fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer; fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer;
} }
} // namespace sh } // namespace sh
...@@ -2517,6 +2517,408 @@ TEST_P(UniformBufferTest, UniformBlocksSharedSameUniformBuffer) ...@@ -2517,6 +2517,408 @@ TEST_P(UniformBufferTest, UniformBlocksSharedSameUniformBuffer)
} }
} }
// Compile uniform buffer with a large matrix array member.
TEST_P(UniformBufferTest, UniformBlockWithOneLargeMatrixArrayIndexAccess)
{
GLint64 maxUniformBlockSize;
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
std::ostringstream stream;
// Ensure that shader uniform block do not exceed MAX_UNIFORM_BLOCK_SIZE limit.
if (maxUniformBlockSize < 16384)
{
return;
}
const char *kFS = R"(#version 300 es
precision mediump float;
uniform uint index;
struct S { uvec4 idx; };
layout(std140) uniform idxbuf { S idxArray[2]; };
layout(std140) uniform buffer1 { mat4 s1[128]; };
layout(std140) uniform buffer2 { mat4 s2[128]; } buf2[2];
out vec4 fragColor;
void main()
{
fragColor = s1[1][0] + s1[index][1] + s1[idxArray[0].idx.x][idxArray[1].idx.z]
+ buf2[0].s2[1][0] + buf2[1].s2[index][1] + buf2[0].s2[idxArray[0].idx.y][idxArray[1].idx.z]
+ vec4(buf2[1].s2[index][1][index], s1[1][0][2], s1[idxArray[0].idx.x][idxArray[1].idx.z][2],
buf2[0].s2[idxArray[0].idx.y][idxArray[1].idx.z][3]);
})";
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
ASSERT_GL_NO_ERROR();
}
// Test uniform buffer with a large matrix array member.
TEST_P(UniformBufferTest, UniformBlockWithOneLargeMatrixArray)
{
GLint64 maxUniformBlockSize;
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
std::ostringstream stream;
GLuint arraySize;
// Ensure that shader uniform block do not exceed MAX_UNIFORM_BLOCK_SIZE limit.
if (maxUniformBlockSize >= 16384 && maxUniformBlockSize < 32768)
{
arraySize = 128;
stream << "const uint arraySize = 128u;\n"
"const uint divisor1 = 128u;\n"
"const uint divisor2 = 32u;\n";
}
else if (maxUniformBlockSize >= 32768 && maxUniformBlockSize < 65536)
{
arraySize = 256;
stream << "const uint arraySize = 256u;\n"
"const uint divisor1 = 64u;\n"
"const uint divisor2 = 16u;\n";
}
else
{
arraySize = 512;
stream << "const uint arraySize = 512u;\n"
"const uint divisor1 = 32u;\n"
"const uint divisor2 = 8u;\n";
}
const std::string &kFS =
"#version 300 es\n"
"precision highp float;\n" +
stream.str() +
"out vec4 my_FragColor;\n"
"layout(std140) uniform buffer { mat4 s[arraySize]; };\n"
"void main()\n"
"{\n"
" uvec2 coord = uvec2(floor(gl_FragCoord.xy));\n"
" uint index = coord.x + coord.y * 128u;\n"
" uint index_x = index / divisor1;\n"
" uint index_y = (index % divisor1) / divisor2;\n"
" my_FragColor = s[index_x][index_y];\n"
"}\n";
GLint blockSize;
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS.c_str());
GLint uniformBufferIndex = glGetUniformBlockIndex(program, "buffer");
glGetActiveUniformBlockiv(program, uniformBufferIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
glUniformBlockBinding(program, uniformBufferIndex, 0);
const GLuint kVectorPerMat = 4;
const GLuint kFloatPerVector = 4;
GLuint kVectorCount = arraySize * kVectorPerMat;
GLuint kFloatCount = kVectorCount * kFloatPerVector;
std::vector<GLfloat> floatData(kFloatCount, 0.0f);
const GLuint kPositionCount = 12;
unsigned int positionToTest[kPositionCount][2] = {{0, 0}, {75, 0}, {98, 13}, {31, 31},
{0, 32}, {65, 33}, {23, 54}, {63, 63},
{0, 64}, {43, 86}, {53, 100}, {127, 127}};
for (GLuint i = 0; i < kVectorCount; i++)
{
floatData[4 * i + 2] = 1.0f;
floatData[4 * i + 3] = 1.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::blue);
}
for (GLuint i = 0; i < kVectorCount; i++)
{
floatData[4 * i + 1] = 1.0f;
floatData[4 * i + 2] = 0.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::green);
}
for (GLuint i = kVectorCount / 4; i < kVectorCount / 2; i++)
{
floatData[4 * i] = 1.0f;
floatData[4 * i + 1] = 0.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
if (positionToTest[i][1] > 31 && positionToTest[i][1] < 64)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::red);
}
else
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::green);
}
}
}
// Test uniform buffer with a large matrix array member, which using row major qualifier.
TEST_P(UniformBufferTest, UniformBlockWithOneLargeMatrixArrayWithRowMajorQualifier)
{
// http://anglebug.com/3837 , http://anglebug.com/2273
ANGLE_SKIP_TEST_IF(IsOSX() || IsAndroid() || (IsAMD() && IsOpenGL()) ||
(IsLinux() && IsIntel() && IsOpenGL()));
GLint64 maxUniformBlockSize;
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
std::ostringstream stream;
GLuint arraySize;
// Ensure that shader uniform block do not exceed MAX_UNIFORM_BLOCK_SIZE limit.
if (maxUniformBlockSize >= 16384 && maxUniformBlockSize < 32768)
{
arraySize = 128;
stream << "const uint arraySize = 128u;\n"
"const uint divisor1 = 128u;\n"
"const uint divisor2 = 32u;\n";
}
else if (maxUniformBlockSize >= 32768 && maxUniformBlockSize < 65536)
{
arraySize = 256;
stream << "const uint arraySize = 256u;\n"
"const uint divisor1 = 64u;\n"
"const uint divisor2 = 16u;\n";
}
else
{
arraySize = 512;
stream << "const uint arraySize = 512u;\n"
"const uint divisor1 = 32u;\n"
"const uint divisor2 = 8u;\n";
}
const std::string &kFS =
"#version 300 es\n"
"precision highp float;\n" +
stream.str() +
"out vec4 my_FragColor;\n"
"layout(std140, row_major) uniform buffer { mat4 s[arraySize]; };\n"
"void main()\n"
"{\n"
" uvec2 coord = uvec2(floor(gl_FragCoord.xy));\n"
" uint index = coord.x + coord.y * 128u;\n"
" uint index_x = index / divisor1;\n"
" uint index_y = (index % divisor1) / divisor2;\n"
" my_FragColor = s[index_x][index_y];\n"
"}\n";
GLint blockSize;
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS.c_str());
GLint uniformBufferIndex = glGetUniformBlockIndex(program, "buffer");
glGetActiveUniformBlockiv(program, uniformBufferIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
glUniformBlockBinding(program, uniformBufferIndex, 0);
const GLuint kVectorPerMat = 4;
const GLuint kFloatPerVector = 4;
GLuint kVectorCount = arraySize * kVectorPerMat;
GLuint kFloatCount = kVectorCount * kFloatPerVector;
std::vector<GLfloat> floatData(kFloatCount, 0.0f);
const GLuint kPositionCount = 12;
unsigned int positionToTest[kPositionCount][2] = {{0, 0}, {75, 0}, {98, 13}, {31, 31},
{0, 32}, {65, 33}, {23, 54}, {63, 63},
{0, 64}, {43, 86}, {53, 100}, {127, 127}};
for (GLuint i = 0; i < kVectorCount / 4; i++)
{
for (GLuint j = 0; j < 4; j++)
{
floatData[16 * i + 8 + j] = 1.0f;
floatData[16 * i + 12 + j] = 1.0f;
}
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::blue);
}
for (GLuint i = 0; i < kVectorCount / 4; i++)
{
for (GLuint j = 0; j < 4; j++)
{
floatData[16 * i + 4 + j] = 1.0f;
floatData[16 * i + 8 + j] = 0.0f;
}
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::green);
}
for (GLuint i = kVectorCount / 16; i < kVectorCount / 8; i++)
{
for (GLuint j = 0; j < 4; j++)
{
floatData[16 * i + j] = 1.0f;
floatData[16 * i + 4 + j] = 0.0f;
}
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
if (positionToTest[i][1] > 31 && positionToTest[i][1] < 64)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::red);
}
else
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::green);
}
}
}
// Test instance array uniform buffer with a large matrix array member.
TEST_P(UniformBufferTest, InstanceArrayUniformBlockWithOneLargeMatrixArray)
{
GLint64 maxUniformBlockSize;
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize);
std::ostringstream stream;
GLuint arraySize;
// Ensure that shader uniform block do not exceed MAX_UNIFORM_BLOCK_SIZE limit.
if (maxUniformBlockSize >= 16384 && maxUniformBlockSize < 32768)
{
arraySize = 128;
stream << "const uint arraySize = 128u;\n"
"const uint divisor1 = 128u;\n"
"const uint divisor2 = 32u;\n";
}
else if (maxUniformBlockSize >= 32768 && maxUniformBlockSize < 65536)
{
arraySize = 256;
stream << "const uint arraySize = 256u;\n"
"const uint divisor1 = 64u;\n"
"const uint divisor2 = 16u;\n";
}
else
{
arraySize = 512;
stream << "const uint arraySize = 512u;\n"
"const uint divisor1 = 32u;\n"
"const uint divisor2 = 8u;\n";
}
const std::string &kFS =
"#version 300 es\n"
"precision highp float;\n" +
stream.str() +
"out vec4 my_FragColor;\n"
"layout(std140) uniform buffer { mat4 s[arraySize]; } instance[2];\n"
"void main()\n"
"{\n"
" uvec2 coord = uvec2(floor(gl_FragCoord.xy));\n"
" uint index = coord.x + coord.y * 128u;\n"
" uint index_x = index / divisor1;\n"
" uint index_y = (index % divisor1) / divisor2;\n"
" my_FragColor = instance[0].s[index_x][index_y] + "
"instance[1].s[index_x][index_y];\n"
"}\n";
GLint blockSize0, blockSize1;
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS.c_str());
GLint uniformBufferIndex0 = glGetUniformBlockIndex(program, "buffer[0]");
GLint uniformBufferIndex1 = glGetUniformBlockIndex(program, "buffer[1]");
glGetActiveUniformBlockiv(program, uniformBufferIndex0, GL_UNIFORM_BLOCK_DATA_SIZE,
&blockSize0);
glGetActiveUniformBlockiv(program, uniformBufferIndex1, GL_UNIFORM_BLOCK_DATA_SIZE,
&blockSize1);
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
glBufferData(GL_UNIFORM_BUFFER, blockSize0, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
glUniformBlockBinding(program, uniformBufferIndex0, 0);
const GLuint kVectorPerMat = 4;
const GLuint kFloatPerVector = 4;
GLuint kVectorCount = arraySize * kVectorPerMat;
GLuint kFloatCount = kVectorCount * kFloatPerVector;
std::vector<GLfloat> floatData0(kFloatCount, 0.0f);
std::vector<GLfloat> floatData1(kFloatCount, 0.0f);
const GLuint kPositionCount = 12;
unsigned int positionToTest[kPositionCount][2] = {{0, 0}, {75, 0}, {98, 13}, {31, 31},
{0, 32}, {65, 33}, {23, 54}, {63, 63},
{0, 64}, {43, 86}, {53, 100}, {127, 127}};
for (GLuint i = 0; i < kVectorCount; i++)
{
floatData0[4 * i + 2] = 1.0f;
floatData0[4 * i + 3] = 1.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData0.data());
GLBuffer uniformBuffer1;
glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer1);
glBufferData(GL_UNIFORM_BUFFER, blockSize1, nullptr, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, uniformBuffer1);
glUniformBlockBinding(program, uniformBufferIndex0, 1);
for (GLuint i = 0; i < kVectorCount; i++)
{
floatData1[4 * i + 1] = 1.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData1.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::cyan);
}
glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
for (GLuint i = 0; i < kVectorCount; i++)
{
floatData0[4 * i] = 1.0f;
floatData0[4 * i + 2] = 0.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData0.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::yellow);
}
glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer1);
for (GLuint i = kVectorCount / 4; i < kVectorCount / 2; i++)
{
floatData1[4 * i + 2] = 1.0f;
floatData1[4 * i + 1] = 0.0f;
}
glBufferSubData(GL_UNIFORM_BUFFER, 0, kFloatCount * sizeof(GLfloat), floatData1.data());
drawQuad(program.get(), essl3_shaders::PositionAttrib(), 0.5f);
for (GLuint i = 0; i < kPositionCount; i++)
{
if (positionToTest[i][1] > 31 && positionToTest[i][1] < 64)
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::magenta);
}
else
{
EXPECT_PIXEL_COLOR_EQ(positionToTest[i][0], positionToTest[i][1], GLColor::yellow);
}
}
}
// Test a uniform block where an array of row-major matrices is dynamically indexed. // Test a uniform block where an array of row-major matrices is dynamically indexed.
TEST_P(UniformBufferTest, Std140UniformBlockWithDynamicallyIndexedRowMajorArray) TEST_P(UniformBufferTest, Std140UniformBlockWithDynamicallyIndexedRowMajorArray)
{ {
......
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