зеркало из https://github.com/AvaloniaUI/angle.git
ES31: Fix some bugs in ShaderStorageBlockOutputHLSL
When EOpIndexDirect/EOpIndexIndirect/EOpIndexDirectStruct/TIntermSwizzle appear in [] in ssbo access chain, we should transfer the process of them to OutputHLSL. For example: instance.v[gl_GlobalInvocationID.x] = data; // becomes float_Store(dx_instance, 0 + 16 * gl_GlobalInvocationID.x, _data); instance.v[s.index[0].x] = data; // becomes float_Store(dx_instance, 0 + 16 * _s.index[0].x, _data); Bug: angleproject:1951 Change-Id: I333e238400a10a799a6294f8759cf9c4ef2451c8 Reviewed-on: https://chromium-review.googlesource.com/c/1250661 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Jiajia Qin <jiajia.qin@intel.com>
This commit is contained in:
Родитель
19b51d2983
Коммит
6d765b07f8
|
@ -227,9 +227,14 @@ void ShaderStorageBlockOutputHLSL::visitConstantUnion(TIntermConstantUnion *node
|
||||||
|
|
||||||
bool ShaderStorageBlockOutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node)
|
bool ShaderStorageBlockOutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node)
|
||||||
{
|
{
|
||||||
TInfoSinkBase &out = mOutputHLSL->getInfoSink();
|
|
||||||
if (visit == PostVisit)
|
if (visit == PostVisit)
|
||||||
{
|
{
|
||||||
|
if (!IsInShaderStorageBlock(node))
|
||||||
|
{
|
||||||
|
return mOutputHLSL->visitSwizzle(visit, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
TInfoSinkBase &out = mOutputHLSL->getInfoSink();
|
||||||
// TODO(jiajia.qin@intel.com): add swizzle process.
|
// TODO(jiajia.qin@intel.com): add swizzle process.
|
||||||
if (mIsLoadFunctionCall)
|
if (mIsLoadFunctionCall)
|
||||||
{
|
{
|
||||||
|
@ -247,6 +252,11 @@ bool ShaderStorageBlockOutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
||||||
{
|
{
|
||||||
case EOpIndexDirect:
|
case EOpIndexDirect:
|
||||||
{
|
{
|
||||||
|
if (!IsInShaderStorageBlock(node->getLeft()))
|
||||||
|
{
|
||||||
|
return mOutputHLSL->visitBinary(visit, node);
|
||||||
|
}
|
||||||
|
|
||||||
const TType &leftType = node->getLeft()->getType();
|
const TType &leftType = node->getLeft()->getType();
|
||||||
if (leftType.isInterfaceBlock())
|
if (leftType.isInterfaceBlock())
|
||||||
{
|
{
|
||||||
|
@ -276,21 +286,36 @@ bool ShaderStorageBlockOutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOpIndexIndirect:
|
case EOpIndexIndirect:
|
||||||
|
{
|
||||||
|
if (!IsInShaderStorageBlock(node->getLeft()))
|
||||||
|
{
|
||||||
|
return mOutputHLSL->visitBinary(visit, node);
|
||||||
|
}
|
||||||
|
|
||||||
// We do not currently support indirect references to interface blocks
|
// We do not currently support indirect references to interface blocks
|
||||||
ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
|
ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
|
||||||
writeEOpIndexDirectOrIndirectOutput(out, visit, node);
|
writeEOpIndexDirectOrIndirectOutput(out, visit, node);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
|
{
|
||||||
|
if (!IsInShaderStorageBlock(node->getLeft()))
|
||||||
|
{
|
||||||
|
return mOutputHLSL->visitBinary(visit, node);
|
||||||
|
}
|
||||||
|
|
||||||
if (visit == InVisit)
|
if (visit == InVisit)
|
||||||
{
|
{
|
||||||
ASSERT(IsInShaderStorageBlock(node->getLeft()));
|
ASSERT(IsInShaderStorageBlock(node->getLeft()));
|
||||||
const TStructure *structure = node->getLeft()->getType().getStruct();
|
const TStructure *structure = node->getLeft()->getType().getStruct();
|
||||||
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
|
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
|
||||||
const TField *field = structure->fields()[index->getIConst(0)];
|
const TField *field = structure->fields()[index->getIConst(0)];
|
||||||
|
out << " + ";
|
||||||
writeDotOperatorOutput(out, field);
|
writeDotOperatorOutput(out, field);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case EOpIndexDirectInterfaceBlock:
|
case EOpIndexDirectInterfaceBlock:
|
||||||
if (visit == InVisit)
|
if (visit == InVisit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -762,6 +762,11 @@ bool IsInShaderStorageBlock(TIntermTyped *node)
|
||||||
{
|
{
|
||||||
return IsInShaderStorageBlock(binaryNode->getLeft());
|
return IsInShaderStorageBlock(binaryNode->getLeft());
|
||||||
}
|
}
|
||||||
|
TIntermSymbol *symbolNode = swizzleNode->getOperand()->getAsSymbolNode();
|
||||||
|
if (symbolNode)
|
||||||
|
{
|
||||||
|
return symbolNode->getQualifier() == EvqBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binaryNode = node->getAsBinaryNode();
|
binaryNode = node->getAsBinaryNode();
|
||||||
|
|
||||||
|
|
|
@ -2190,6 +2190,82 @@ TEST_P(ComputeShaderTest, ShaderStorageBlocksWithUnsizedArray)
|
||||||
EXPECT_GL_NO_ERROR();
|
EXPECT_GL_NO_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that EOpIndexDirect/EOpIndexIndirect/EOpIndexDirectStruct nodes in ssbo EOpIndexInDirect
|
||||||
|
// don't need to calculate the offset and should be translated by OutputHLSL directly.
|
||||||
|
TEST_P(ComputeShaderTest, IndexAndDotOperatorsInSSBOIndexIndirectOperator)
|
||||||
|
{
|
||||||
|
constexpr char kComputeShaderSource[] =
|
||||||
|
R"(#version 310 es
|
||||||
|
layout(local_size_x=1) in;
|
||||||
|
layout(std140, binding = 0) buffer blockA {
|
||||||
|
float v[4];
|
||||||
|
};
|
||||||
|
layout(std140, binding = 1) buffer blockB {
|
||||||
|
float v[4];
|
||||||
|
} instanceB[1];
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
uvec4 index[2];
|
||||||
|
} s;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
s.index[0] = uvec4(0u, 1u, 2u, 3u);
|
||||||
|
float data = v[s.index[0].y];
|
||||||
|
instanceB[0].v[s.index[0].x] = data;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
|
||||||
|
EXPECT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that swizzle node in non-SSBO symbol works well.
|
||||||
|
TEST_P(ComputeShaderTest, ShaderStorageBlocksWithNonSSBOSwizzle)
|
||||||
|
{
|
||||||
|
constexpr char kComputeShaderSource[] =
|
||||||
|
R"(#version 310 es
|
||||||
|
layout(local_size_x=8) in;
|
||||||
|
layout(std140, binding = 0) buffer blockA {
|
||||||
|
float v[8];
|
||||||
|
};
|
||||||
|
layout(std140, binding = 1) buffer blockB {
|
||||||
|
float v[8];
|
||||||
|
} instanceB[1];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float data = v[gl_GlobalInvocationID.x];
|
||||||
|
instanceB[0].v[gl_GlobalInvocationID.x] = data;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
|
||||||
|
EXPECT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that swizzle node in SSBO symbol works well.
|
||||||
|
TEST_P(ComputeShaderTest, ShaderStorageBlocksWithSSBOSwizzle)
|
||||||
|
{
|
||||||
|
constexpr char kComputeShaderSource[] =
|
||||||
|
R"(#version 310 es
|
||||||
|
layout(local_size_x=1) in;
|
||||||
|
layout(std140, binding = 0) buffer blockA {
|
||||||
|
vec2 v;
|
||||||
|
};
|
||||||
|
layout(std140, binding = 1) buffer blockB {
|
||||||
|
float v;
|
||||||
|
} instanceB[1];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
instanceB[0].v = v.x;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
|
||||||
|
EXPECT_GL_NO_ERROR();
|
||||||
|
}
|
||||||
|
|
||||||
// Check that it is not possible to create a compute shader when the context does not support ES
|
// Check that it is not possible to create a compute shader when the context does not support ES
|
||||||
// 3.10
|
// 3.10
|
||||||
TEST_P(ComputeShaderTestES3, NotSupported)
|
TEST_P(ComputeShaderTestES3, NotSupported)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче