Revert "Re-land "Move sampler validation to the GL layer.""
Build failure on Linux:
In file included from ../../third_party/angle/src/tests/gl_tests/UniformTest.cpp:7:
In file included from ../../third_party/angle/src/tests/test_utils/ANGLETest.h:10:
../../testing/gtest/include/gtest/gtest.h:1392:16: error: comparison of integers of different signs: 'const int' and 'const unsigned int' [-Werror,-Wsign-compare]
if (expected == actual) {
~~~~~~~~ ^ ~~~~~~
../../testing/gtest/include/gtest/gtest.h:1422:12: note: in instantiation of function template specialization 'testing::internal::CmpHelperEQ<int, unsigned int>' requested here
return CmpHelperEQ(expected_expression, actual_expression, expected,
^
../../third_party/angle/src/tests/gl_tests/UniformTest.cpp:487:5: note: in instantiation of function template specialization 'testing::internal::EqHelper<false>::Compare<int, unsigned int>' requested here
EXPECT_EQ(GL_SAMPLER_2D, type);
^
BUG=angleproject:1123
This reverts commit 6cbf4385280c4c1dd97f0882ecb18dbc4c341fd4.
Change-Id: I95279b37d253e3ea78faa53f3773f2dc3d17df95
Reviewed-on: https://chromium-review.googlesource.com/302030
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 14a50ba..6922adf 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -174,17 +174,6 @@
}
}
-bool UniformInList(const std::vector<LinkedUniform> &list, const std::string &name)
-{
- for (const LinkedUniform &uniform : list)
- {
- if (uniform.name == name)
- return true;
- }
-
- return false;
-}
-
} // anonymous namespace
AttributeBindings::AttributeBindings()
@@ -370,8 +359,7 @@
mDeleteStatus(false),
mRefCount(0),
mResourceManager(manager),
- mHandle(handle),
- mSamplerUniformRange(0, 0)
+ mHandle(handle)
{
ASSERT(mProgram);
@@ -686,15 +674,12 @@
{
int locationIndex = stream.readInt<int>();
VariableLocation locationData;
- stream.readInt(&locationData.element);
- stream.readInt(&locationData.index);
- stream.readString(&locationData.name);
+ locationData.element = stream.readInt<unsigned int>();
+ locationData.index = stream.readInt<unsigned int>();
+ locationData.name = stream.readString();
mData.mOutputVariables[locationIndex] = locationData;
}
- stream.readInt(&mSamplerUniformRange.start);
- stream.readInt(&mSamplerUniformRange.end);
-
rx::LinkResult result = mProgram->load(mInfoLog, &stream);
if (result.error.isError() || !result.linkSuccess)
{
@@ -784,9 +769,6 @@
stream.writeString(outputPair.second.name);
}
- stream.writeInt(mSamplerUniformRange.start);
- stream.writeInt(mSamplerUniformRange.end);
-
gl::Error error = mProgram->save(&stream);
if (error.isError())
{
@@ -1315,78 +1297,7 @@
bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
- // Skip cache if we're using an infolog, so we get the full error.
- // Also skip the cache if the sample mapping has changed, or if we haven't ever validated.
- if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
- {
- return mCachedValidateSamplersResult.value();
- }
-
- if (mTextureUnitTypesCache.empty())
- {
- mTextureUnitTypesCache.resize(caps.maxCombinedTextureImageUnits, GL_NONE);
- }
- else
- {
- std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE);
- }
-
- // if any two active samplers in a program are of different types, but refer to the same
- // texture image unit, and this is the current program, then ValidateProgram will fail, and
- // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
- for (unsigned int samplerIndex = mSamplerUniformRange.start;
- samplerIndex < mSamplerUniformRange.end; ++samplerIndex)
- {
- const LinkedUniform &uniform = mData.mUniforms[samplerIndex];
- ASSERT(uniform.isSampler());
-
- if (!uniform.staticUse)
- continue;
-
- const GLuint *dataPtr = reinterpret_cast<const GLuint *>(uniform.getDataPtrToElement(0));
- GLenum textureType = SamplerTypeToTextureType(uniform.type);
-
- for (unsigned int arrayElement = 0; arrayElement < uniform.elementCount(); ++arrayElement)
- {
- GLuint textureUnit = dataPtr[arrayElement];
-
- if (textureUnit >= caps.maxCombinedTextureImageUnits)
- {
- if (infoLog)
- {
- (*infoLog) << "Sampler uniform (" << textureUnit
- << ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
- << caps.maxCombinedTextureImageUnits << ")";
- }
-
- mCachedValidateSamplersResult = false;
- return false;
- }
-
- if (mTextureUnitTypesCache[textureUnit] != GL_NONE)
- {
- if (textureType != mTextureUnitTypesCache[textureUnit])
- {
- if (infoLog)
- {
- (*infoLog) << "Samplers of conflicting types refer to the same texture "
- "image unit ("
- << textureUnit << ").";
- }
-
- mCachedValidateSamplersResult = false;
- return false;
- }
- }
- else
- {
- mTextureUnitTypesCache[textureUnit] = textureType;
- }
- }
- }
-
- mCachedValidateSamplersResult = true;
- return true;
+ return mProgram->validateSamplers(infoLog, caps);
}
bool Program::isValidated() const
@@ -2175,13 +2086,11 @@
const gl::Shader *vertexShader = mData.getAttachedVertexShader();
VectorAndSamplerCount vsCounts;
- std::vector<LinkedUniform> samplerUniforms;
-
for (const sh::Uniform &uniform : vertexShader->getUniforms())
{
if (uniform.staticUse)
{
- vsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms);
+ vsCounts += flattenUniform(uniform, uniform.name);
}
}
@@ -2206,7 +2115,7 @@
{
if (uniform.staticUse)
{
- fsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms);
+ fsCounts += flattenUniform(uniform, uniform.name);
}
}
@@ -2224,18 +2133,11 @@
return false;
}
- mSamplerUniformRange.start = static_cast<unsigned int>(mData.mUniforms.size());
- mSamplerUniformRange.end =
- mSamplerUniformRange.start + static_cast<unsigned int>(samplerUniforms.size());
-
- mData.mUniforms.insert(mData.mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end());
-
return true;
}
Program::VectorAndSamplerCount Program::flattenUniform(const sh::ShaderVariable &uniform,
- const std::string &fullName,
- std::vector<LinkedUniform> *samplerUniforms)
+ const std::string &fullName)
{
VectorAndSamplerCount vectorAndSamplerCount;
@@ -2250,7 +2152,7 @@
const sh::ShaderVariable &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = (fullName + elementString + "." + field.name);
- vectorAndSamplerCount += flattenUniform(field, fieldFullName, samplerUniforms);
+ vectorAndSamplerCount += flattenUniform(field, fieldFullName);
}
}
@@ -2258,28 +2160,18 @@
}
// Not a struct
- bool isSampler = IsSamplerType(uniform.type);
- if (!UniformInList(mData.getUniforms(), fullName) && !UniformInList(*samplerUniforms, fullName))
+ if (mData.getUniformByName(fullName) == nullptr)
{
gl::LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName,
uniform.arraySize, -1,
sh::BlockMemberInfo::getDefaultBlockInfo());
linkedUniform.staticUse = true;
-
- // Store sampler uniforms separately, so we'll append them to the end of the list.
- if (isSampler)
- {
- samplerUniforms->push_back(linkedUniform);
- }
- else
- {
- mData.mUniforms.push_back(linkedUniform);
- }
+ mData.mUniforms.push_back(linkedUniform);
}
- unsigned int elementCount = uniform.elementCount();
- vectorAndSamplerCount.vectorCount = (VariableRegisterCount(uniform.type) * elementCount);
- vectorAndSamplerCount.samplerCount = (isSampler ? elementCount : 0);
+ vectorAndSamplerCount.vectorCount =
+ (VariableRegisterCount(uniform.type) * uniform.elementCount());
+ vectorAndSamplerCount.samplerCount = (IsSamplerType(uniform.type) ? uniform.elementCount() : 0);
return vectorAndSamplerCount;
}
@@ -2402,12 +2294,6 @@
}
else
{
- // Invalide the validation cache if we modify the sampler data.
- if (linkedUniform->isSampler() && memcmp(destPointer, v, sizeof(T) * count) != 0)
- {
- mCachedValidateSamplersResult.reset();
- }
-
memcpy(destPointer, v, sizeof(T) * count);
}
}
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 6e9d682..3dd7c46 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -10,6 +10,13 @@
#ifndef LIBANGLE_PROGRAM_H_
#define LIBANGLE_PROGRAM_H_
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+#include "common/angleutils.h"
+
#include <GLES2/gl2.h>
#include <GLSLANG/ShaderLang.h>
@@ -18,15 +25,6 @@
#include <string>
#include <vector>
-#include "common/angleutils.h"
-#include "common/mathutil.h"
-#include "common/Optional.h"
-
-#include "libANGLE/angletypes.h"
-#include "libANGLE/Constants.h"
-#include "libANGLE/Error.h"
-#include "libANGLE/RefCountObject.h"
-
namespace rx
{
class ImplFactory;
@@ -217,11 +215,6 @@
std::vector<sh::Attribute> mAttributes;
std::bitset<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
- // Uniforms are sorted in order:
- // 1. Non-sampler uniforms
- // 2. Sampler uniforms
- // 3. Uniform block uniforms
- // This makes sampler validation easier, since we don't need a separate list.
std::vector<LinkedUniform> mUniforms;
std::vector<VariableLocation> mUniformLocations;
std::vector<UniformBlock> mUniformBlocks;
@@ -391,8 +384,7 @@
};
VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform,
- const std::string &fullName,
- std::vector<LinkedUniform> *samplerUniforms);
+ const std::string &fullName);
void gatherInterfaceBlockInfo();
void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType);
@@ -422,11 +414,6 @@
const GLuint mHandle;
InfoLog mInfoLog;
-
- // Cache for sampler validation
- Optional<bool> mCachedValidateSamplersResult;
- std::vector<GLenum> mTextureUnitTypesCache;
- RangeUI mSamplerUniformRange;
};
}
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index d51015a..752f995 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -633,7 +633,6 @@
{
const auto it = mSamplerTextures.find(type);
ASSERT(it != mSamplerTextures.end());
- ASSERT(sampler < it->second.size());
return it->second[sampler].get();
}
@@ -641,7 +640,6 @@
{
const auto it = mSamplerTextures.find(type);
ASSERT(it != mSamplerTextures.end());
- ASSERT(sampler < it->second.size());
return it->second[sampler].id();
}
diff --git a/src/libANGLE/Uniform.h b/src/libANGLE/Uniform.h
index 1b21825..040c978 100644
--- a/src/libANGLE/Uniform.h
+++ b/src/libANGLE/Uniform.h
@@ -64,7 +64,6 @@
std::vector<unsigned int> memberUniformIndexes;
- // TODO(jmadill): Make D3D-only.
unsigned int psRegisterIndex;
unsigned int vsRegisterIndex;
};
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index a47b18e..47fb9be 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -66,6 +66,10 @@
virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0;
+ // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to
+ // determine if they can be removed from this interface.
+ virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
+
// Gather uniform block active uniform indices, and uniform block offset info.
virtual void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
std::vector<gl::LinkedUniform> *uniforms) = 0;
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 4819ca0..6cb5c14 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -28,6 +28,36 @@
namespace
{
+GLenum GetTextureType(GLenum samplerType)
+{
+ switch (samplerType)
+ {
+ case GL_SAMPLER_2D:
+ case GL_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_SAMPLER_2D_SHADOW:
+ return GL_TEXTURE_2D;
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ return GL_TEXTURE_3D;
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ return GL_TEXTURE_CUBE_MAP;
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ return GL_TEXTURE_2D_ARRAY;
+ default: UNREACHABLE();
+ }
+
+ return GL_TEXTURE_2D;
+}
+
gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Shader *vertexShader)
{
gl::InputLayout defaultLayout;
@@ -308,6 +338,7 @@
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true),
+ mTextureUnitTypesCache(renderer->getRendererCaps().maxCombinedTextureImageUnits),
mShaderVersion(100),
mSerial(issueSerial())
{
@@ -455,6 +486,106 @@
}
}
+bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
+{
+ // Skip cache if we're using an infolog, so we get the full error.
+ // Also skip the cache if the sample mapping has changed, or if we haven't ever validated.
+ if (!mDirtySamplerMapping && infoLog == nullptr && mCachedValidateSamplersResult.valid())
+ {
+ return mCachedValidateSamplersResult.value();
+ }
+
+ // if any two active samplers in a program are of different types, but refer to the same
+ // texture image unit, and this is the current program, then ValidateProgram will fail, and
+ // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+ updateSamplerMapping();
+
+ std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE);
+
+ for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
+ {
+ if (mSamplersPS[i].active)
+ {
+ unsigned int unit = mSamplersPS[i].logicalTextureUnit;
+
+ if (unit >= caps.maxCombinedTextureImageUnits)
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Sampler uniform (" << unit
+ << ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
+ << caps.maxCombinedTextureImageUnits << ")";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+
+ if (mTextureUnitTypesCache[unit] != GL_NONE)
+ {
+ if (mSamplersPS[i].textureType != mTextureUnitTypesCache[unit])
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Samplers of conflicting types refer to the same texture image unit ("
+ << unit << ").";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+ }
+ else
+ {
+ mTextureUnitTypesCache[unit] = mSamplersPS[i].textureType;
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
+ {
+ if (mSamplersVS[i].active)
+ {
+ unsigned int unit = mSamplersVS[i].logicalTextureUnit;
+
+ if (unit >= caps.maxCombinedTextureImageUnits)
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Sampler uniform (" << unit
+ << ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS ("
+ << caps.maxCombinedTextureImageUnits << ")";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+
+ if (mTextureUnitTypesCache[unit] != GL_NONE)
+ {
+ if (mSamplersVS[i].textureType != mTextureUnitTypesCache[unit])
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Samplers of conflicting types refer to the same texture image unit ("
+ << unit << ").";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+ }
+ else
+ {
+ mTextureUnitTypesCache[unit] = mSamplersVS[i].textureType;
+ }
+ }
+ }
+
+ mCachedValidateSamplersResult = true;
+ return true;
+}
+
LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
reset();
@@ -1042,7 +1173,7 @@
initSemanticIndex();
- defineUniformsAndAssignRegisters();
+ assignUniformRegisters();
gatherTransformFeedbackVaryings(linkedVaryings);
@@ -1056,10 +1187,10 @@
return LinkResult(true, gl::Error(GL_NO_ERROR));
}
-GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
+GLboolean ProgramD3D::validate(const gl::Caps &caps, gl::InfoLog *infoLog)
{
- // TODO(jmadill): Do something useful here?
- return GL_TRUE;
+ applyUniforms();
+ return validateSamplers(infoLog, caps);
}
void ProgramD3D::gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
@@ -1344,19 +1475,17 @@
setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
}
-void ProgramD3D::defineUniformsAndAssignRegisters()
+void ProgramD3D::assignUniformRegisters()
{
const gl::Shader *vertexShader = mData.getAttachedVertexShader();
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
- D3DUniformMap uniformMap;
-
for (const sh::Uniform &vertexUniform : vertexShader->getUniforms())
{
if (vertexUniform.staticUse)
{
- defineUniformBase(vertexShaderD3D, vertexUniform, &uniformMap);
+ assignUniformRegistersBase(vertexShaderD3D, vertexUniform);
}
}
@@ -1367,32 +1496,19 @@
{
if (fragmentUniform.staticUse)
{
- defineUniformBase(fragmentShaderD3D, fragmentUniform, &uniformMap);
+ assignUniformRegistersBase(fragmentShaderD3D, fragmentUniform);
}
}
- // Initialize the D3DUniform list to mirror the indexing of the GL layer.
- for (const gl::LinkedUniform &glUniform : mData.getUniforms())
- {
- if (!glUniform.isInDefaultBlock())
- continue;
-
- auto mapEntry = uniformMap.find(glUniform.name);
- ASSERT(mapEntry != uniformMap.end());
- mD3DUniforms.push_back(mapEntry->second);
- }
-
assignAllSamplerRegisters();
initializeUniformStorage();
}
-void ProgramD3D::defineUniformBase(const ShaderD3D *shader,
- const sh::Uniform &uniform,
- D3DUniformMap *uniformMap)
+void ProgramD3D::assignUniformRegistersBase(const ShaderD3D *shader, const sh::Uniform &uniform)
{
if (uniform.isBuiltIn())
{
- defineUniform(shader, uniform, uniform.name, nullptr, uniformMap);
+ assignUniformRegisters(shader, uniform, uniform.name, nullptr);
return;
}
@@ -1401,7 +1517,7 @@
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(startRegister);
- defineUniform(shader, uniform, uniform.name, &encoder, uniformMap);
+ assignUniformRegisters(shader, uniform, uniform.name, &encoder);
}
D3DUniform *ProgramD3D::getD3DUniformByName(const std::string &name)
@@ -1417,11 +1533,10 @@
return nullptr;
}
-void ProgramD3D::defineUniform(const ShaderD3D *shader,
- const sh::ShaderVariable &uniform,
- const std::string &fullName,
- sh::HLSLBlockEncoder *encoder,
- D3DUniformMap *uniformMap)
+void ProgramD3D::assignUniformRegisters(const ShaderD3D *shader,
+ const sh::ShaderVariable &uniform,
+ const std::string &fullName,
+ sh::HLSLBlockEncoder *encoder)
{
if (uniform.isStruct())
{
@@ -1437,7 +1552,7 @@
const sh::ShaderVariable &field = uniform.fields[fieldIndex];
const std::string &fieldFullName = (fullName + elementString + "." + field.name);
- defineUniform(shader, field, fieldFullName, encoder, uniformMap);
+ assignUniformRegisters(shader, field, fieldFullName, encoder);
}
if (encoder)
@@ -1457,23 +1572,27 @@
encoder ? encoder->encodeType(uniform.type, uniform.arraySize, false)
: sh::BlockMemberInfo::getDefaultBlockInfo();
- auto uniformMapEntry = uniformMap->find(fullName);
- D3DUniform *d3dUniform = nullptr;
+ D3DUniform *d3dUniform = getD3DUniformByName(fullName);
- if (uniformMapEntry != uniformMap->end())
+ if (!d3dUniform)
{
- d3dUniform = uniformMapEntry->second;
- }
- else
- {
+ // We're building the list twice, make sure we use the same indexing. Special case
+ // built-ins.
+ ASSERT(fullName.compare(0, 3, "gl_") == 0 ||
+ mData.getUniformIndex(fullName) == static_cast<GLint>(mD3DUniforms.size()));
+
d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySize, true);
- (*uniformMap)[fullName] = d3dUniform;
+ mD3DUniforms.push_back(d3dUniform);
+
+ if (encoder)
+ {
+ d3dUniform->registerElement =
+ static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
+ }
}
if (encoder)
{
- d3dUniform->registerElement =
- static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo));
unsigned int reg =
static_cast<unsigned int>(sh::HLSLBlockEncoder::getBlockRegister(blockInfo));
if (shader->getShaderType() == GL_FRAGMENT_SHADER)
@@ -1752,7 +1871,7 @@
ASSERT(samplerIndex < outSamplers.size());
Sampler *sampler = &outSamplers[samplerIndex];
sampler->active = true;
- sampler->textureType = gl::SamplerTypeToTextureType(samplerType);
+ sampler->textureType = GetTextureType(samplerType);
sampler->logicalTextureUnit = 0;
*outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
samplerIndex++;
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 2183961..5e86516 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include "common/Optional.h"
#include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/Constants.h"
#include "libANGLE/formatutils.h"
@@ -32,7 +33,7 @@
#endif
// Helper struct representing a single shader uniform
-struct D3DUniform : angle::NonCopyable
+struct D3DUniform
{
D3DUniform(GLenum typeIn,
const std::string &nameIn,
@@ -83,6 +84,7 @@
GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
GLint getUsedSamplerRange(gl::SamplerType type) const;
void updateSamplerMapping();
+ bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const;
@@ -196,18 +198,14 @@
GLenum textureType;
};
- typedef std::map<std::string, D3DUniform *> D3DUniformMap;
typedef std::map<std::string, sh::BlockMemberInfo> BlockInfoMap;
- void defineUniformsAndAssignRegisters();
- void defineUniformBase(const ShaderD3D *shader,
- const sh::Uniform &uniform,
- D3DUniformMap *uniformMap);
- void defineUniform(const ShaderD3D *shader,
- const sh::ShaderVariable &uniform,
- const std::string &fullName,
- sh::HLSLBlockEncoder *encoder,
- D3DUniformMap *uniformMap);
+ void assignUniformRegisters();
+ void assignUniformRegistersBase(const ShaderD3D *shader, const sh::Uniform &uniform);
+ void assignUniformRegisters(const ShaderD3D *shader,
+ const sh::ShaderVariable &uniform,
+ const std::string &fullName,
+ sh::HLSLBlockEncoder *encoder);
void assignAllSamplerRegisters();
void assignSamplerRegisters(const D3DUniform *d3dUniform);
@@ -264,6 +262,9 @@
GLuint mUsedPixelSamplerRange;
bool mDirtySamplerMapping;
+ // Cache for validateSamplers
+ std::vector<GLenum> mTextureUnitTypesCache;
+
// Cache for getPixelExecutableForFramebuffer
std::vector<GLenum> mPixelShaderOutputFormatCache;
@@ -274,6 +275,8 @@
unsigned int mSerial;
+ Optional<bool> mCachedValidateSamplersResult;
+
std::vector<GLint> mVertexUBOCache;
std::vector<GLint> mFragmentUBOCache;
VertexExecutable::Signature mCachedVertexSignature;
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index bbb4540..bae8389 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -299,6 +299,12 @@
mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
}
+bool ProgramGL::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
+{
+ //UNIMPLEMENTED();
+ return true;
+}
+
void ProgramGL::reset()
{
mUniformRealLocationMap.clear();
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index 982d5bb..9cc0a14 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -62,6 +62,8 @@
void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) override;
+ bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) override;
+
void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
std::vector<gl::LinkedUniform> *uniforms) override;
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index acb511f..e9f871d 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -703,366 +703,8 @@
ASSERT_GL_NO_ERROR();
}
-class TextureLimitsTest : public ANGLETest
-{
- protected:
- struct RGBA8
- {
- uint8_t R, G, B, A;
- };
-
- TextureLimitsTest()
- : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0)
- {
- setWindowWidth(128);
- setWindowHeight(128);
- setConfigRedBits(8);
- setConfigGreenBits(8);
- setConfigBlueBits(8);
- setConfigAlphaBits(8);
- }
-
- ~TextureLimitsTest()
- {
- if (mProgram != 0)
- {
- glDeleteProgram(mProgram);
- mProgram = 0;
-
- if (!mTextures.empty())
- {
- glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]);
- }
- }
- }
-
- void SetUp() override
- {
- ANGLETest::SetUp();
-
- glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures);
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures);
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures);
-
- ASSERT_GL_NO_ERROR();
- }
-
- void compileProgramWithTextureCounts(const std::string &vertexPrefix,
- GLint vertexTextureCount,
- GLint vertexActiveTextureCount,
- const std::string &fragPrefix,
- GLint fragmentTextureCount,
- GLint fragmentActiveTextureCount)
- {
- std::stringstream vertexShaderStr;
- vertexShaderStr << "attribute vec2 position;\n"
- << "varying vec4 color;\n"
- << "varying vec2 texCoord;\n";
-
- for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex)
- {
- vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n";
- }
-
- vertexShaderStr << "void main() {\n"
- << " gl_Position = vec4(position, 0, 1);\n"
- << " texCoord = (position * 0.5) + 0.5;\n"
- << " color = vec4(0);\n";
-
- for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex)
- {
- vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex
- << ", texCoord);\n";
- }
-
- vertexShaderStr << "}";
-
- std::stringstream fragmentShaderStr;
- fragmentShaderStr << "varying mediump vec4 color;\n"
- << "varying mediump vec2 texCoord;\n";
-
- for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex)
- {
- fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n";
- }
-
- fragmentShaderStr << "void main() {\n"
- << " gl_FragColor = color;\n";
-
- for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex)
- {
- fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex
- << ", texCoord);\n";
- }
-
- fragmentShaderStr << "}";
-
- const std::string &vertexShaderSource = vertexShaderStr.str();
- const std::string &fragmentShaderSource = fragmentShaderStr.str();
-
- mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
- }
-
- RGBA8 getPixel(GLint texIndex)
- {
- RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3),
- 0, 255u};
- return pixel;
- }
-
- void initTextures(GLint tex2DCount, GLint texCubeCount)
- {
- GLint totalCount = tex2DCount + texCubeCount;
- mTextures.assign(totalCount, 0);
- glGenTextures(totalCount, &mTextures[0]);
- ASSERT_GL_NO_ERROR();
-
- std::vector<RGBA8> texData(16 * 16);
-
- GLint texIndex = 0;
- for (; texIndex < tex2DCount; ++texIndex)
- {
- texData.assign(texData.size(), getPixel(texIndex));
- glActiveTexture(GL_TEXTURE0 + texIndex);
- glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- &texData[0]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- ASSERT_GL_NO_ERROR();
-
- for (; texIndex < texCubeCount; ++texIndex)
- {
- texData.assign(texData.size(), getPixel(texIndex));
- glActiveTexture(GL_TEXTURE0 + texIndex);
- glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, &texData[0]);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- ASSERT_GL_NO_ERROR();
- }
-
- void testWithTextures(GLint vertexTextureCount,
- const std::string &vertexTexturePrefix,
- GLint fragmentTextureCount,
- const std::string &fragmentTexturePrefix)
- {
- // Generate textures
- initTextures(vertexTextureCount + fragmentTextureCount, 0);
-
- glUseProgram(mProgram);
- RGBA8 expectedSum = {0};
- for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex)
- {
- std::stringstream uniformNameStr;
- uniformNameStr << vertexTexturePrefix << texIndex;
- const std::string &uniformName = uniformNameStr.str();
- GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
- ASSERT_NE(-1, location);
-
- glUniform1i(location, texIndex);
- RGBA8 contribution = getPixel(texIndex);
- expectedSum.R += contribution.R;
- expectedSum.G += contribution.G;
- }
-
- for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex)
- {
- std::stringstream uniformNameStr;
- uniformNameStr << fragmentTexturePrefix << texIndex;
- const std::string &uniformName = uniformNameStr.str();
- GLint location = glGetUniformLocation(mProgram, uniformName.c_str());
- ASSERT_NE(-1, location);
-
- glUniform1i(location, texIndex + vertexTextureCount);
- RGBA8 contribution = getPixel(texIndex + vertexTextureCount);
- expectedSum.R += contribution.R;
- expectedSum.G += contribution.G;
- }
-
- ASSERT_GE(256u, expectedSum.G);
-
- drawQuad(mProgram, "position", 0.5f);
- ASSERT_GL_NO_ERROR();
- EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255);
- }
-
- GLuint mProgram;
- std::vector<GLuint> mTextures;
- GLint mMaxVertexTextures;
- GLint mMaxFragmentTextures;
- GLint mMaxCombinedTextures;
-};
-
-// Test rendering with the maximum vertex texture units.
-TEST_P(TextureLimitsTest, MaxVertexTextures)
-{
- compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0);
- ASSERT_NE(0u, mProgram);
- ASSERT_GL_NO_ERROR();
-
- testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
-}
-
-// Test rendering with the maximum fragment texture units.
-TEST_P(TextureLimitsTest, MaxFragmentTextures)
-{
- compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures);
- ASSERT_NE(0u, mProgram);
- ASSERT_GL_NO_ERROR();
-
- testWithTextures(mMaxFragmentTextures, "tex", 0, "tex");
-}
-
-// Test rendering with maximum combined texture units.
-TEST_P(TextureLimitsTest, MaxCombinedTextures)
-{
- GLint vertexTextures = mMaxVertexTextures;
-
- if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures)
- {
- vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures;
- }
-
- compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex",
- mMaxFragmentTextures, mMaxFragmentTextures);
- ASSERT_NE(0u, mProgram);
- ASSERT_GL_NO_ERROR();
-
- testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex");
-}
-
-// Negative test for exceeding the number of vertex textures
-TEST_P(TextureLimitsTest, ExcessiveVertexTextures)
-{
- compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0,
- 0);
- ASSERT_EQ(0u, mProgram);
-}
-
-// Negative test for exceeding the number of fragment textures
-TEST_P(TextureLimitsTest, ExcessiveFragmentTextures)
-{
- compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1,
- mMaxFragmentTextures + 1);
- ASSERT_EQ(0u, mProgram);
-}
-
-// Test active vertex textures under the limit, but excessive textures specified.
-TEST_P(TextureLimitsTest, MaxActiveVertexTextures)
-{
- compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0);
- ASSERT_NE(0u, mProgram);
- ASSERT_GL_NO_ERROR();
-
- testWithTextures(mMaxVertexTextures, "tex", 0, "tex");
-}
-
-// Test active fragment textures under the limit, but excessive textures specified.
-TEST_P(TextureLimitsTest, MaxActiveFragmentTextures)
-{
- compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4,
- mMaxFragmentTextures);
- ASSERT_NE(0u, mProgram);
- ASSERT_GL_NO_ERROR();
-
- testWithTextures(0, "tex", mMaxFragmentTextures, "tex");
-}
-
-// Negative test for pointing two sampler uniforms of different types to the same texture.
-TEST_P(TextureLimitsTest, TextureTypeConflict)
-{
- const std::string &vertexShader =
- "attribute vec2 position;\n"
- "varying float color;\n"
- "uniform sampler2D tex2D;\n"
- "uniform samplerCube texCube;\n"
- "void main() {\n"
- " gl_Position = vec4(position, 0, 1);\n"
- " vec2 texCoord = (position * 0.5) + 0.5;\n"
- " color = texture2D(tex2D, texCoord).x;\n"
- " color += textureCube(texCube, vec3(texCoord, 0)).x;\n"
- "}";
- const std::string &fragmentShader =
- "varying mediump float color;\n"
- "void main() {\n"
- " gl_FragColor = vec4(color, 0, 0, 1);\n"
- "}";
-
- mProgram = CompileProgram(vertexShader, fragmentShader);
- ASSERT_NE(0u, mProgram);
-
- initTextures(1, 0);
-
- glUseProgram(mProgram);
- GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
- ASSERT_NE(-1, tex2DLocation);
- GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube");
- ASSERT_NE(-1, texCubeLocation);
-
- glUniform1i(tex2DLocation, 0);
- glUniform1i(texCubeLocation, 0);
- ASSERT_GL_NO_ERROR();
-
- drawQuad(mProgram, "position", 0.5f);
- EXPECT_GL_ERROR(GL_INVALID_OPERATION);
-}
-
-// Negative test for rendering with texture outside the valid range.
-// TODO(jmadill): Research if this is correct.
-TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum)
-{
- const std::string &vertexShader =
- "attribute vec2 position;\n"
- "varying float color;\n"
- "uniform sampler2D tex2D;\n"
- "void main() {\n"
- " gl_Position = vec4(position, 0, 1);\n"
- " vec2 texCoord = (position * 0.5) + 0.5;\n"
- " color = texture2D(tex2D, texCoord).x;\n"
- "}";
- const std::string &fragmentShader =
- "varying mediump float color;\n"
- "void main() {\n"
- " gl_FragColor = vec4(color, 0, 0, 1);\n"
- "}";
-
- mProgram = CompileProgram(vertexShader, fragmentShader);
- ASSERT_NE(0u, mProgram);
-
- glUseProgram(mProgram);
- GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D");
- ASSERT_NE(-1, tex2DLocation);
-
- glUniform1i(tex2DLocation, mMaxCombinedTextures);
- ASSERT_GL_NO_ERROR();
-
- drawQuad(mProgram, "position", 0.5f);
- EXPECT_GL_ERROR(GL_INVALID_OPERATION);
-}
-
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(TextureTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3()); // TODO(geofflang): Figure out why this test fails on Intel OpenGL
ANGLE_INSTANTIATE_TEST(TextureTestES3, ES3_D3D11(), ES3_OPENGL());
-ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL());
} // namespace
diff --git a/src/tests/gl_tests/UniformTest.cpp b/src/tests/gl_tests/UniformTest.cpp
index 0cd3684..e1db43f 100644
--- a/src/tests/gl_tests/UniformTest.cpp
+++ b/src/tests/gl_tests/UniformTest.cpp
@@ -452,46 +452,6 @@
}
}
-// Check that sampler uniforms only show up one time in the list
-TEST_P(UniformTest, SamplerUniformsAppearOnce)
-{
- const std::string &vertShader =
- "attribute vec2 position;\n"
- "uniform sampler2D tex2D;\n"
- "varying vec4 color;\n"
- "void main() {\n"
- " gl_Position = vec4(position, 0, 1);\n"
- " color = texture2D(tex2D, vec2(0));\n"
- "}";
-
- const std::string &fragShader =
- "precision mediump float;\n"
- "varying vec4 color;\n"
- "uniform sampler2D tex2D;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(tex2D, vec2(0)) + color;\n"
- "}";
-
- GLuint program = CompileProgram(vertShader, fragShader);
- ASSERT_NE(0u, program);
-
- GLint activeUniformsCount = 0;
- glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniformsCount);
- ASSERT_EQ(1, activeUniformsCount);
-
- GLint size = 0;
- GLenum type = GL_NONE;
- GLchar name[120] = {0};
- glGetActiveUniform(program, 0, 100, nullptr, &size, &type, name);
- EXPECT_EQ(1, size);
- EXPECT_EQ(GL_SAMPLER_2D, type);
- EXPECT_STREQ("tex2D", name);
-
- EXPECT_GL_NO_ERROR();
-
- glDeleteProgram(program);
-}
-
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(UniformTestES3, ES3_D3D11(), ES3_OPENGL());