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/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++;