Commit 862c0ba4 by Geoff Lang

Implement the remaining caps queries.

Limit the supported ES version based on these caps. BUG=angleproject:879 Change-Id: If3a097576465b33af0015fcb28dab10e88fdc4d9 Reviewed-on: https://chromium-review.googlesource.com/273160Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent dd323e95
...@@ -24,6 +24,7 @@ struct Version ...@@ -24,6 +24,7 @@ struct Version
}; };
bool operator>=(const Version &a, const Version &b); bool operator>=(const Version &a, const Version &b);
bool operator<(const Version &a, const Version &b);
} }
......
...@@ -25,4 +25,9 @@ inline bool operator>=(const Version &a, const Version &b) ...@@ -25,4 +25,9 @@ inline bool operator>=(const Version &a, const Version &b)
return a.major > b.major || (a.major == b.major && a.minor >= b.minor); return a.major > b.major || (a.major == b.major && a.minor >= b.minor);
} }
inline bool operator<(const Version &a, const Version &b)
{
return !(a >= b);
}
} }
...@@ -32,6 +32,13 @@ DisplayGL::~DisplayGL() ...@@ -32,6 +32,13 @@ DisplayGL::~DisplayGL()
egl::Error DisplayGL::initialize(egl::Display *display) egl::Error DisplayGL::initialize(egl::Display *display)
{ {
mRenderer = new RendererGL(getFunctionsGL(), display->getAttributeMap()); mRenderer = new RendererGL(getFunctionsGL(), display->getAttributeMap());
const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion();
if (maxVersion < gl::Version(2, 0))
{
return egl::Error(EGL_NOT_INITIALIZED, "OpenGL ES 2.0 is not supportable.");
}
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
...@@ -63,4 +70,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS ...@@ -63,4 +70,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS
return glDrawSurface->makeCurrent(); return glDrawSurface->makeCurrent();
} }
const gl::Version &DisplayGL::getMaxSupportedESVersion() const
{
ASSERT(mRenderer != nullptr);
return mRenderer->getMaxSupportedESVersion();
}
} }
...@@ -31,6 +31,9 @@ class DisplayGL : public DisplayImpl ...@@ -31,6 +31,9 @@ class DisplayGL : public DisplayImpl
egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override; egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
protected:
const gl::Version &getMaxSupportedESVersion() const;
private: private:
virtual const FunctionsGL *getFunctionsGL() const = 0; virtual const FunctionsGL *getFunctionsGL() const = 0;
......
...@@ -6,7 +6,7 @@ Documentation of OpenGL ES and EGL features, caps and formats and required exten ...@@ -6,7 +6,7 @@ Documentation of OpenGL ES and EGL features, caps and formats and required exten
|---|---|---|---|---|---| |---|---|---|---|---|---|
|Framebuffer/renderbuffer objects|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|2.0|--|Can potentially be emulated with Pbuffers but realistically this extension is always required.| |Framebuffer/renderbuffer objects|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|2.0|--|Can potentially be emulated with Pbuffers but realistically this extension is always required.|
|Blit framebuffer|3.0|[GL_EXT_framebuffer_blit](https://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt)|3.0|[GL_ANGLE_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_blit.txt) or [GL_NV_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt)|| |Blit framebuffer|3.0|[GL_EXT_framebuffer_blit](https://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt)|3.0|[GL_ANGLE_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_blit.txt) or [GL_NV_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt)||
|Multisampling|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)|| |Multisampling|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)||
|Depth textures|3.0|[GL_ARB_depth_texture](https://www.opengl.org/registry/specs/ARB/depth_texture.txt)|3.0|[GL_OES_depth_texture](https://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt) or [GL_ANGLE_depth_texture](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_depth_texture.txt) |Depth textures|3.0|[GL_ARB_depth_texture](https://www.opengl.org/registry/specs/ARB/depth_texture.txt)|3.0|[GL_OES_depth_texture](https://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt) or [GL_ANGLE_depth_texture](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_depth_texture.txt)
|Draw buffers (MRT)|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)|| |Draw buffers (MRT)|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)||
|3D textures|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)|| |3D textures|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)||
...@@ -55,7 +55,7 @@ Documentation of OpenGL ES and EGL features, caps and formats and required exten ...@@ -55,7 +55,7 @@ Documentation of OpenGL ES and EGL features, caps and formats and required exten
|GL_MAX_VARYING_COMPONENTS|3.0|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Was depricated in the OpenGL core spec but re-added in GL_ARB_ES3_compatibility| |GL_MAX_VARYING_COMPONENTS|3.0|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Was depricated in the OpenGL core spec but re-added in GL_ARB_ES3_compatibility|
|GL_MAX_VARYING_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VARYING_COMPONENTS / 4.| |GL_MAX_VARYING_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VARYING_COMPONENTS / 4.|
|GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|-- |GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|--
|GL_MAX_SAMPLES|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)|| |GL_MAX_SAMPLES|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)||
|GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.| |GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.|
|IMPLEMENTATION_COLOR_READ_FORMAT IMPLEMENTATION_COLOR_READ_TYPE|--|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Desktop GL doesn't as many limitations as ES for ReadPixels, can either always return GL_RGBA/GL_UNSIGNED_BYTE or return the format and type of the read buffer.| |IMPLEMENTATION_COLOR_READ_FORMAT IMPLEMENTATION_COLOR_READ_TYPE|--|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Desktop GL doesn't as many limitations as ES for ReadPixels, can either always return GL_RGBA/GL_UNSIGNED_BYTE or return the format and type of the read buffer.|
......
...@@ -1174,6 +1174,12 @@ void FunctionsGL::initialize() ...@@ -1174,6 +1174,12 @@ void FunctionsGL::initialize()
// Extensions // Extensions
AssignGLExtensionEntryPoint(extensions, "GL_ARB_internalformat_query", loadProcAddress("glGetInternalformativ"), &getInternalformativ); AssignGLExtensionEntryPoint(extensions, "GL_ARB_internalformat_query", loadProcAddress("glGetInternalformativ"), &getInternalformativ);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glShaderBinary"), &shaderBinary);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glDepthRangef"), &depthRangef);
AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glClearDepthf"), &clearDepthf);
} }
// 3.1 // 3.1
...@@ -1615,4 +1621,14 @@ bool FunctionsGL::hasExtension(const std::string &ext) const ...@@ -1615,4 +1621,14 @@ bool FunctionsGL::hasExtension(const std::string &ext) const
return std::find(extensions.begin(), extensions.end(), ext) != extensions.end(); return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
} }
bool FunctionsGL::hasGLExtension(const std::string &ext) const
{
return standard == STANDARD_GL_DESKTOP && hasExtension(ext);
}
bool FunctionsGL::hasGLESExtension(const std::string &ext) const
{
return standard == STANDARD_GL_ES && hasExtension(ext);
}
} }
...@@ -40,6 +40,8 @@ class FunctionsGL ...@@ -40,6 +40,8 @@ class FunctionsGL
// Extensions // Extensions
std::vector<std::string> extensions; std::vector<std::string> extensions;
bool hasExtension(const std::string &ext) const; bool hasExtension(const std::string &ext) const;
bool hasGLExtension(const std::string &ext) const;
bool hasGLESExtension(const std::string &ext) const;
// Entry Points // Entry Points
// 1.0 // 1.0
......
...@@ -80,6 +80,7 @@ namespace rx ...@@ -80,6 +80,7 @@ namespace rx
RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap) RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
: Renderer(), : Renderer(),
mMaxSupportedESVersion(0, 0),
mFunctions(functions), mFunctions(functions),
mStateManager(nullptr), mStateManager(nullptr),
mSkipDrawCalls(false) mSkipDrawCalls(false)
...@@ -279,9 +280,17 @@ std::string RendererGL::getRendererDescription() const ...@@ -279,9 +280,17 @@ std::string RendererGL::getRendererDescription() const
return rendererString.str(); return rendererString.str();
} }
const gl::Version &RendererGL::getMaxSupportedESVersion() const
{
// Force generation of caps
getRendererCaps();
return mMaxSupportedESVersion;
}
void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const
{ {
nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions); nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
} }
Workarounds RendererGL::generateWorkarounds() const Workarounds RendererGL::generateWorkarounds() const
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_ #ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_
#define LIBANGLE_RENDERER_GL_RENDERERGL_H_ #define LIBANGLE_RENDERER_GL_RENDERERGL_H_
#include "libANGLE/Version.h"
#include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/Renderer.h"
namespace rx namespace rx
...@@ -70,10 +71,14 @@ class RendererGL : public Renderer ...@@ -70,10 +71,14 @@ class RendererGL : public Renderer
std::string getVendorString() const override; std::string getVendorString() const override;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
const gl::Version &getMaxSupportedESVersion() const;
private: private:
void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const override; void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const override;
Workarounds generateWorkarounds() const override; Workarounds generateWorkarounds() const override;
mutable gl::Version mMaxSupportedESVersion;
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
......
...@@ -93,8 +93,51 @@ static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name) ...@@ -93,8 +93,51 @@ static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
return result; return result;
} }
static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
{
GLint result[2];
functions->getIntegerv(name, result);
return result[index];
}
static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
{
GLint64 result;
functions->getInteger64v(name, &result);
return result;
}
static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
{
GLfloat result;
functions->getFloatv(name, &result);
return result;
}
static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
{
GLfloat result[2];
functions->getFloatv(name, result);
return result[index];
}
static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions, GLenum shaderType, GLenum precisionType)
{
gl::TypePrecision precision;
functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range, &precision.precision);
return precision;
}
static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
{
if (*curVersion >= maxVersion)
{
*curVersion = maxVersion;
}
}
void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap,
gl::Extensions *extensions) gl::Extensions *extensions, gl::Version *maxSupportedESVersion)
{ {
// Texture format support checks // Texture format support checks
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
...@@ -109,77 +152,314 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM ...@@ -109,77 +152,314 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
} }
} }
// Set some minimum GLES2 caps, TODO: query for real GL caps // Start by assuming ES3 support and work down
*maxSupportedESVersion = gl::Version(3, 0);
// Table 6.28, implementation dependent values // Table 6.28, implementation dependent values
caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max()); if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE); functions->isAtLeastGLES(gl::Version(3, 0)))
caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); {
caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS); }
caps->maxLODBias = 2.0f; else
caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE); {
caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS); // Doesn't affect ES3 support, can use a pre-defined limit
caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS); caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
caps->maxViewportWidth = caps->max2DTextureSize; }
caps->maxViewportHeight = caps->maxViewportWidth;
caps->minAliasedPointSize = 1.0f; if (functions->isAtLeastGL(gl::Version(1, 2)) ||
caps->maxAliasedPointSize = 1.0f; functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_3D"))
caps->minAliasedLineWidth = 1.0f; {
caps->maxAliasedLineWidth = 1.0f; caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE);
}
else
{
// Can't support ES3 without 3D textures
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); // GL 1.0 / ES 2.0
caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); // GL 1.3 / ES 2.0
if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_texture_array") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
}
else
{
// Can't support ES3 without array textures
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(1, 5)) || functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
}
else
{
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
}
else
{
// Can't support ES2 without framebuffers and renderbuffers
LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
}
if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("ARB_draw_buffers") ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_draw_buffers"))
{
caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
}
else
{
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
caps->maxViewportWidth = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0); // GL 1.0 / ES 2.0
caps->maxViewportHeight = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1); // GL 1.0 / ES 2.0
caps->minAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0);
caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
caps->minAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0); // GL 1.2 / ES 2.0
caps->maxAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1); // GL 1.2 / ES 2.0
// Table 6.29, implementation dependent values (cont.) // Table 6.29, implementation dependent values (cont.)
caps->maxElementsIndices = 0; if (functions->isAtLeastGL(gl::Version(1, 2)) ||
caps->maxElementsVertices = 0; functions->isAtLeastGLES(gl::Version(3, 0)))
caps->vertexHighpFloat.setIEEEFloat(); {
caps->vertexMediumpFloat.setIEEEFloat(); caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
caps->vertexLowpFloat.setIEEEFloat(); caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
caps->fragmentHighpFloat.setIEEEFloat(); }
caps->fragmentMediumpFloat.setIEEEFloat(); else
caps->fragmentLowpFloat.setIEEEFloat(); {
caps->vertexHighpInt.setTwosComplementInt(32); // Doesn't impact supported version
caps->vertexMediumpInt.setTwosComplementInt(32); }
caps->vertexLowpInt.setTwosComplementInt(32);
caps->fragmentHighpInt.setTwosComplementInt(32); // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or GL_ARB_ES2_compatibility exists
caps->fragmentMediumpInt.setTwosComplementInt(32); if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
caps->fragmentLowpInt.setTwosComplementInt(32); functions->isAtLeastGLES(gl::Version(2, 0)))
caps->maxServerWaitTimeout = 0; {
caps->vertexHighpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
caps->vertexLowpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
caps->fragmentMediumpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
caps->fragmentLowpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
caps->vertexHighpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
caps->vertexMediumpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
caps->vertexLowpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
caps->fragmentHighpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
caps->fragmentLowpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
}
else
{
// Doesn't impact supported version, set some default values
caps->vertexHighpFloat.setIEEEFloat();
caps->vertexMediumpFloat.setIEEEFloat();
caps->vertexLowpFloat.setIEEEFloat();
caps->fragmentHighpFloat.setIEEEFloat();
caps->fragmentMediumpFloat.setIEEEFloat();
caps->fragmentLowpFloat.setIEEEFloat();
caps->vertexHighpInt.setTwosComplementInt(32);
caps->vertexMediumpInt.setTwosComplementInt(32);
caps->vertexLowpInt.setTwosComplementInt(32);
caps->fragmentHighpInt.setTwosComplementInt(32);
caps->fragmentMediumpInt.setTwosComplementInt(32);
caps->fragmentLowpInt.setTwosComplementInt(32);
}
if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxServerWaitTimeout = QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT);
}
else
{
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
// Table 6.31, implementation dependent vertex shader limits // Table 6.31, implementation dependent vertex shader limits
caps->maxVertexAttributes = 16; if (functions->isAtLeastGL(gl::Version(2, 0)) ||
caps->maxVertexUniformComponents = 1024; functions->isAtLeastGLES(gl::Version(2, 0)))
caps->maxVertexUniformVectors = 256; {
caps->maxVertexUniformBlocks = 12; caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
caps->maxVertexOutputComponents = 64; caps->maxVertexUniformComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
}
else
{
// Can't support ES2 version without these caps
LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
}
if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
}
else
{
// Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
caps->maxVertexUniformVectors = caps->maxVertexUniformComponents / 4;
}
if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxVertexUniformBlocks = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
}
else
{
// Can't support ES3 without uniform blocks
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(3, 2)) ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxVertexOutputComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
}
else
{
// There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit
// instead of limiting the supported ES version.
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
// Table 6.32, implementation dependent fragment shader limits // Table 6.32, implementation dependent fragment shader limits
caps->maxFragmentUniformComponents = 896; if (functions->isAtLeastGL(gl::Version(2, 0)) ||
caps->maxFragmentUniformVectors = 224; functions->isAtLeastGLES(gl::Version(2, 0)))
caps->maxFragmentUniformBlocks = 12; {
caps->maxFragmentInputComponents = 60; caps->maxFragmentUniformComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS); caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
caps->minProgramTexelOffset = -8; }
caps->maxProgramTexelOffset = 7; else
{
// Can't support ES2 version without these caps
LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
}
if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxFragmentUniformVectors = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
}
else
{
// Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
caps->maxFragmentUniformVectors = caps->maxFragmentUniformComponents / 4;
}
if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxFragmentUniformBlocks = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
}
else
{
// Can't support ES3 without uniform blocks
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(3, 2)) ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxFragmentInputComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
}
else
{
// There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit
// instead of limiting the supported ES version.
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(3, 0)) ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
}
else
{
// Can't support ES3 without texel offset, could possibly be emulated in the shader
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
// Table 6.33, implementation dependent aggregate shader limits // Table 6.33, implementation dependent aggregate shader limits
caps->maxUniformBufferBindings = 24; if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
caps->maxUniformBlockSize = 16384; functions->isAtLeastGLES(gl::Version(3, 0)))
caps->uniformBufferOffsetAlignment = 1; {
caps->maxCombinedUniformBlocks = 24; caps->maxUniformBufferBindings = QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
caps->maxCombinedVertexUniformComponents = (caps->maxVertexUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxVertexUniformComponents; caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
caps->maxCombinedFragmentUniformComponents = (caps->maxFragmentUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxFragmentUniformComponents; caps->uniformBufferOffsetAlignment = QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
caps->maxVaryingComponents = 60; caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentInputComponents;
caps->maxVaryingVectors = 15; caps->maxCombinedVertexUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
caps->maxCombinedFragmentUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
}
else
{
// Can't support ES3 without uniform blocks
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
}
else
{
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
}
else
{
// Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
}
// Determine the max combined texture image units by adding the vertex and fragment limits. If
// the real cap is queried, it would contain the limits for shader types that are not available to ES.
caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
// Table 6.34, implementation dependent transform feedback limits // Table 6.34, implementation dependent transform feedback limits
caps->maxTransformFeedbackInterleavedComponents = 64; if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_transform_feedback") ||
caps->maxTransformFeedbackSeparateAttributes = 4; functions->isAtLeastGLES(gl::Version(3, 0)))
caps->maxTransformFeedbackSeparateComponents = 4; {
caps->maxTransformFeedbackInterleavedComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
caps->maxTransformFeedbackSeparateAttributes = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
caps->maxTransformFeedbackSeparateComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
}
else
{
// Can't support ES3 without transform feedback
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
// Table 6.35, Framebuffer Dependent Values // Table 6.35, Framebuffer Dependent Values
caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES); if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
{
caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES);
}
else
{
LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
}
// Extension support // Extension support
extensions->setTextureExtensionSupport(*textureCapsMap); extensions->setTextureExtensionSupport(*textureCapsMap);
...@@ -188,7 +468,7 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM ...@@ -188,7 +468,7 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
extensions->fboRenderMipmap = true; extensions->fboRenderMipmap = true;
extensions->framebufferBlit = (functions->blitFramebuffer != nullptr); extensions->framebufferBlit = (functions->blitFramebuffer != nullptr);
extensions->framebufferMultisample = caps->maxSamples > 0; extensions->framebufferMultisample = caps->maxSamples > 0;
extensions->fence = std::find(functions->extensions.begin(), functions->extensions.end(), "GL_NV_fence") != functions->extensions.end(); extensions->fence = functions->hasGLExtension("GL_NV_fence") || functions->hasGLESExtension("GL_NV_fence");
} }
} }
......
...@@ -20,6 +20,7 @@ namespace gl ...@@ -20,6 +20,7 @@ namespace gl
struct Caps; struct Caps;
class TextureCapsMap; class TextureCapsMap;
struct Extensions; struct Extensions;
struct Version;
} }
namespace rx namespace rx
...@@ -30,7 +31,7 @@ namespace nativegl_gl ...@@ -30,7 +31,7 @@ namespace nativegl_gl
{ {
void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap,
gl::Extensions *extensions); gl::Extensions *extensions, gl::Version *maxSupportedESVersion);
} }
} }
......
...@@ -370,6 +370,10 @@ egl::ConfigSet DisplayWGL::generateConfigs() const ...@@ -370,6 +370,10 @@ egl::ConfigSet DisplayWGL::generateConfigs() const
maxSwapInterval = 8; maxSwapInterval = 8;
} }
const gl::Version &maxVersion = getMaxSupportedESVersion();
ASSERT(maxVersion >= gl::Version(2, 0));
bool supportsES3 = maxVersion >= gl::Version(3, 0);
PIXELFORMATDESCRIPTOR pixelFormatDescriptor; PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor); DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor);
...@@ -387,7 +391,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const ...@@ -387,7 +391,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const
config.bindToTextureRGBA = (QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_BIND_TO_TEXTURE_RGBA_ARB, mFunctionsWGL) == TRUE); config.bindToTextureRGBA = (QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_BIND_TO_TEXTURE_RGBA_ARB, mFunctionsWGL) == TRUE);
config.colorBufferType = EGL_RGB_BUFFER; config.colorBufferType = EGL_RGB_BUFFER;
config.configCaveat = EGL_NONE; config.configCaveat = EGL_NONE;
config.conformant = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR; // TODO: determine the GL version and what ES versions it supports config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
config.depthSize = pixelFormatDescriptor.cDepthBits; config.depthSize = pixelFormatDescriptor.cDepthBits;
config.level = 0; config.level = 0;
config.matchNativePixmap = EGL_NONE; config.matchNativePixmap = EGL_NONE;
...@@ -399,7 +403,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const ...@@ -399,7 +403,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const
config.nativeRenderable = EGL_TRUE; // Direct rendering config.nativeRenderable = EGL_TRUE; // Direct rendering
config.nativeVisualID = 0; config.nativeVisualID = 0;
config.nativeVisualType = EGL_NONE; config.nativeVisualType = EGL_NONE;
config.renderableType = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR; // TODO config.renderableType = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
config.sampleBuffers = 0; // FIXME: enumerate multi-sampling config.sampleBuffers = 0; // FIXME: enumerate multi-sampling
config.samples = 0; config.samples = 0;
config.stencilSize = pixelFormatDescriptor.cStencilBits; config.stencilSize = pixelFormatDescriptor.cStencilBits;
......
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