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
};
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)
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()
egl::Error DisplayGL::initialize(egl::Display *display)
{
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);
}
......@@ -63,4 +70,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS
return glDrawSurface->makeCurrent();
}
const gl::Version &DisplayGL::getMaxSupportedESVersion() const
{
ASSERT(mRenderer != nullptr);
return mRenderer->getMaxSupportedESVersion();
}
}
......@@ -31,6 +31,9 @@ class DisplayGL : public DisplayImpl
egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
protected:
const gl::Version &getMaxSupportedESVersion() const;
private:
virtual const FunctionsGL *getFunctionsGL() const = 0;
......
......@@ -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.|
|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)
|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)||
......@@ -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_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_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.|
|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()
// Extensions
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
......@@ -1615,4 +1621,14 @@ bool FunctionsGL::hasExtension(const std::string &ext) const
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
// Extensions
std::vector<std::string> extensions;
bool hasExtension(const std::string &ext) const;
bool hasGLExtension(const std::string &ext) const;
bool hasGLESExtension(const std::string &ext) const;
// Entry Points
// 1.0
......
......@@ -80,6 +80,7 @@ namespace rx
RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap)
: Renderer(),
mMaxSupportedESVersion(0, 0),
mFunctions(functions),
mStateManager(nullptr),
mSkipDrawCalls(false)
......@@ -279,9 +280,17 @@ std::string RendererGL::getRendererDescription() const
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
{
nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions);
nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
}
Workarounds RendererGL::generateWorkarounds() const
......
......@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_
#define LIBANGLE_RENDERER_GL_RENDERERGL_H_
#include "libANGLE/Version.h"
#include "libANGLE/renderer/Renderer.h"
namespace rx
......@@ -70,10 +71,14 @@ class RendererGL : public Renderer
std::string getVendorString() const override;
std::string getRendererDescription() const override;
const gl::Version &getMaxSupportedESVersion() const;
private:
void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const override;
Workarounds generateWorkarounds() const override;
mutable gl::Version mMaxSupportedESVersion;
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
......
......@@ -93,8 +93,51 @@ static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
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,
gl::Extensions *extensions)
gl::Extensions *extensions, gl::Version *maxSupportedESVersion)
{
// Texture format support checks
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
......@@ -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
caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE);
caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE);
caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE);
caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
caps->maxLODBias = 2.0f;
caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
caps->maxViewportWidth = caps->max2DTextureSize;
caps->maxViewportHeight = caps->maxViewportWidth;
caps->minAliasedPointSize = 1.0f;
caps->maxAliasedPointSize = 1.0f;
caps->minAliasedLineWidth = 1.0f;
caps->maxAliasedLineWidth = 1.0f;
if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
}
else
{
// Doesn't affect ES3 support, can use a pre-defined limit
caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
}
if (functions->isAtLeastGL(gl::Version(1, 2)) ||
functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_3D"))
{
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.)
caps->maxElementsIndices = 0;
caps->maxElementsVertices = 0;
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);
caps->maxServerWaitTimeout = 0;
if (functions->isAtLeastGL(gl::Version(1, 2)) ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
}
else
{
// Doesn't impact supported version
}
// glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or GL_ARB_ES2_compatibility exists
if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
functions->isAtLeastGLES(gl::Version(2, 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
caps->maxVertexAttributes = 16;
caps->maxVertexUniformComponents = 1024;
caps->maxVertexUniformVectors = 256;
caps->maxVertexUniformBlocks = 12;
caps->maxVertexOutputComponents = 64;
caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
if (functions->isAtLeastGL(gl::Version(2, 0)) ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
caps->maxVertexUniformComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
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
caps->maxFragmentUniformComponents = 896;
caps->maxFragmentUniformVectors = 224;
caps->maxFragmentUniformBlocks = 12;
caps->maxFragmentInputComponents = 60;
caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
caps->minProgramTexelOffset = -8;
caps->maxProgramTexelOffset = 7;
if (functions->isAtLeastGL(gl::Version(2, 0)) ||
functions->isAtLeastGLES(gl::Version(2, 0)))
{
caps->maxFragmentUniformComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_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->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
caps->maxUniformBufferBindings = 24;
caps->maxUniformBlockSize = 16384;
caps->uniformBufferOffsetAlignment = 1;
caps->maxCombinedUniformBlocks = 24;
caps->maxCombinedVertexUniformComponents = (caps->maxVertexUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxVertexUniformComponents;
caps->maxCombinedFragmentUniformComponents = (caps->maxFragmentUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxFragmentUniformComponents;
caps->maxVaryingComponents = 60;
caps->maxVaryingVectors = 15;
if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
caps->maxUniformBufferBindings = QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
caps->uniformBufferOffsetAlignment = QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentInputComponents;
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;
// Table 6.34, implementation dependent transform feedback limits
caps->maxTransformFeedbackInterleavedComponents = 64;
caps->maxTransformFeedbackSeparateAttributes = 4;
caps->maxTransformFeedbackSeparateComponents = 4;
if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_transform_feedback") ||
functions->isAtLeastGLES(gl::Version(3, 0)))
{
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
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
extensions->setTextureExtensionSupport(*textureCapsMap);
......@@ -188,7 +468,7 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM
extensions->fboRenderMipmap = true;
extensions->framebufferBlit = (functions->blitFramebuffer != nullptr);
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
struct Caps;
class TextureCapsMap;
struct Extensions;
struct Version;
}
namespace rx
......@@ -30,7 +31,7 @@ namespace nativegl_gl
{
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
maxSwapInterval = 8;
}
const gl::Version &maxVersion = getMaxSupportedESVersion();
ASSERT(maxVersion >= gl::Version(2, 0));
bool supportsES3 = maxVersion >= gl::Version(3, 0);
PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor);
......@@ -387,7 +391,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const
config.bindToTextureRGBA = (QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_BIND_TO_TEXTURE_RGBA_ARB, mFunctionsWGL) == TRUE);
config.colorBufferType = EGL_RGB_BUFFER;
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.level = 0;
config.matchNativePixmap = EGL_NONE;
......@@ -399,7 +403,7 @@ egl::ConfigSet DisplayWGL::generateConfigs() const
config.nativeRenderable = EGL_TRUE; // Direct rendering
config.nativeVisualID = 0;
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.samples = 0;
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