Commit 69f9b2c8 by Cooper Partin Committed by Jamie Madill

Fixed GL_MAX_VERTEX_UNIFORM_VECTORS and GL_MAX_FRAGMENT_UNIFORM_VECTORS to…

Fixed GL_MAX_VERTEX_UNIFORM_VECTORS and GL_MAX_FRAGMENT_UNIFORM_VECTORS to report accurate maximum value. Change-Id: Ic581e1ef0c6be2bf1ff0092b373b3c480b6fbd8a Reviewed-on: https://chromium-review.googlesource.com/294755Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarCooper Partin <coopp@microsoft.com> Tryjob-Request: Jamie Madill <jmadill@chromium.org>
parent 3766a40d
...@@ -1451,6 +1451,13 @@ bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) ...@@ -1451,6 +1451,13 @@ bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
const std::vector<sh::Uniform> &vertexUniforms = vertexShader->getUniforms(); const std::vector<sh::Uniform> &vertexUniforms = vertexShader->getUniforms();
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader); const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(vertexShader);
if (vertexUniforms.size() > caps.maxVertexUniformVectors)
{
infoLog << "Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS ("
<< caps.maxVertexUniformVectors << ").";
return false;
}
for (const sh::Uniform &uniform : vertexUniforms) for (const sh::Uniform &uniform : vertexUniforms)
{ {
if (uniform.staticUse) if (uniform.staticUse)
...@@ -1465,6 +1472,13 @@ bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) ...@@ -1465,6 +1472,13 @@ bool ProgramD3D::defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader->getUniforms(); const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader->getUniforms();
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader); const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(fragmentShader);
if (fragmentUniforms.size() > caps.maxFragmentUniformVectors)
{
infoLog << "Vertex shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS ("
<< caps.maxFragmentUniformVectors << ").";
return false;
}
for (const sh::Uniform &uniform : fragmentUniforms) for (const sh::Uniform &uniform : fragmentUniforms)
{ {
if (uniform.staticUse) if (uniform.staticUse)
......
...@@ -2514,12 +2514,14 @@ DeviceIdentifier Renderer11::getAdapterIdentifier() const ...@@ -2514,12 +2514,14 @@ DeviceIdentifier Renderer11::getAdapterIdentifier() const
unsigned int Renderer11::getReservedVertexUniformVectors() const unsigned int Renderer11::getReservedVertexUniformVectors() const
{ {
return 0; // Driver uniforms are stored in a separate constant buffer // Driver uniforms are stored in a separate constant buffer
return d3d11_gl::GetReservedVertexUniformVectors(mRenderer11DeviceCaps.featureLevel);
} }
unsigned int Renderer11::getReservedFragmentUniformVectors() const unsigned int Renderer11::getReservedFragmentUniformVectors() const
{ {
return 0; // Driver uniforms are stored in a separate constant buffer // Driver uniforms are stored in a separate constant buffer
return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel);
} }
unsigned int Renderer11::getReservedVertexUniformBuffers() const unsigned int Renderer11::getReservedVertexUniformBuffers() const
......
...@@ -276,6 +276,48 @@ class DXGISupportHelper : angle::NonCopyable ...@@ -276,6 +276,48 @@ class DXGISupportHelper : angle::NonCopyable
} // anonymous namespace } // anonymous namespace
unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return 0;
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1:
return 2; // dx_ViewAdjust and dx_ViewCoords
default:
UNREACHABLE();
return 0;
}
}
unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return 0;
case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1:
return 2;
default:
UNREACHABLE();
return 0;
}
}
GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
{ {
switch (featureLevel) switch (featureLevel)
...@@ -702,7 +744,8 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -702,7 +744,8 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 255; case D3D_FEATURE_LEVEL_9_1:
return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
...@@ -818,7 +861,8 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) ...@@ -818,7 +861,8 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers
case D3D_FEATURE_LEVEL_9_3: case D3D_FEATURE_LEVEL_9_3:
case D3D_FEATURE_LEVEL_9_2: case D3D_FEATURE_LEVEL_9_2:
case D3D_FEATURE_LEVEL_9_1: return 32; case D3D_FEATURE_LEVEL_9_1:
return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel);
default: UNREACHABLE(); return 0; default: UNREACHABLE(); return 0;
} }
......
...@@ -52,6 +52,10 @@ D3D11_QUERY ConvertQueryType(GLenum queryType); ...@@ -52,6 +52,10 @@ D3D11_QUERY ConvertQueryType(GLenum queryType);
namespace d3d11_gl namespace d3d11_gl
{ {
unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel);
unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel);
GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel); GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel);
void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps, void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps,
gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations); gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations);
......
...@@ -2509,12 +2509,12 @@ DeviceIdentifier Renderer9::getAdapterIdentifier() const ...@@ -2509,12 +2509,12 @@ DeviceIdentifier Renderer9::getAdapterIdentifier() const
unsigned int Renderer9::getReservedVertexUniformVectors() const unsigned int Renderer9::getReservedVertexUniformVectors() const
{ {
return 2; // dx_ViewAdjust and dx_DepthRange. return d3d9_gl::GetReservedVertexUniformVectors();
} }
unsigned int Renderer9::getReservedFragmentUniformVectors() const unsigned int Renderer9::getReservedFragmentUniformVectors() const
{ {
return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. return d3d9_gl::GetReservedFragmentUniformVectors();
} }
unsigned int Renderer9::getReservedVertexUniformBuffers() const unsigned int Renderer9::getReservedVertexUniformBuffers() const
......
...@@ -274,6 +274,16 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) ...@@ -274,6 +274,16 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples)
namespace d3d9_gl namespace d3d9_gl
{ {
unsigned int GetReservedVertexUniformVectors()
{
return 3; // dx_ViewCoords, dx_ViewAdjust and dx_DepthRange.
}
unsigned int GetReservedFragmentUniformVectors()
{
return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
}
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
{ {
return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
...@@ -435,9 +445,9 @@ void GenerateCaps(IDirect3D9 *d3d9, ...@@ -435,9 +445,9 @@ void GenerateCaps(IDirect3D9 *d3d9,
// Vertex shader limits // Vertex shader limits
caps->maxVertexAttributes = 16; caps->maxVertexAttributes = 16;
const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange.
const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256;
caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors; caps->maxVertexUniformVectors =
MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors();
caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4; caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4;
caps->maxVertexUniformBlocks = 0; caps->maxVertexUniformBlocks = 0;
...@@ -463,12 +473,12 @@ void GenerateCaps(IDirect3D9 *d3d9, ...@@ -463,12 +473,12 @@ void GenerateCaps(IDirect3D9 *d3d9,
} }
// Fragment shader limits // Fragment shader limits
const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224; const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224;
const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32; const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32;
caps->maxFragmentUniformVectors = ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 caps->maxFragmentUniformVectors =
: MAX_PIXEL_CONSTANT_VECTORS_SM2) - reservedPixelUniformVectors; ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3
: MAX_PIXEL_CONSTANT_VECTORS_SM2) -
GetReservedFragmentUniformVectors();
caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4; caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4;
caps->maxFragmentUniformBlocks = 0; caps->maxFragmentUniformBlocks = 0;
caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; caps->maxFragmentInputComponents = caps->maxVertexOutputComponents;
......
...@@ -47,6 +47,10 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); ...@@ -47,6 +47,10 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
namespace d3d9_gl namespace d3d9_gl
{ {
unsigned int GetReservedVertexUniformVectors();
unsigned int GetReservedFragmentUniformVectors();
GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type); GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
......
...@@ -1128,6 +1128,166 @@ TEST_P(GLSLTest, LoopIndexingValidation) ...@@ -1128,6 +1128,166 @@ TEST_P(GLSLTest, LoopIndexingValidation)
} }
} }
// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS
// can actually be used.
TEST_P(GLSLTest, VerifyMaxVertexUniformVectors)
{
const std::string &fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
);
int maxUniforms = 10000;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
EXPECT_GL_NO_ERROR();
std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl;
std::stringstream vshaderSource;
vshaderSource << "precision mediump float;\n";
for (int i = 0; i < maxUniforms; i++)
{
vshaderSource << "uniform vec4 v" << std::to_string(i) << ";\n";
}
vshaderSource << "void main()\n{\n";
for (int i = 0; i < maxUniforms; i++)
{
vshaderSource << " gl_Position += v" << std::to_string(i) << ";\n";
}
vshaderSource << "}\n";
GLuint program = CompileProgram(vshaderSource.str(), fragmentShaderSource);
EXPECT_NE(0u, program);
}
// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS
// fails shader compilation.
TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded)
{
const std::string &fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
);
int maxUniforms = 10000;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms);
EXPECT_GL_NO_ERROR();
// Add 1 more to exceed the reported max count
maxUniforms += 1;
std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms << std::endl;
std::stringstream vshaderSource;
vshaderSource << "precision mediump float;\n";
for (int i = 0; i < maxUniforms; i++)
{
vshaderSource << "uniform vec4 v" << std::to_string(i) << ";\n";
}
vshaderSource << "void main()\n{\n";
for (int i = 0; i < maxUniforms; i++)
{
vshaderSource << " gl_Position += v" << std::to_string(i) << ";\n";
}
vshaderSource << "}\n";
GLuint program = CompileProgram(vshaderSource.str(), fragmentShaderSource);
EXPECT_EQ(0u, program);
}
// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
// can actually be used.
TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsFragment)
{
const std::string &vertexShaderSource = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_Position = vec4(0.0);
}
);
int maxUniforms = 10000;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
EXPECT_GL_NO_ERROR();
std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl;
std::stringstream fshaderSource;
fshaderSource << "precision mediump float;\n";
for (int i = 0; i < maxUniforms; i++)
{
fshaderSource << "uniform vec4 v" << std::to_string(i) << ";\n";
}
fshaderSource << "void main()\n{\n";
for (int i = 0; i < maxUniforms; i++)
{
fshaderSource << " gl_FragColor += v" << std::to_string(i) << ";\n";
}
fshaderSource << "}\n";
GLuint program = CompileProgram(vertexShaderSource, fshaderSource.str());
EXPECT_NE(0u, program);
}
// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS
// fails shader compilation.
TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsFragmentExceeded)
{
const std::string &vertexShaderSource = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_Position = vec4(0.0);
}
);
int maxUniforms = 10000;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms);
EXPECT_GL_NO_ERROR();
// Add 1 more to exceed the reported max count
maxUniforms += 1;
std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms << std::endl;
std::stringstream fshaderSource;
fshaderSource << "precision mediump float;\n";
for (int i = 0; i < maxUniforms; i++)
{
fshaderSource << "uniform vec4 v" << std::to_string(i) << ";\n";
}
fshaderSource << "void main()\n{\n";
for (int i = 0; i < maxUniforms; i++)
{
fshaderSource << " gl_FragColor += v" << std::to_string(i) << ";\n";
}
fshaderSource << "}\n";
GLuint program = CompileProgram(vertexShaderSource, fshaderSource.str());
EXPECT_EQ(0u, program);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3()); ANGLE_INSTANTIATE_TEST(GLSLTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3());
......
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