Commit c9e6026c by Kenneth Russell

Revert "Add workaround for unused std140 and shared uniform blocks on MacOS"

This reverts commit 9aa83fe3. The new test UniformBufferTest.ActiveUniformNumberAndName/ES3_OPENGL is failing on multiple platforms. Examples: https://build.chromium.org/p/chromium.gpu.fyi/builders/Mac%2010.10%20Release%20%28ATI%29/builds/12285 https://build.chromium.org/p/chromium.gpu.fyi/builders/Linux%20Release%20(ATI) Change-Id: I78b1a4d58e9a291e40ad304eb32f990e0518f7ee Reviewed-on: https://chromium-review.googlesource.com/391049Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org>
parent 5dc37d05
......@@ -64,10 +64,6 @@ Intel Corporation
Andy Chen
Josh Triplett
Sudarsana Nagineni
Jiajia Qin
Jiawei Shao
Jie Chen
Qiankun Miao
Klarälvdalens Datakonsult AB
Milian Wolff
......
......@@ -49,7 +49,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 163
#define ANGLE_SH_VERSION 162
typedef enum {
SH_GLES2_SPEC,
......@@ -208,14 +208,6 @@ const ShCompileOptions SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR = UINT64_C(1) <<
// It works by using an expression to emulate this function.
const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27;
// This flag will use all uniforms of unused std140 and shared uniform blocks at the
// beginning of the vertex/fragment shader's main(). It is intended as a workaround for Mac
// drivers with shader version 4.10. In those drivers, they will treat unused
// std140 and shared uniform blocks' members as inactive. However, WebGL2.0 based on
// OpenGL ES3.0.4 requires all members of a named uniform block declared with a shared or std140
// layout qualifier to be considered active. The uniform block itself is also considered active.
const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
// Defines alternate strategies for implementing array index clamping.
typedef enum {
// Use the clamp intrinsic for array index clamping.
......
......@@ -110,8 +110,6 @@
'compiler/translator/Types.h',
'compiler/translator/UnfoldShortCircuitAST.cpp',
'compiler/translator/UnfoldShortCircuitAST.h',
'compiler/translator/UseInterfaceBlockFields.cpp',
'compiler/translator/UseInterfaceBlockFields.h',
'compiler/translator/ValidateGlobalInitializer.cpp',
'compiler/translator/ValidateGlobalInitializer.h',
'compiler/translator/ValidateLimitations.cpp',
......
......@@ -26,7 +26,6 @@
#include "compiler/translator/RewriteDoWhile.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
#include "compiler/translator/UnfoldShortCircuitAST.h"
#include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/ValidateLimitations.h"
#include "compiler/translator/ValidateMaxParameters.h"
#include "compiler/translator/ValidateOutputs.h"
......@@ -392,10 +391,6 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && shouldCollectVariables(compileOptions))
{
collectVariables(root);
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
{
useAllMembersInUnusedStandardAndSharedBlocks(root);
}
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
{
success = enforcePackingRestrictions();
......@@ -858,22 +853,6 @@ void TCompiler::initializeGLPosition(TIntermNode* root)
InitializeVariables(root, list);
}
void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root)
{
sh::InterfaceBlockList list;
for (auto block : interfaceBlocks)
{
if (!block.staticUse &&
(block.layout == sh::BLOCKLAYOUT_STANDARD || block.layout == sh::BLOCKLAYOUT_SHARED))
{
list.push_back(block);
}
}
sh::UseInterfaceBlockFields(root, list);
}
void TCompiler::initializeOutputVariables(TIntermNode *root)
{
InitVariableList list;
......
......@@ -132,10 +132,6 @@ class TCompiler : public TShHandleBase
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
// Appendix A, section 7, the shader does not use too many uniforms.
bool enforcePackingRestrictions();
// Insert statements to reference all members in unused uniform blocks with standard and shared
// layout. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive.
void useAllMembersInUnusedStandardAndSharedBlocks(TIntermNode *root);
// Insert statements to initialize output variables in the beginning of main().
// This is to avoid undefined behaviors.
void initializeOutputVariables(TIntermNode *root);
......
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive.
#include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/util.h"
namespace sh
{
namespace
{
class UseUniformBlockMembers : public TIntermTraverser
{
public:
UseUniformBlockMembers(const InterfaceBlockList &blocks)
: TIntermTraverser(true, false, false), mBlocks(blocks), mCodeInserted(false)
{
}
protected:
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void insertUseCode(TIntermSequence *sequence);
void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence);
const InterfaceBlockList &mBlocks;
bool mCodeInserted;
};
bool UseUniformBlockMembers::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = !mCodeInserted;
switch (node->getOp())
{
case EOpSequence:
break;
case EOpFunction:
{
ASSERT(visit == PreVisit);
if (node->getName() == "main(")
{
TIntermSequence *sequence = node->getSequence();
ASSERT((sequence->size() == 1) || (sequence->size() == 2));
TIntermAggregate *body = nullptr;
if (sequence->size() == 1)
{
body = new TIntermAggregate(EOpSequence);
sequence->push_back(body);
}
else
{
body = (*sequence)[1]->getAsAggregate();
}
ASSERT(body);
insertUseCode(body->getSequence());
mCodeInserted = true;
visitChildren = false;
}
break;
}
default:
visitChildren = false;
break;
}
return visitChildren;
}
void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var,
TIntermSequence *sequence)
{
TString name = TString(var.name.c_str());
TType type = GetShaderVariableType(var);
if (var.isArray())
{
size_t pos = name.find_last_of('[');
if (pos != TString::npos)
{
name = name.substr(0, pos);
}
TType elementType = type;
elementType.clearArrayness();
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
for (unsigned int i = 0; i < var.arraySize; ++i)
{
TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, arraySymbol, TIntermTyped::CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
else if (var.isStruct())
{
TIntermSymbol *structSymbol = new TIntermSymbol(0, name, type);
for (unsigned int i = 0; i < var.fields.size(); ++i)
{
TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct, structSymbol,
TIntermTyped::CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
else
{
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
sequence->insert(sequence->begin(), symbol);
}
}
void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence)
{
for (const auto &block : mBlocks)
{
if (block.instanceName.empty())
{
for (const auto &var : block.fields)
{
AddFieldUseStatements(var, sequence);
}
}
else if (block.arraySize > 0)
{
TType type = GetInterfaceBlockType(block);
TString name = TString(block.instanceName.c_str());
TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
for (unsigned int i = 0; i < block.arraySize; ++i)
{
TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
TIntermTyped::CreateIndexNode(i));
for (unsigned int j = 0; j < block.fields.size(); ++j)
{
TIntermBinary *element =
new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
TIntermTyped::CreateIndexNode(j));
sequence->insert(sequence->begin(), element);
}
}
}
else
{
TType type = GetInterfaceBlockType(block);
TString name = TString(block.instanceName.c_str());
TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, type);
for (unsigned int i = 0; i < block.fields.size(); ++i)
{
TIntermBinary *element = new TIntermBinary(
EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
}
}
} // namespace anonymous
void UseInterfaceBlockFields(TIntermNode *root, const InterfaceBlockList &blocks)
{
UseUniformBlockMembers useUniformBlock(blocks);
root->traverse(&useUniformBlock);
}
} // namespace sh
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UseInterfaceBlockFields.h: insert statements to reference all members in InterfaceBlock list at
// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive.
#ifndef COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
#define COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
#include <GLSLANG/ShaderLang.h>
class TIntermNode;
namespace sh
{
using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
void UseInterfaceBlockFields(TIntermNode *root, const InterfaceBlockList &blocks);
} // namespace sh
#endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_
......@@ -278,38 +278,10 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
TType GetInterfaceBlockType(const sh::InterfaceBlock &block)
{
TType type;
TFieldList *fields = new TFieldList;
TSourceLoc loc;
for (const auto &field : block.fields)
{
TType *fieldType = new TType(GetShaderVariableType(field));
fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc));
}
TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
new TString(block.name.c_str()), fields, new TString(block.instanceName.c_str()),
block.arraySize, TLayoutQualifier::create());
type.setBasicType(EbtInterfaceBlock);
type.setInterfaceBlock(interfaceBlock);
return type;
}
TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
{
switch (var.type)
{
case GL_BOOL:
return TType(EbtBool);
case GL_BOOL_VEC2:
return TType(EbtBool, 2);
case GL_BOOL_VEC3:
return TType(EbtBool, 3);
case GL_BOOL_VEC4:
return TType(EbtBool, 4);
case GL_FLOAT:
return TType(EbtFloat);
case GL_FLOAT_VEC2:
......
......@@ -38,7 +38,6 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type);
TType GetInterfaceBlockType(const sh::InterfaceBlock &block);
TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
TType GetShaderVariableType(const sh::ShaderVariable &var);
......
......@@ -70,11 +70,6 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour
options |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
}
if (mWorkarounds.useUnusedBlocksWithStandardOrSharedLayout)
{
options |= SH_USE_UNUSED_STANDARD_SHARED_BLOCKS;
}
return options;
}
......
......@@ -24,8 +24,7 @@ struct WorkaroundsGL
unpackOverlappingRowsSeparatelyUnpackBuffer(false),
emulateAbsIntFunction(false),
addAndTrueToLoopCondition(false),
emulateIsnanFloat(false),
useUnusedBlocksWithStandardOrSharedLayout(false)
emulateIsnanFloat(false)
{
}
......@@ -106,11 +105,6 @@ struct WorkaroundsGL
// this bug, we use an expression to emulate function isnan().
// Tracking bug: http://crbug.com/650547
bool emulateIsnanFloat;
// On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be
// treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a
// unused std140 or shared uniform block at the beginning of main to work around it.
bool useUnusedBlocksWithStandardOrSharedLayout;
};
}
......
......@@ -897,7 +897,6 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
#if defined(ANGLE_PLATFORM_APPLE)
workarounds->doWhileGLSLCausesGPUHang = true;
workarounds->useUnusedBlocksWithStandardOrSharedLayout = true;
#endif
workarounds->finishDoesNotCauseQueriesToBeAvailable =
......
......@@ -5,7 +5,6 @@
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
......@@ -397,158 +396,6 @@ TEST_P(UniformBufferTest, ActiveUniformNames)
EXPECT_EQ("blockName.f", std::string(&strBuffer[0]));
}
// Tests active uniforms and blocks when the layout is std140, shared and packed.
TEST_P(UniformBufferTest, ActiveUniformNumberAndName)
{
// TODO(Jiajia): Figure out why this fails on Intel on Mac.
// This case can pass on Intel Mac-10.11/10.12. But it fails on Intel Mac-10.10.
if (IsIntel() && IsOSX())
{
std::cout << "Test skipped on Intel on Mac." << std::endl;
return;
}
if (IsAMD() && IsWindows())
{
std::cout << "Test skipped on AMD on Win." << std::endl;
return;
}
const std::string &vertexShaderSource =
"#version 300 es\n"
"in vec2 position;\n"
"out float v;\n"
"struct S {\n"
" highp ivec3 a;\n"
" mediump ivec2 b[4];\n"
"};\n"
"struct T {\n"
" S c[2];\n"
"};\n"
"layout(std140) uniform blockName0 {\n"
" S s0;\n"
" lowp vec2 v0;\n"
" T t0[2];\n"
" highp uint u0;\n"
"};\n"
"layout(std140) uniform blockName1 {\n"
" float f1;\n"
" bool b1;\n"
"} instanceName1;\n"
"layout(shared) uniform blockName2 {\n"
" float f2;\n"
"};\n"
"layout(packed) uniform blockName3 {\n"
" float f3;\n"
"};\n"
"void main() {\n"
" v = instanceName1.f1;\n"
" gl_Position = vec4(position, 0, 1);\n"
"}";
const std::string &fragmentShaderSource =
"#version 300 es\n"
"precision highp float;\n"
"in float v;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(v, 0, 0, 1);\n"
"}";
ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource);
GLint activeUniforms;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORMS, &activeUniforms);
ASSERT_EQ(15, activeUniforms);
GLint activeUniformBlocks;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks);
ASSERT_EQ(3, activeUniformBlocks);
GLint maxLength, size;
GLenum type;
GLsizei length;
glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
std::vector<GLchar> strBuffer(maxLength + 1, 0);
glGetActiveUniform(program.get(), 0, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("s0.a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 1, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("s0.b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 2, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("v0", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 3, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[0].c[0].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 4, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[0].c[0].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 5, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[0].c[1].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 6, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[0].c[1].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 7, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[1].c[0].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 8, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[1].c[0].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 9, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("t0[1].c[1].a", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 10, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(4, size);
EXPECT_EQ("t0[1].c[1].b[0]", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 11, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("u0", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 12, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.f1", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 13, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("blockName1.b1", std::string(&strBuffer[0]));
glGetActiveUniform(program.get(), 14, maxLength, &length, &size, &type, &strBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_EQ("f2", std::string(&strBuffer[0]));
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformBufferTest,
ES3_D3D11(),
......
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