Initialize ANGLE_multiview caps and workaround state
The patch checks whether ANGLE_multiview can be supported in the OpenGL
renderer, updates the caps and adds a workaround field to enable
multiview support through the NV_viewport_array2 extension.
BUG=angleproject:2062
TEST=angle_end2end_tests
Change-Id: I99dae10564db7bcca41d7624f8de272c1d996e09
Reviewed-on: https://chromium-review.googlesource.com/567934
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index a194071..92c850a 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -685,12 +685,14 @@
<< ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
<< ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
<< ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
+ << ":OVR_multiview:" << compileResources.OVR_multiview
<< ":EXT_YUV_target:" << compileResources.EXT_YUV_target
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
+ << ":MaxViewsOVR:" << compileResources.MaxViewsOVR
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision
<< ":MaxImageUnits:" << compileResources.MaxImageUnits
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index adeebf3..08c4bbf 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -179,7 +179,7 @@
// Extensions constants.
resources->MaxDualSourceDrawBuffers = 0;
- resources->MaxViewsOVR = 2;
+ resources->MaxViewsOVR = 4;
// Disable name hashing by default.
resources->HashFunction = nullptr;
diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
index 67085e4..8b159f6 100644
--- a/src/libANGLE/Caps.cpp
+++ b/src/libANGLE/Caps.cpp
@@ -188,6 +188,8 @@
ARMshaderFramebufferFetch(false),
NVshaderFramebufferFetch(false),
fragDepth(false),
+ multiview(false),
+ maxViews(1u),
textureUsage(false),
translatedShaderSource(false),
fboRenderMipmap(false),
@@ -659,6 +661,7 @@
map["GL_ARM_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::ARMshaderFramebufferFetch);
map["GL_EXT_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::shaderFramebufferFetch);
map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth);
+ map["GL_ANGLE_multiview"] = enableableExtension(&Extensions::multiview);
map["GL_ANGLE_texture_usage"] = esOnlyExtension(&Extensions::textureUsage);
map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource);
map["GL_OES_fbo_render_mipmap"] = esOnlyExtension(&Extensions::fboRenderMipmap);
diff --git a/src/libANGLE/Caps.h b/src/libANGLE/Caps.h
index 2588ad0..67dbbeb 100644
--- a/src/libANGLE/Caps.h
+++ b/src/libANGLE/Caps.h
@@ -251,6 +251,10 @@
// GL_EXT_frag_depth
bool fragDepth;
+ // ANGLE_multiview
+ bool multiview;
+ GLuint maxViews;
+
// GL_ANGLE_texture_usage
bool textureUsage;
diff --git a/src/libANGLE/Compiler.cpp b/src/libANGLE/Compiler.cpp
index 32267d1..87c58fa 100644
--- a/src/libANGLE/Compiler.cpp
+++ b/src/libANGLE/Compiler.cpp
@@ -76,6 +76,10 @@
mResources.FragmentPrecisionHigh = 1;
mResources.EXT_frag_depth = extensions.fragDepth;
+ // OVR_multiview state
+ mResources.OVR_multiview = extensions.multiview;
+ mResources.MaxViewsOVR = extensions.maxViews;
+
// GLSL ES 3.0 constants
mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
diff --git a/src/libANGLE/renderer/gl/ContextGL.cpp b/src/libANGLE/renderer/gl/ContextGL.cpp
index 457581c..2634d12 100644
--- a/src/libANGLE/renderer/gl/ContextGL.cpp
+++ b/src/libANGLE/renderer/gl/ContextGL.cpp
@@ -52,7 +52,8 @@
ShaderImpl *ContextGL::createShader(const gl::ShaderState &data)
{
return new ShaderGL(data, getFunctions(), getWorkaroundsGL(),
- getExtensions().webglCompatibility);
+ getExtensions().webglCompatibility,
+ mRenderer->getMultiviewImplementationType());
}
ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data)
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index a391ad4..9716104 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -170,7 +170,8 @@
mBlitter(nullptr),
mHasDebugOutput(false),
mSkipDrawCalls(false),
- mCapsInitialized(false)
+ mCapsInitialized(false),
+ mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED)
{
ASSERT(mFunctions);
nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds);
@@ -606,7 +607,7 @@
gl::Limitations * /* outLimitations */) const
{
nativegl_gl::GenerateCaps(mFunctions, mWorkarounds, outCaps, outTextureCaps, outExtensions,
- &mMaxSupportedESVersion);
+ &mMaxSupportedESVersion, &mMultiviewImplementationType);
}
GLint RendererGL::getGPUDisjoint()
@@ -655,6 +656,12 @@
return mNativeLimitations;
}
+MultiviewImplementationTypeGL RendererGL::getMultiviewImplementationType() const
+{
+ ensureCapsInitialized();
+ return mMultiviewImplementationType;
+}
+
void RendererGL::applyNativeWorkarounds(gl::Workarounds *workarounds) const
{
ensureCapsInitialized();
diff --git a/src/libANGLE/renderer/gl/RendererGL.h b/src/libANGLE/renderer/gl/RendererGL.h
index 4902c4f..01a3d7f 100644
--- a/src/libANGLE/renderer/gl/RendererGL.h
+++ b/src/libANGLE/renderer/gl/RendererGL.h
@@ -13,6 +13,7 @@
#include "libANGLE/Error.h"
#include "libANGLE/Version.h"
#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/renderergl_utils.h"
namespace gl
{
@@ -162,6 +163,7 @@
const WorkaroundsGL &getWorkarounds() const { return mWorkarounds; }
BlitGL *getBlitter() const { return mBlitter; }
+ MultiviewImplementationTypeGL getMultiviewImplementationType() const;
const gl::Caps &getNativeCaps() const;
const gl::TextureCapsMap &getNativeTextureCaps() const;
const gl::Extensions &getNativeExtensions() const;
@@ -199,6 +201,7 @@
mutable gl::TextureCapsMap mNativeTextureCaps;
mutable gl::Extensions mNativeExtensions;
mutable gl::Limitations mNativeLimitations;
+ mutable MultiviewImplementationTypeGL mMultiviewImplementationType;
};
} // namespace rx
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
index 05888b4..b75dbe7 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -22,12 +22,14 @@
ShaderGL::ShaderGL(const gl::ShaderState &data,
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
- bool isWebGL)
+ bool isWebGL,
+ MultiviewImplementationTypeGL multiviewImplementationType)
: ShaderImpl(data),
mFunctions(functions),
mWorkarounds(workarounds),
mShaderID(0),
- mIsWebGL(isWebGL)
+ mIsWebGL(isWebGL),
+ mMultiviewImplementationType(multiviewImplementationType)
{
ASSERT(mFunctions);
}
@@ -110,6 +112,12 @@
options |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
}
+ if (mMultiviewImplementationType == MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2)
+ {
+ options |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
+ options |= SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER;
+ }
+
return options;
}
diff --git a/src/libANGLE/renderer/gl/ShaderGL.h b/src/libANGLE/renderer/gl/ShaderGL.h
index 8ddf801..bfe01f2 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.h
+++ b/src/libANGLE/renderer/gl/ShaderGL.h
@@ -15,6 +15,7 @@
{
class FunctionsGL;
struct WorkaroundsGL;
+enum class MultiviewImplementationTypeGL;
class ShaderGL : public ShaderImpl
{
@@ -22,7 +23,8 @@
ShaderGL(const gl::ShaderState &data,
const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
- bool isWebGL);
+ bool isWebGL,
+ MultiviewImplementationTypeGL multiviewImplementationType);
~ShaderGL() override;
// ShaderImpl implementation
@@ -39,6 +41,7 @@
GLuint mShaderID;
bool mIsWebGL;
+ MultiviewImplementationTypeGL mMultiviewImplementationType;
};
}
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index bfa4bd9..bdcf53c 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -222,7 +222,8 @@
gl::Caps *caps,
gl::TextureCapsMap *textureCapsMap,
gl::Extensions *extensions,
- gl::Version *maxSupportedESVersion)
+ gl::Version *maxSupportedESVersion,
+ MultiviewImplementationTypeGL *multiviewImplementationType)
{
// Texture format support checks
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
@@ -873,6 +874,18 @@
functions->hasGLESExtension("GL_EXT_shader_texture_lod");
extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP ||
functions->hasGLESExtension("GL_EXT_frag_depth");
+
+ if (functions->hasGLExtension("GL_NV_viewport_array2"))
+ {
+ extensions->multiview = true;
+ // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
+ const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
+ // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
+ const int maxViewports = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
+ extensions->maxViews = static_cast<GLuint>(std::min(maxLayers, maxViewports));
+ *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
+ }
+
extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
extensions->instancedArrays = functions->isAtLeastGL(gl::Version(3, 1)) ||
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.h b/src/libANGLE/renderer/gl/renderergl_utils.h
index d8df6f3..76eb478 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.h
+++ b/src/libANGLE/renderer/gl/renderergl_utils.h
@@ -32,6 +32,11 @@
{
class FunctionsGL;
struct WorkaroundsGL;
+enum class MultiviewImplementationTypeGL
+{
+ NV_VIEWPORT_ARRAY2,
+ UNSPECIFIED
+};
VendorID GetVendorID(const FunctionsGL *functions);
std::string GetDriverVersion(const FunctionsGL *functions);
@@ -44,7 +49,8 @@
gl::Caps *caps,
gl::TextureCapsMap *textureCapsMap,
gl::Extensions *extensions,
- gl::Version *maxSupportedESVersion);
+ gl::Version *maxSupportedESVersion,
+ MultiviewImplementationTypeGL *multiviewImplementationType);
void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds);
void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds);