Commit 4a9f9b08 by Qin Jiajia Committed by Commit Bot

ES31: support ssbo as the operand of unary operator

Bug: angleproject:1951 Change-Id: I71c2cf2ca35d7b1fe5d14358a0749f47e223816b Reviewed-on: https://chromium-review.googlesource.com/c/1367405Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jiajia Qin <jiajia.qin@intel.com>
parent bec39877
......@@ -22,6 +22,21 @@ namespace sh
{
namespace
{
bool IsIncrementOrDecrementOperator(TOperator op)
{
switch (op)
{
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
return true;
default:
return false;
}
}
bool IsCompoundAssignment(TOperator op)
{
switch (op)
......@@ -106,6 +121,8 @@ class RewriteExpressionsWithShaderStorageBlockTraverser : public TIntermTraverse
private:
bool visitBinary(Visit, TIntermBinary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitUnary(Visit visit, TIntermUnary *node) override;
TIntermSymbol *insertInitStatementAndReturnTempSymbol(TIntermTyped *node,
TIntermSequence *insertions);
......@@ -313,6 +330,64 @@ bool RewriteExpressionsWithShaderStorageBlockTraverser::visitAggregate(Visit vis
return false;
}
bool RewriteExpressionsWithShaderStorageBlockTraverser::visitUnary(Visit visit, TIntermUnary *node)
{
if (mFoundSSBO)
{
return false;
}
if (!IsInShaderStorageBlock(node->getOperand()))
{
return true;
}
// .length() is processed in OutputHLSL.
if (node->getOp() == EOpArrayLength)
{
return true;
}
mFoundSSBO = true;
// case 4: ssbo as the operand of ++/--
// original:
// ++ssbo * expr;
// new:
// var temp1 = ssbo;
// var temp2 = ++temp1;
// ssbo = temp1;
// temp2 * expr;
if (IsIncrementOrDecrementOperator(node->getOp()))
{
TIntermSequence insertions;
TIntermSymbol *temp1 =
insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
TIntermUnary *newUnary = new TIntermUnary(node->getOp(), temp1->deepCopy(), nullptr);
TIntermSymbol *temp2 = insertInitStatementAndReturnTempSymbol(newUnary, &insertions);
TIntermBinary *readBackToSSBO =
new TIntermBinary(EOpAssign, node->getOperand()->deepCopy(), temp1->deepCopy());
insertions.push_back(readBackToSSBO);
insertStatementsInParentBlock(insertions);
queueReplacement(temp2->deepCopy(), OriginalNode::IS_DROPPED);
}
// case 5: ssbo as the operand of readonly unary operator
// original:
// ~ssbo * expr;
// new:
// var temp = ssbo;
// ~temp * expr;
else
{
TIntermSequence insertions;
TIntermSymbol *temp =
insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
insertStatementsInParentBlock(insertions);
node->replaceChildNode(node->getOperand(), temp->deepCopy());
}
return false;
}
void RewriteExpressionsWithShaderStorageBlockTraverser::nextIteration()
{
mFoundSSBO = false;
......
......@@ -1783,6 +1783,56 @@ void main(void)
EXPECT_GL_NO_ERROR();
}
// Test that ssbo as unary operand works well.
TEST_P(ShaderStorageBufferTest31, SSBOAsUnaryOperand)
{
// http://anglebug.com/2990
ANGLE_SKIP_TEST_IF(IsD3D11());
constexpr char kComputeShaderSource[] =
R"(#version 310 es
layout (local_size_x=1) in;
layout(binding=0, std140) buffer Storage0
{
uint b;
} sb_load;
layout(binding=1, std140) buffer Storage1
{
uint i;
} sb_store;
void main()
{
sb_store.i = +sb_load.b;
++sb_store.i;
}
)";
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
glUseProgram(program);
constexpr unsigned int kBytesPerComponent = sizeof(unsigned int);
constexpr unsigned kInputValue = 1u;
constexpr unsigned int kExpectedValue = 2u;
GLBuffer shaderStorageBuffer[2];
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[0]);
glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
glBufferData(GL_SHADER_STORAGE_BUFFER, kBytesPerComponent, &kInputValue, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBuffer[0]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, shaderStorageBuffer[1]);
glDispatchCompute(1, 1, 1);
glFinish();
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBuffer[1]);
const GLuint *ptr = reinterpret_cast<const GLuint *>(
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBytesPerComponent, GL_MAP_READ_BIT));
EXPECT_EQ(kExpectedValue, *ptr);
EXPECT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST(ShaderStorageBufferTest31, ES31_OPENGL(), ES31_OPENGLES(), ES31_D3D11());
} // 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