summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libGLESv2/Context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/Context.cpp')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp974
1 files changed, 425 insertions, 549 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index 99df85b0d3..5342de1331 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
@@ -1,4 +1,3 @@
-#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -12,6 +11,7 @@
#include "libGLESv2/main.h"
#include "common/utilities.h"
+#include "common/platform.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
@@ -24,7 +24,6 @@
#include "libGLESv2/Texture.h"
#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/RenderTarget.h"
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h"
@@ -33,8 +32,8 @@
#include "libEGL/Surface.h"
-#undef near
-#undef far
+#include <sstream>
+#include <iterator>
namespace gl
{
@@ -45,6 +44,7 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
ASSERT(robustAccess == false); // Unimplemented
initCaps(clientVersion);
+ mState.initialize(mCaps, clientVersion);
mClientVersion = clientVersion;
@@ -66,16 +66,26 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero.set(new Texture2D(mRenderer->createTexture2D(), 0));
- mTextureCubeMapZero.set(new TextureCubeMap(mRenderer->createTextureCube(), 0));
- mTexture3DZero.set(new Texture3D(mRenderer->createTexture3D(), 0));
- mTexture2DArrayZero.set(new Texture2DArray(mRenderer->createTexture2DArray(), 0));
+ mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
+ bindTexture(GL_TEXTURE_2D, 0);
+
+ mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
+ bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+
+ if (mClientVersion >= 3)
+ {
+ // TODO: These could also be enabled via extension
+ mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
+ bindTexture(GL_TEXTURE_3D, 0);
+
+ mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
+ bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+ }
bindVertexArray(0);
bindArrayBuffer(0);
bindElementArrayBuffer(0);
- bindTextureCubeMap(0);
- bindTexture2D(0);
+
bindReadFramebuffer(0);
bindDrawFramebuffer(0);
bindRenderbuffer(0);
@@ -101,23 +111,15 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In the initial state, a default transform feedback object is bound and treated as
// a transform feedback object with a name of zero. That object is bound any time
// BindTransformFeedback is called with id of zero
- mTransformFeedbackZero.set(new TransformFeedback(0));
+ mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0));
bindTransformFeedback(0);
- mInvalidEnum = false;
- mInvalidValue = false;
- mInvalidOperation = false;
- mOutOfMemory = false;
- mInvalidFramebufferOperation = false;
-
mHasBeenCurrent = false;
mContextLost = false;
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
- mNumCompressedTextureFormats = 0;
-
mState.setContext(this);
}
@@ -161,15 +163,17 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
}
- for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
+ for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
{
- mIncompleteTextures[type].set(NULL);
+ i->second.set(NULL);
}
+ mIncompleteTextures.clear();
- mTexture2DZero.set(NULL);
- mTextureCubeMapZero.set(NULL);
- mTexture3DZero.set(NULL);
- mTexture2DArrayZero.set(NULL);
+ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+ {
+ i->second.set(NULL);
+ }
+ mZeroTextures.clear();
mResourceManager->release();
}
@@ -178,23 +182,6 @@ void Context::makeCurrent(egl::Surface *surface)
{
if (!mHasBeenCurrent)
{
- mMajorShaderModel = mRenderer->getMajorShaderModel();
- mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
-
- mNumCompressedTextureFormats = 0;
- if (mExtensions.textureCompressionDXT1)
- {
- mNumCompressedTextureFormats += 2;
- }
- if (mExtensions.textureCompressionDXT3)
- {
- mNumCompressedTextureFormats += 1;
- }
- if (mExtensions.textureCompressionDXT5)
- {
- mNumCompressedTextureFormats += 1;
- }
-
initRendererString();
initExtensionStrings();
@@ -287,7 +274,7 @@ GLuint Context::createSampler()
GLuint Context::createTransformFeedback()
{
GLuint handle = mTransformFeedbackAllocator.allocate();
- TransformFeedback *transformFeedback = new TransformFeedback(handle);
+ TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle);
transformFeedback->addRef();
mTransformFeedbackMap[handle] = transformFeedback;
return handle;
@@ -528,32 +515,11 @@ void Context::bindElementArrayBuffer(unsigned int buffer)
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
}
-void Context::bindTexture2D(GLuint texture)
+void Context::bindTexture(GLenum target, GLuint texture)
{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
+ mResourceManager->checkTextureAllocation(texture, target);
- mState.setSamplerTexture(TEXTURE_2D, getTexture(texture));
-}
-
-void Context::bindTextureCubeMap(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
-
- mState.setSamplerTexture(TEXTURE_CUBE, getTexture(texture));
-}
-
-void Context::bindTexture3D(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
-
- mState.setSamplerTexture(TEXTURE_3D, getTexture(texture));
-}
-
-void Context::bindTexture2DArray(GLuint texture)
-{
- mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
-
- mState.setSamplerTexture(TEXTURE_2D_ARRAY, getTexture(texture));
+ mState.setSamplerTexture(target, getTexture(texture));
}
void Context::bindReadFramebuffer(GLuint framebuffer)
@@ -596,7 +562,7 @@ void Context::bindVertexArray(GLuint vertexArray)
void Context::bindSampler(GLuint textureUnit, GLuint sampler)
{
- ASSERT(textureUnit < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS); // TODO: Update for backend-determined array size
+ ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits);
mResourceManager->checkSamplerAllocation(sampler);
mState.setSamplerBinding(textureUnit, getSampler(sampler));
@@ -678,7 +644,7 @@ void Context::linkProgram(GLuint program)
{
Program *programObject = mResourceManager->getProgram(program);
- bool linked = programObject->link();
+ bool linked = programObject->link(getCaps());
// if the current program was relinked successfully we
// need to install the new executables
@@ -688,11 +654,11 @@ void Context::linkProgram(GLuint program)
}
}
-void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
+void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
{
Program *programObject = mResourceManager->getProgram(program);
- bool loaded = programObject->setProgramBinary(binary, length);
+ bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
// if the current program was reloaded successfully we
// need to install the new executables
@@ -708,26 +674,35 @@ void Context::bindTransformFeedback(GLuint transformFeedback)
mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback));
}
-void Context::beginQuery(GLenum target, GLuint query)
+Error Context::beginQuery(GLenum target, GLuint query)
{
Query *queryObject = getQuery(query, true, target);
ASSERT(queryObject);
- // set query as active for specified target
+ // begin query
+ Error error = queryObject->begin();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // set query as active for specified target only if begin succeeded
mState.setActiveQuery(target, queryObject);
- // begin query
- queryObject->begin();
+ return Error(GL_NO_ERROR);
}
-void Context::endQuery(GLenum target)
+Error Context::endQuery(GLenum target)
{
Query *queryObject = mState.getActiveQuery(target);
ASSERT(queryObject);
- queryObject->end();
+ gl::Error error = queryObject->end();
+ // Always unbind the query, even if there was an error. This may delete the query object.
mState.setActiveQuery(target, NULL);
+
+ return error;
}
void Context::setFramebufferZero(Framebuffer *buffer)
@@ -755,15 +730,16 @@ void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum inter
RenderbufferStorage *renderbuffer = NULL;
- if (GetDepthBits(internalformat) > 0 && GetStencilBits(internalformat) > 0)
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
{
renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
}
- else if (GetDepthBits(internalformat) > 0)
+ else if (formatInfo.depthBits > 0)
{
renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
}
- else if (GetStencilBits(internalformat) > 0)
+ else if (formatInfo.stencilBits > 0)
{
renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
}
@@ -815,7 +791,7 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
{
if (!query->second && create)
{
- query->second = new Query(mRenderer, type, handle);
+ query->second = new Query(mRenderer->createQuery(type), handle);
query->second->addRef();
}
return query->second;
@@ -841,36 +817,29 @@ Texture *Context::getTargetTexture(GLenum target) const
Texture2D *Context::getTexture2D() const
{
- return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D));
+ return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
}
TextureCubeMap *Context::getTextureCubeMap() const
{
- return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_CUBE));
+ return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
}
Texture3D *Context::getTexture3D() const
{
- return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_3D));
+ return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
}
Texture2DArray *Context::getTexture2DArray() const
{
- return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), TEXTURE_2D_ARRAY));
+ return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
}
-Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
+Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
if (mState.getSamplerTextureId(sampler, type) == 0)
{
- switch (type)
- {
- default: UNREACHABLE();
- case TEXTURE_2D: return mTexture2DZero.get();
- case TEXTURE_CUBE: return mTextureCubeMapZero.get();
- case TEXTURE_3D: return mTexture3DZero.get();
- case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
- }
+ return mZeroTextures.at(type).get();
}
else
{
@@ -921,45 +890,39 @@ void Context::getIntegerv(GLenum pname, GLint *params)
switch (pname)
{
- case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
- case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
- case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break;
- case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
- case GL_MAX_VARYING_COMPONENTS: *params = mRenderer->getMaxVaryingVectors() * 4; break;
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
- case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
- case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break;
+ case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break;
+ case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break;
+ case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break;
case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break;
case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break;
case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break;
- case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
- case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
//case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break;
case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break;
case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break;
- case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break;
- case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break;
- case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break;
- case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break;
- case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break;
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break;
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break;
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break;
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break;
case GL_MAJOR_VERSION: *params = mClientVersion; break;
case GL_MINOR_VERSION: *params = 0; break;
- case GL_MAX_ELEMENTS_INDICES: *params = mRenderer->getMaxRecommendedElementsIndices(); break;
- case GL_MAX_ELEMENTS_VERTICES: *params = mRenderer->getMaxRecommendedElementsVertices(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mRenderer->getMaxTransformFeedbackBuffers(); break;
- case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackSeparateComponents(); break;
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
- params[0] = mNumCompressedTextureFormats;
- break;
- case GL_MAX_SAMPLES_ANGLE:
- *params = static_cast<GLint>(getMaxSupportedSamples());
- break;
+ case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break;
+ case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = mCaps.compressedTextureFormats.size(); break;
+ case GL_MAX_SAMPLES_ANGLE: *params = mExtensions.maxSamples; break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE:
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
{
@@ -978,30 +941,22 @@ void Context::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
- {
- if (mExtensions.textureCompressionDXT1)
- {
- *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- }
- if (mExtensions.textureCompressionDXT3)
- {
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
- }
- if (mExtensions.textureCompressionDXT5)
- {
- *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
- }
- }
+ std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params);
break;
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
*params = mResetStrategy;
break;
- case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
- *params = 1;
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ *params = mCaps.shaderBinaryFormats.size();
break;
- case GL_PROGRAM_BINARY_FORMATS_OES:
- *params = GL_PROGRAM_BINARY_ANGLE;
+ case GL_SHADER_BINARY_FORMATS:
+ std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params);
+ break;
+ case GL_NUM_PROGRAM_BINARY_FORMATS:
+ *params = mCaps.programBinaryFormats.size();
+ break;
+ case GL_PROGRAM_BINARY_FORMATS:
+ std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params);
break;
case GL_NUM_EXTENSIONS:
*params = static_cast<GLint>(mExtensionStrings.size());
@@ -1022,25 +977,16 @@ void Context::getInteger64v(GLenum pname, GLint64 *params)
*params = mCaps.maxElementIndex;
break;
case GL_MAX_UNIFORM_BLOCK_SIZE:
- *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
+ *params = mCaps.maxUniformBlockSize;
break;
case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
- {
- GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
- GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
- *params = uniformBufferComponents + defaultBufferComponents;
- }
+ *params = mCaps.maxCombinedVertexUniformComponents;
break;
case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
- {
- GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
- GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
- *params = uniformBufferComponents + defaultBufferComponents;
- }
+ *params = mCaps.maxCombinedFragmentUniformComponents;
break;
case GL_MAX_SERVER_WAIT_TIMEOUT:
- // We do not wait for server fence objects internally, so report a max timeout of zero.
- *params = 0;
+ *params = mCaps.maxServerWaitTimeout;
break;
default:
UNREACHABLE();
@@ -1087,13 +1033,19 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_COMPRESSED_TEXTURE_FORMATS:
{
*type = GL_INT;
- *numParams = mNumCompressedTextureFormats;
+ *numParams = mCaps.compressedTextureFormats.size();
+ }
+ return true;
+ case GL_PROGRAM_BINARY_FORMATS_OES:
+ {
+ *type = GL_INT;
+ *numParams = mCaps.programBinaryFormats.size();
}
return true;
case GL_SHADER_BINARY_FORMATS:
{
*type = GL_INT;
- *numParams = 0;
+ *numParams = mCaps.shaderBinaryFormats.size();
}
return true;
case GL_MAX_VERTEX_ATTRIBS:
@@ -1162,7 +1114,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
- case GL_PROGRAM_BINARY_FORMATS_OES:
{
*type = GL_INT;
*numParams = 1;
@@ -1360,28 +1311,29 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
// Applies the render target surface, depth stencil surface, viewport rectangle and
// scissor rectangle to the renderer
-bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
+Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
{
Framebuffer *framebufferObject = mState.getDrawFramebuffer();
ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
- mRenderer->applyRenderTarget(framebufferObject);
+ gl::Error error = mRenderer->applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
float nearZ, farZ;
mState.getDepthRange(&nearZ, &farZ);
- if (!mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
- ignoreViewport))
- {
- return false;
- }
+ mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
+ ignoreViewport);
mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
- return true;
+ return gl::Error(GL_NO_ERROR);
}
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
-void Context::applyState(GLenum drawMode)
+Error Context::applyState(GLenum drawMode)
{
Framebuffer *framebufferObject = mState.getDrawFramebuffer();
int samples = framebufferObject->getSamples();
@@ -1390,7 +1342,11 @@ void Context::applyState(GLenum drawMode)
rasterizer.pointDrawMode = (drawMode == GL_POINTS);
rasterizer.multiSample = (samples != 0);
- mRenderer->setRasterizerState(rasterizer);
+ Error error = mRenderer->setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
unsigned int mask = 0;
if (mState.isSampleCoverageEnabled())
@@ -1400,7 +1356,6 @@ void Context::applyState(GLenum drawMode)
mState.getSampleCoverageParams(&coverageValue, &coverageInvert);
if (coverageValue != 0)
{
-
float threshold = 0.5f;
for (int i = 0; i < samples; ++i)
@@ -1424,117 +1379,185 @@ void Context::applyState(GLenum drawMode)
{
mask = 0xFFFFFFFF;
}
- mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
+ error = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
+ rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
- mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
- rasterizer.frontFace == GL_CCW);
+ return Error(GL_NO_ERROR);
}
// Applies the shaders and shader constants to the Direct3D 9 device
-void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
+Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
{
const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
- VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
const Framebuffer *fbo = mState.getDrawFramebuffer();
- mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- programBinary->applyUniforms();
+ return programBinary->applyUniforms();
}
-size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
- TextureType *outTextureTypes, SamplerState *outSamplers)
+Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
{
size_t samplerRange = programBinary->getUsedSamplerRange(type);
+
for (size_t i = 0; i < samplerRange; i++)
{
- outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i); // OpenGL texture image unit index
+ GLenum textureType = programBinary->getSamplerTextureType(type, i);
+ GLint textureUnit = programBinary->getSamplerMapping(type, i, getCaps());
if (textureUnit != -1)
{
- outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
- outTextures[i]->getSamplerStateWithNativeOffset(&outSamplers[i]);
- Sampler *samplerObject = mState.getSampler(textureUnit);
- if (samplerObject)
+ Texture* texture = getSamplerTexture(textureUnit, textureType);
+ if (texture->getSamplerState().swizzleRequired())
{
- samplerObject->getState(&outSamplers[i]);
+ Error error = mRenderer->generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
- else
- {
- outTextures[i] = NULL;
- }
}
- return samplerRange;
+ return Error(GL_NO_ERROR);
}
-void Context::generateSwizzles(Texture *textures[], size_t count)
+Error Context::generateSwizzles(ProgramBinary *programBinary)
{
- for (size_t i = 0; i < count; i++)
+ Error error = generateSwizzles(programBinary, SAMPLER_VERTEX);
+ if (error.isError())
{
- if (textures[i] && textures[i]->getSamplerState().swizzleRequired())
- {
- mRenderer->generateSwizzle(textures[i]);
- }
+ return error;
}
+
+ error = generateSwizzles(programBinary, SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return Error(GL_NO_ERROR);
}
// For each Direct3D sampler of either the pixel or vertex stage,
// looks up the corresponding OpenGL texture image unit and texture type,
// and sets the texture and its addressing/filtering state (or NULL when inactive).
-void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
- size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
- size_t framebufferSerialCount)
+Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
{
- // Range of Direct3D samplers of given sampler type
- size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
- : mRenderer->getMaxVertexTextureImageUnits();
-
- for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
+ size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{
- Texture *texture = textures[samplerIndex];
- const SamplerState &sampler = samplers[samplerIndex];
- TextureType textureType = textureTypes[samplerIndex];
-
- if (texture)
+ GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, getCaps());
+ if (textureUnit != -1)
{
+ SamplerState sampler;
+ Texture* texture = getSamplerTexture(textureUnit, textureType);
+ texture->getSamplerStateWithNativeOffset(&sampler);
+
+ Sampler *samplerObject = mState.getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
// TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler) &&
+ if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
!std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
{
- mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
- mRenderer->setTexture(shaderType, samplerIndex, texture);
- texture->resetDirty();
+ Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = mRenderer->setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
}
else
{
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
Texture *incompleteTexture = getIncompleteTexture(textureType);
- mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
- incompleteTexture->resetDirty();
+ gl::Error error = mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
else
{
- mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
}
}
- for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
+ : mCaps.maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
{
- mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return Error(GL_NO_ERROR);
}
-bool Context::applyUniformBuffers()
+Error Context::applyTextures(ProgramBinary *programBinary)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
+
+ Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Context::applyUniformBuffers()
{
Program *programObject = getProgram(mState.getCurrentProgramId());
ProgramBinary *programBinary = programObject->getProgramBinary();
- std::vector<gl::Buffer*> boundBuffers;
+ std::vector<Buffer*> boundBuffers;
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
{
@@ -1543,7 +1566,7 @@ bool Context::applyUniformBuffers()
if (mState.getIndexedUniformBuffer(blockBinding)->id() == 0)
{
// undefined behaviour
- return false;
+ return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
}
else
{
@@ -1553,7 +1576,7 @@ bool Context::applyUniformBuffers()
}
}
- return programBinary->applyUniformBuffers(boundBuffers);
+ return programBinary->applyUniformBuffers(boundBuffers, getCaps());
}
bool Context::applyTransformFeedbackBuffers()
@@ -1589,28 +1612,25 @@ void Context::markTransformFeedbackUsage()
}
}
-void Context::clear(GLbitfield mask)
+Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
ClearParameters clearParams = mState.getClearParameters(mask);
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
+Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfv can be called to clear the color buffer or depth buffer
@@ -1632,19 +1652,16 @@ void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
clearParams.depthClearValue = values[0];
}
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
+Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferuv can only be called to clear a color buffer
@@ -1656,19 +1673,16 @@ void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *
clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
+Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfv can be called to clear the color buffer or stencil buffer
@@ -1690,19 +1704,16 @@ void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
clearParams.stencilClearValue = values[1];
}
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
+Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
{
if (mState.isRasterizerDiscardEnabled())
{
- return;
+ return Error(GL_NO_ERROR);
}
// glClearBufferfi can only be called to clear a depth stencil buffer
@@ -1712,135 +1723,145 @@ void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int sten
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
- if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
- {
- return;
- }
+ applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
- mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
}
-void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
+Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
{
- gl::Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Framebuffer *framebuffer = mState.getReadFramebuffer();
- bool isSized = IsSizedInternalFormat(format);
- GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type));
- GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, width, mState.getPackAlignment());
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
+ const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
+ GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
- mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(), pixels);
+ return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
+ reinterpret_cast<uint8_t*>(pixels));
}
-void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
+Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
ASSERT(mState.getCurrentProgramId() != 0);
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
- Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
- Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
- TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
- SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
- size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
- generateSwizzles(vsTextures, vsTextureCount);
- generateSwizzles(psTextures, psTextureCount);
+ Error error = generateSwizzles(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
if (!mRenderer->applyPrimitiveType(mode, count))
{
- return;
+ return Error(GL_NO_ERROR);
}
- if (!applyRenderTarget(mode, false))
+ error = applyRenderTarget(mode, false);
+ if (error.isError())
{
- return;
+ return error;
}
- applyState(mode);
+ error = applyState(mode);
+ if (error.isError())
+ {
+ return error;
+ }
- GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
- if (err != GL_NO_ERROR)
+ error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
- applyShaders(programBinary, transformFeedbackActive);
-
- FramebufferTextureSerialArray frameBufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
+ error = applyShaders(programBinary, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
- applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+ error = applyTextures(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
- if (!applyUniformBuffers())
+ error = applyUniformBuffers();
+ if (error.isError())
{
- return;
+ return error;
}
if (!skipDraw(mode))
{
- mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
+ error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
if (transformFeedbackActive)
{
markTransformFeedbackUsage();
}
}
+
+ return gl::Error(GL_NO_ERROR);
}
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
+Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const rx::RangeUI &indexRange)
{
ASSERT(mState.getCurrentProgramId() != 0);
ProgramBinary *programBinary = mState.getCurrentProgramBinary();
programBinary->updateSamplerMapping();
- Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
- size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
-
- Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
- TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
- SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
- size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
-
- generateSwizzles(vsTextures, vsTextureCount);
- generateSwizzles(psTextures, psTextureCount);
+ Error error = generateSwizzles(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
if (!mRenderer->applyPrimitiveType(mode, count))
{
- return;
+ return Error(GL_NO_ERROR);
}
- if (!applyRenderTarget(mode, false))
+ error = applyRenderTarget(mode, false);
+ if (error.isError())
{
- return;
+ return error;
}
- applyState(mode);
+ error = applyState(mode);
+ if (error.isError())
+ {
+ return error;
+ }
VertexArray *vao = mState.getVertexArray();
rx::TranslatedIndexData indexInfo;
- GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (err != GL_NO_ERROR)
+ indexInfo.indexRange = indexRange;
+ error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
- GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
- err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.getVertexAttribCurrentValues(), indexInfo.minIndex, vertexCount, instances);
- if (err != GL_NO_ERROR)
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
+ mState.getVertexAttribCurrentValues(),
+ indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
{
- return gl::error(err);
+ return error;
}
bool transformFeedbackActive = applyTransformFeedbackBuffers();
@@ -1848,23 +1869,34 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
// layer.
ASSERT(!transformFeedbackActive);
- applyShaders(programBinary, transformFeedbackActive);
-
- FramebufferTextureSerialArray frameBufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
+ error = applyShaders(programBinary, transformFeedbackActive);
+ if (error.isError())
+ {
+ return error;
+ }
- applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
- applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
+ error = applyTextures(programBinary);
+ if (error.isError())
+ {
+ return error;
+ }
- if (!applyUniformBuffers())
+ error = applyUniformBuffers();
+ if (error.isError())
{
- return;
+ return error;
}
if (!skipDraw(mode))
{
- mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
}
+
+ return Error(GL_NO_ERROR);
}
// Implements glFlush when block is false, glFinish when block is true
@@ -1873,71 +1905,28 @@ void Context::sync(bool block)
mRenderer->sync(block);
}
-void Context::recordInvalidEnum()
-{
- mInvalidEnum = true;
-}
-
-void Context::recordInvalidValue()
-{
- mInvalidValue = true;
-}
-
-void Context::recordInvalidOperation()
-{
- mInvalidOperation = true;
-}
-
-void Context::recordOutOfMemory()
+void Context::recordError(const Error &error)
{
- mOutOfMemory = true;
-}
-
-void Context::recordInvalidFramebufferOperation()
-{
- mInvalidFramebufferOperation = true;
+ if (error.isError())
+ {
+ mErrors.insert(error.getCode());
+ }
}
// Get one of the recorded errors and clear its flag, if any.
// [OpenGL ES 2.0.24] section 2.5 page 13.
GLenum Context::getError()
{
- if (mInvalidEnum)
- {
- mInvalidEnum = false;
-
- return GL_INVALID_ENUM;
- }
-
- if (mInvalidValue)
+ if (mErrors.empty())
{
- mInvalidValue = false;
-
- return GL_INVALID_VALUE;
- }
-
- if (mInvalidOperation)
- {
- mInvalidOperation = false;
-
- return GL_INVALID_OPERATION;
- }
-
- if (mOutOfMemory)
- {
- mOutOfMemory = false;
-
- return GL_OUT_OF_MEMORY;
+ return GL_NO_ERROR;
}
-
- if (mInvalidFramebufferOperation)
+ else
{
- mInvalidFramebufferOperation = false;
-
- return GL_INVALID_FRAMEBUFFER_OPERATION;
+ GLenum error = *mErrors.begin();
+ mErrors.erase(mErrors.begin());
+ return error;
}
-
- return GL_NO_ERROR;
}
GLenum Context::getResetStatus()
@@ -1989,53 +1978,6 @@ const Extensions &Context::getExtensions() const
return mExtensions;
}
-int Context::getMajorShaderModel() const
-{
- return mMajorShaderModel;
-}
-
-unsigned int Context::getMaximumCombinedTextureImageUnits() const
-{
- return mRenderer->getMaxCombinedTextureImageUnits();
-}
-
-unsigned int Context::getMaximumCombinedUniformBufferBindings() const
-{
- return mRenderer->getMaxVertexShaderUniformBuffers() +
- mRenderer->getMaxFragmentShaderUniformBuffers();
-}
-
-int Context::getMaxSupportedSamples() const
-{
- return mRenderer->getMaxSupportedSamples();
-}
-
-GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
-{
- return mRenderer->getMaxSupportedFormatSamples(internalFormat);
-}
-
-GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
-{
- return mRenderer->getNumSampleCounts(internalFormat);
-}
-
-void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
-{
- mRenderer->getSampleCounts(internalFormat, bufSize, params);
-}
-
-unsigned int Context::getMaxTransformFeedbackBufferBindings() const
-{
- return mRenderer->getMaxTransformFeedbackBuffers();
-}
-
-GLintptr Context::getUniformBufferOffsetAlignment() const
-{
- // setting a large alignment forces uniform buffers to bind with zero offset
- return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
-}
-
void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
{
Framebuffer *framebuffer = mState.getReadFramebuffer();
@@ -2044,9 +1986,12 @@ void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, G
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
ASSERT(attachment);
- *internalFormat = attachment->getActualFormat();
- *format = gl::GetFormat(attachment->getActualFormat());
- *type = gl::GetType(attachment->getActualFormat());
+ GLenum actualFormat = attachment->getActualFormat();
+ const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
+
+ *internalFormat = actualFormat;
+ *format = actualFormatInfo.format;
+ *type = actualFormatInfo.type;
}
void Context::detachTexture(GLuint texture)
@@ -2127,32 +2072,31 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler);
}
-Texture *Context::getIncompleteTexture(TextureType type)
+Texture *Context::getIncompleteTexture(GLenum type)
{
- Texture *t = mIncompleteTextures[type].get();
-
- if (t == NULL)
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
{
const GLubyte color[] = { 0, 0, 0, 255 };
const PixelUnpackState incompleteUnpackState(1);
+ Texture* t = NULL;
switch (type)
{
default:
UNREACHABLE();
// default falls through to TEXTURE_2D
- case TEXTURE_2D:
+ case GL_TEXTURE_2D:
{
- Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture2D(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2d;
}
break;
- case TEXTURE_CUBE:
+ case GL_TEXTURE_CUBE_MAP:
{
- TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTextureCube(), Texture::INCOMPLETE_TEXTURE_ID);
+ TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
@@ -2165,18 +2109,18 @@ Texture *Context::getIncompleteTexture(TextureType type)
}
break;
- case TEXTURE_3D:
+ case GL_TEXTURE_3D:
{
- Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture3D(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), Texture::INCOMPLETE_TEXTURE_ID);
incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete3d;
}
break;
- case TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
{
- Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture2DArray(), Texture::INCOMPLETE_TEXTURE_ID);
+ Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), Texture::INCOMPLETE_TEXTURE_ID);
incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
t = incomplete2darray;
@@ -2187,7 +2131,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
mIncompleteTextures[type].set(t);
}
- return t;
+ return mIncompleteTextures[type].get();
}
bool Context::skipDraw(GLenum drawMode)
@@ -2359,14 +2303,16 @@ size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray
FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
if (attachment && attachment->isTexture())
{
- (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
+ Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
}
}
FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
if (depthStencilAttachment && depthStencilAttachment->isTexture())
{
- (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
+ Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
}
std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
@@ -2396,114 +2342,19 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
blitDepth = true;
}
- gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
- gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+ Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
if (blitRenderTarget || blitDepth || blitStencil)
{
- const gl::Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
+ const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
blitRenderTarget, blitDepth, blitStencil, filter);
}
}
-void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
- GLint x, GLint y, GLsizei width, GLsizei height)
-{
- Framebuffer *frameBuffer = NULL;
- switch (target)
- {
- case GL_FRAMEBUFFER:
- case GL_DRAW_FRAMEBUFFER:
- frameBuffer = mState.getDrawFramebuffer();
- break;
- case GL_READ_FRAMEBUFFER:
- frameBuffer = mState.getReadFramebuffer();
- break;
- default:
- UNREACHABLE();
- }
-
- if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
- {
- for (int i = 0; i < numAttachments; ++i)
- {
- rx::RenderTarget *renderTarget = NULL;
-
- if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
- {
- gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
- if (attachment)
- {
- renderTarget = attachment->getRenderTarget();
- }
- }
- else if (attachments[i] == GL_COLOR)
- {
- gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
- if (attachment)
- {
- renderTarget = attachment->getRenderTarget();
- }
- }
- else
- {
- gl::FramebufferAttachment *attachment = NULL;
- switch (attachments[i])
- {
- case GL_DEPTH_ATTACHMENT:
- case GL_DEPTH:
- attachment = frameBuffer->getDepthbuffer();
- break;
- case GL_STENCIL_ATTACHMENT:
- case GL_STENCIL:
- attachment = frameBuffer->getStencilbuffer();
- break;
- case GL_DEPTH_STENCIL_ATTACHMENT:
- attachment = frameBuffer->getDepthOrStencilbuffer();
- break;
- default:
- UNREACHABLE();
- }
-
- if (attachment)
- {
- renderTarget = attachment->getDepthStencil();
- }
- }
-
- if (renderTarget)
- {
- renderTarget->invalidate(x, y, width, height);
- }
- }
- }
-}
-
-bool Context::hasMappedBuffer(GLenum target) const
+void Context::releaseShaderCompiler()
{
- if (target == GL_ARRAY_BUFFER)
- {
- for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
- {
- const gl::VertexAttribute &vertexAttrib = mState.getVertexAttribState(attribIndex);
- gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
- if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
- {
- return true;
- }
- }
- }
- else if (target == GL_ELEMENT_ARRAY_BUFFER)
- {
- Buffer *elementBuffer = mState.getTargetBuffer(target);
- return (elementBuffer && elementBuffer->isMapped());
- }
- else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
- {
- UNIMPLEMENTED();
- }
- else UNREACHABLE();
- return false;
+ mRenderer->releaseShaderCompiler();
}
void Context::initCaps(GLuint clientVersion)
@@ -2524,20 +2375,45 @@ void Context::initCaps(GLuint clientVersion)
//mExtensions.sRGB = false;
}
+ // Apply implementation limits
+ mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
+ mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+ mCaps.maxVertexOutputComponents = std::min<GLuint>(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+ mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+ GLuint maxSamples = 0;
+ mCaps.compressedTextureFormats.clear();
+
const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps();
for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++)
{
GLenum format = i->first;
TextureCaps formatCaps = i->second;
- if (formatCaps.texturable && IsValidInternalFormat(format, mExtensions, clientVersion))
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+
+ // Update the format caps based on the client version and extensions
+ formatCaps.texturable = formatInfo.textureSupport(clientVersion, mExtensions);
+ formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions);
+ formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions);
+
+ // OpenGL ES does not support multisampling with integer formats
+ if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT)
+ {
+ formatCaps.sampleCounts.clear();
+ }
+ maxSamples = std::max(maxSamples, formatCaps.getMaxSamples());
+
+ if (formatCaps.texturable && formatInfo.compressed)
{
- // Update the format caps based on the client version and extensions
- formatCaps.renderable = IsRenderingSupported(format, mExtensions, clientVersion);
- formatCaps.filterable = IsFilteringSupported(format, mExtensions, clientVersion);
- mTextureCaps.insert(format, formatCaps);
+ mCaps.compressedTextureFormats.push_back(format);
}
+
+ mTextureCaps.insert(format, formatCaps);
}
+
+ mExtensions.maxSamples = maxSamples;
}
}