blob: 92227b5d77253d8c1137fdf7a6d48746c4c48bf4 [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002//
daniel@transgaming.comb37cd2d2013-01-11 04:10:31 +00003// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
apatrick@chromium.org144f2802012-07-12 01:42:34 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Context.cpp: Implements the gl::Context class, managing all GL state and performing
9// rendering operations. It is the GLES2 specific implementation of EGLContext.
10
11#include "libGLESv2/Context.h"
12
apatrick@chromium.org144f2802012-07-12 01:42:34 +000013#include "libGLESv2/main.h"
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000014#include "common/utilities.h"
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +000015#include "libGLESv2/formatutils.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000016#include "libGLESv2/Buffer.h"
17#include "libGLESv2/Fence.h"
daniel@transgaming.com29ab9522012-08-27 16:25:37 +000018#include "libGLESv2/Framebuffer.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000019#include "libGLESv2/Renderbuffer.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000020#include "libGLESv2/Program.h"
21#include "libGLESv2/ProgramBinary.h"
22#include "libGLESv2/Query.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000023#include "libGLESv2/Texture.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000024#include "libGLESv2/ResourceManager.h"
shannon.woods@transgaming.com938ac8d2013-02-28 23:03:06 +000025#include "libGLESv2/renderer/IndexDataManager.h"
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000026#include "libGLESv2/renderer/RenderTarget.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000027#include "libGLESv2/renderer/Renderer.h"
Jamie Madill57a89722013-07-02 11:57:03 -040028#include "libGLESv2/VertexArray.h"
Jamie Madilldc356042013-07-19 16:36:57 -040029#include "libGLESv2/Sampler.h"
Jamie Madill1fc7e2c2014-01-21 16:47:10 -050030#include "libGLESv2/validationES.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000031
32#include "libEGL/Surface.h"
apatrick@chromium.org144f2802012-07-12 01:42:34 +000033
34#undef near
35#undef far
36
37namespace gl
38{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +000039static const char* makeStaticString(const std::string& str)
40{
41 static std::set<std::string> strings;
42 std::set<std::string>::iterator it = strings.find(str);
43 if (it != strings.end())
44 return it->c_str();
45
46 return strings.insert(str).first->c_str();
47}
48
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +000049Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
apatrick@chromium.org144f2802012-07-12 01:42:34 +000050{
51 ASSERT(robustAccess == false); // Unimplemented
52
Jamie Madill33dc8432013-07-26 11:55:05 -040053 mFenceNVHandleAllocator.setBaseHandle(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +000054
55 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
56
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +000057 mClientVersion = clientVersion;
58
apatrick@chromium.org144f2802012-07-12 01:42:34 +000059 mState.depthClearValue = 1.0f;
60 mState.stencilClearValue = 0;
61
Geoff Lang0550d032014-01-30 11:29:07 -050062 mState.rasterizer.rasterizerDiscard = false;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000063 mState.rasterizer.cullFace = false;
64 mState.rasterizer.cullMode = GL_BACK;
65 mState.rasterizer.frontFace = GL_CCW;
66 mState.rasterizer.polygonOffsetFill = false;
67 mState.rasterizer.polygonOffsetFactor = 0.0f;
68 mState.rasterizer.polygonOffsetUnits = 0.0f;
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +000069 mState.rasterizer.pointDrawMode = false;
Nicolas Capensfd396552013-06-18 21:41:30 -040070 mState.rasterizer.multiSample = false;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +000071 mState.scissorTest = false;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000072 mState.scissor.x = 0;
73 mState.scissor.y = 0;
74 mState.scissor.width = 0;
75 mState.scissor.height = 0;
76
77 mState.blend.blend = false;
78 mState.blend.sourceBlendRGB = GL_ONE;
79 mState.blend.sourceBlendAlpha = GL_ONE;
80 mState.blend.destBlendRGB = GL_ZERO;
81 mState.blend.destBlendAlpha = GL_ZERO;
82 mState.blend.blendEquationRGB = GL_FUNC_ADD;
83 mState.blend.blendEquationAlpha = GL_FUNC_ADD;
84 mState.blend.sampleAlphaToCoverage = false;
85 mState.blend.dither = true;
86
apatrick@chromium.org144f2802012-07-12 01:42:34 +000087 mState.blendColor.red = 0;
88 mState.blendColor.green = 0;
89 mState.blendColor.blue = 0;
90 mState.blendColor.alpha = 0;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000091
92 mState.depthStencil.depthTest = false;
93 mState.depthStencil.depthFunc = GL_LESS;
94 mState.depthStencil.depthMask = true;
95 mState.depthStencil.stencilTest = false;
96 mState.depthStencil.stencilFunc = GL_ALWAYS;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +000097 mState.depthStencil.stencilMask = -1;
98 mState.depthStencil.stencilWritemask = -1;
99 mState.depthStencil.stencilBackFunc = GL_ALWAYS;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000100 mState.depthStencil.stencilBackMask = - 1;
101 mState.depthStencil.stencilBackWritemask = -1;
102 mState.depthStencil.stencilFail = GL_KEEP;
103 mState.depthStencil.stencilPassDepthFail = GL_KEEP;
104 mState.depthStencil.stencilPassDepthPass = GL_KEEP;
105 mState.depthStencil.stencilBackFail = GL_KEEP;
106 mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
107 mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
108
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000109 mState.stencilRef = 0;
110 mState.stencilBackRef = 0;
111
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000112 mState.sampleCoverage = false;
113 mState.sampleCoverageValue = 1.0f;
114 mState.sampleCoverageInvert = false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000115 mState.generateMipmapHint = GL_DONT_CARE;
116 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
117
118 mState.lineWidth = 1.0f;
119
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000120 mState.viewport.x = 0;
121 mState.viewport.y = 0;
122 mState.viewport.width = 0;
123 mState.viewport.height = 0;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000124 mState.zNear = 0.0f;
125 mState.zFar = 1.0f;
126
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000127 mState.blend.colorMaskRed = true;
128 mState.blend.colorMaskGreen = true;
129 mState.blend.colorMaskBlue = true;
130 mState.blend.colorMaskAlpha = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000131
Geoff Lang7dca1862013-07-30 16:30:46 -0400132 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
133 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
134 {
135 mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
136 }
137
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000138 if (shareContext != NULL)
139 {
140 mResourceManager = shareContext->mResourceManager;
141 mResourceManager->addRef();
142 }
143 else
144 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000145 mResourceManager = new ResourceManager(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000146 }
147
148 // [OpenGL ES 2.0.24] section 3.7 page 83:
149 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
150 // and cube map texture state vectors respectively associated with them.
151 // In order that access to these initial textures not be lost, they are treated as texture
152 // objects all of whose names are 0.
153
daniel@transgaming.com370482e2012-11-28 19:32:13 +0000154 mTexture2DZero.set(new Texture2D(mRenderer, 0));
155 mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000156 mTexture3DZero.set(new Texture3D(mRenderer, 0));
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000157 mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000158
Jamie Madilldc356042013-07-19 16:36:57 -0400159 for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
160 {
161 mState.samplers[textureUnit] = 0;
162 }
163
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000164 mState.activeSampler = 0;
Jamie Madill57a89722013-07-02 11:57:03 -0400165 bindVertexArray(0);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000166 bindArrayBuffer(0);
167 bindElementArrayBuffer(0);
168 bindTextureCubeMap(0);
169 bindTexture2D(0);
170 bindReadFramebuffer(0);
171 bindDrawFramebuffer(0);
172 bindRenderbuffer(0);
173
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000174 bindGenericUniformBuffer(0);
175 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
176 {
177 bindIndexedUniformBuffer(0, i, 0, -1);
178 }
179
180 bindGenericTransformFeedbackBuffer(0);
181 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
182 {
183 bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
184 }
185
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000186 bindCopyReadBuffer(0);
187 bindCopyWriteBuffer(0);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000188 bindPixelPackBuffer(0);
189 bindPixelUnpackBuffer(0);
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000190
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000191 mState.currentProgram = 0;
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000192 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000193
shannonwoods@chromium.org302df742013-05-30 00:05:54 +0000194 mCombinedExtensionsString = NULL;
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +0000195 mRendererString = NULL;
196
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000197 mInvalidEnum = false;
198 mInvalidValue = false;
199 mInvalidOperation = false;
200 mOutOfMemory = false;
201 mInvalidFramebufferOperation = false;
202
203 mHasBeenCurrent = false;
204 mContextLost = false;
205 mResetStatus = GL_NO_ERROR;
206 mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
207 mRobustAccess = robustAccess;
208
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +0000209 mSupportsBGRATextures = false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000210 mSupportsDXT1Textures = false;
211 mSupportsDXT3Textures = false;
212 mSupportsDXT5Textures = false;
213 mSupportsEventQueries = false;
214 mSupportsOcclusionQueries = false;
215 mNumCompressedTextureFormats = 0;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000216}
217
218Context::~Context()
219{
220 if (mState.currentProgram != 0)
221 {
222 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
223 if (programObject)
224 {
225 programObject->release();
226 }
227 mState.currentProgram = 0;
228 }
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000229 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000230
231 while (!mFramebufferMap.empty())
232 {
233 deleteFramebuffer(mFramebufferMap.begin()->first);
234 }
235
Jamie Madill33dc8432013-07-26 11:55:05 -0400236 while (!mFenceNVMap.empty())
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000237 {
Jamie Madill33dc8432013-07-26 11:55:05 -0400238 deleteFenceNV(mFenceNVMap.begin()->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000239 }
240
241 while (!mQueryMap.empty())
242 {
243 deleteQuery(mQueryMap.begin()->first);
244 }
245
Jamie Madill57a89722013-07-02 11:57:03 -0400246 while (!mVertexArrayMap.empty())
247 {
248 deleteVertexArray(mVertexArrayMap.begin()->first);
249 }
250
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000251 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
252 {
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +0000253 for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000254 {
255 mState.samplerTexture[type][sampler].set(NULL);
256 }
257 }
258
259 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
260 {
261 mIncompleteTextures[type].set(NULL);
262 }
263
Jamie Madilla857c362013-07-02 11:57:02 -0400264 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
265 for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000266 {
Jamie Madilla857c362013-07-02 11:57:02 -0400267 mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000268 }
269
270 for (int i = 0; i < QUERY_TYPE_COUNT; i++)
271 {
272 mState.activeQuery[i].set(NULL);
273 }
274
275 mState.arrayBuffer.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000276 mState.renderbuffer.set(NULL);
277
278 mTexture2DZero.set(NULL);
279 mTextureCubeMapZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +0000280 mTexture3DZero.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +0000281 mTexture2DArrayZero.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000282
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000283 mState.genericUniformBuffer.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000284 for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
285 {
286 mState.uniformBuffers[i].set(NULL);
287 }
288
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +0000289 mState.genericTransformFeedbackBuffer.set(NULL);
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +0000290 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
291 {
292 mState.transformFeedbackBuffers[i].set(NULL);
293 }
294
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +0000295 mState.copyReadBuffer.set(NULL);
296 mState.copyWriteBuffer.set(NULL);
297
Jamie Madill950a7752013-09-18 14:36:18 -0400298 mState.pack.pixelBuffer.set(NULL);
299 mState.unpack.pixelBuffer.set(NULL);
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +0000300
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000301 mResourceManager->release();
302}
303
daniel@transgaming.comad629872012-11-28 19:32:06 +0000304void Context::makeCurrent(egl::Surface *surface)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000305{
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000306 if (!mHasBeenCurrent)
307 {
daniel@transgaming.com9549bea2012-11-28 20:57:23 +0000308 mMajorShaderModel = mRenderer->getMajorShaderModel();
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000309 mMaximumPointSize = mRenderer->getMaxPointSize();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000310 mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
311 mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
312 mSupportsInstancing = mRenderer->getInstancingSupport();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000313
shannon.woods@transgaming.com8ce2f8f2013-02-28 23:07:10 +0000314 mMaxViewportDimension = mRenderer->getMaxViewportDimension();
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +0000315 mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
316 (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
317 mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
318 mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()),
319 (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +0000320 mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers();
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +0000321 mMaxRenderbufferDimension = mMax2DTextureDimension;
Geoff Langce635692013-09-24 13:56:32 -0400322 mMax2DTextureLevel = log2(mMax2DTextureDimension) + 1;
323 mMaxCubeTextureLevel = log2(mMaxCubeTextureDimension) + 1;
324 mMax3DTextureLevel = log2(mMax3DTextureDimension) + 1;
325 mMax2DArrayTextureLevel = log2(mMax2DTextureDimension) + 1;
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000326 mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +0000327 TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, "
Geoff Langce635692013-09-24 13:56:32 -0400328 "Max2DTextureLevel=%d, MaxCubeTextureLevel=%d, Max3DTextureLevel=%d, Max2DArrayTextureLevel=%d, "
329 "MaxRenderbufferDimension=%d, MaxTextureAnisotropy=%f",
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +0000330 mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers,
Geoff Langce635692013-09-24 13:56:32 -0400331 mMax2DTextureLevel, mMaxCubeTextureLevel, mMax3DTextureLevel, mMax2DArrayTextureLevel,
332 mMaxRenderbufferDimension, mMaxTextureAnisotropy);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000333
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000334 mSupportsEventQueries = mRenderer->getEventQuerySupport();
335 mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +0000336 mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000337 mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
338 mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
339 mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
shannonwoods@chromium.org89200d92013-05-30 00:07:50 +0000340 mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport();
341 mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport();
342 mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport();
343 mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport();
344 mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport();
345 mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000346 mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
347 mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
Geoff Lang632192d2013-10-04 13:40:46 -0400348 mSupportsRGTextures = mRenderer->getRGTextureSupport();
daniel@transgaming.com621ce052012-10-31 17:52:29 +0000349 mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
daniel@transgaming.comba0570e2012-10-31 18:07:39 +0000350 mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
daniel@transgaming.com5f4c1362012-10-31 18:29:00 +0000351 mSupports32bitIndices = mRenderer->get32BitIndexSupport();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000352
353 mNumCompressedTextureFormats = 0;
354 if (supportsDXT1Textures())
355 {
356 mNumCompressedTextureFormats += 2;
357 }
358 if (supportsDXT3Textures())
359 {
360 mNumCompressedTextureFormats += 1;
361 }
362 if (supportsDXT5Textures())
363 {
364 mNumCompressedTextureFormats += 1;
365 }
366
367 initExtensionString();
368 initRendererString();
369
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000370 mState.viewport.x = 0;
371 mState.viewport.y = 0;
372 mState.viewport.width = surface->getWidth();
373 mState.viewport.height = surface->getHeight();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000374
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000375 mState.scissor.x = 0;
376 mState.scissor.y = 0;
377 mState.scissor.width = surface->getWidth();
378 mState.scissor.height = surface->getHeight();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000379
380 mHasBeenCurrent = true;
381 }
382
daniel@transgaming.com024786d2012-10-31 18:42:55 +0000383 // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
daniel@transgaming.com76d3e6e2012-10-31 19:55:33 +0000384 rx::SwapChain *swapchain = surface->getSwapChain();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000385
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000386 Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
387 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
daniel@transgaming.com16418b12012-11-28 19:32:22 +0000388 Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000389
390 setFramebufferZero(framebufferZero);
shannon.woods%transgaming.com@gtempaccount.com785f1962013-04-13 03:34:45 +0000391
392 // Store the current client version in the renderer
393 mRenderer->setCurrentClientVersion(mClientVersion);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000394}
395
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +0000396// NOTE: this function should not assume that this context is current!
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000397void Context::markContextLost()
398{
399 if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
400 mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
401 mContextLost = true;
402}
403
404bool Context::isContextLost()
405{
406 return mContextLost;
407}
408
Geoff Lang0550d032014-01-30 11:29:07 -0500409void Context::setCap(GLenum cap, bool enabled)
410{
411 switch (cap)
412 {
413 case GL_CULL_FACE: setCullFace(enabled); break;
414 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
415 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
416 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
417 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
418 case GL_STENCIL_TEST: setStencilTest(enabled); break;
419 case GL_DEPTH_TEST: setDepthTest(enabled); break;
420 case GL_BLEND: setBlend(enabled); break;
421 case GL_DITHER: setDither(enabled); break;
422 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
423 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
424 default: UNREACHABLE();
425 }
426}
427
428bool Context::getCap(GLenum cap)
429{
430 switch (cap)
431 {
432 case GL_CULL_FACE: return isCullFaceEnabled();
433 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
434 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
435 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
436 case GL_SCISSOR_TEST: return isScissorTestEnabled();
437 case GL_STENCIL_TEST: return isStencilTestEnabled();
438 case GL_DEPTH_TEST: return isDepthTestEnabled();
439 case GL_BLEND: return isBlendEnabled();
440 case GL_DITHER: return isDitherEnabled();
441 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
442 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
443 default: UNREACHABLE(); return false;
444 }
445}
446
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000447void Context::setClearColor(float red, float green, float blue, float alpha)
448{
449 mState.colorClearValue.red = red;
450 mState.colorClearValue.green = green;
451 mState.colorClearValue.blue = blue;
452 mState.colorClearValue.alpha = alpha;
453}
454
455void Context::setClearDepth(float depth)
456{
457 mState.depthClearValue = depth;
458}
459
460void Context::setClearStencil(int stencil)
461{
462 mState.stencilClearValue = stencil;
463}
464
Geoff Lang0550d032014-01-30 11:29:07 -0500465void Context::setRasterizerDiscard(bool enabled)
466{
467 mState.rasterizer.rasterizerDiscard = enabled;
468}
469
470bool Context::isRasterizerDiscardEnabled() const
471{
472 return mState.rasterizer.rasterizerDiscard;
473}
474
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000475void Context::setCullFace(bool enabled)
476{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000477 mState.rasterizer.cullFace = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000478}
479
480bool Context::isCullFaceEnabled() const
481{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000482 return mState.rasterizer.cullFace;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000483}
484
485void Context::setCullMode(GLenum mode)
486{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000487 mState.rasterizer.cullMode = mode;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000488}
489
490void Context::setFrontFace(GLenum front)
491{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000492 mState.rasterizer.frontFace = front;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000493}
494
495void Context::setDepthTest(bool enabled)
496{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000497 mState.depthStencil.depthTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000498}
499
500bool Context::isDepthTestEnabled() const
501{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000502 return mState.depthStencil.depthTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000503}
504
505void Context::setDepthFunc(GLenum depthFunc)
506{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000507 mState.depthStencil.depthFunc = depthFunc;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000508}
509
510void Context::setDepthRange(float zNear, float zFar)
511{
512 mState.zNear = zNear;
513 mState.zFar = zFar;
514}
515
516void Context::setBlend(bool enabled)
517{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000518 mState.blend.blend = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000519}
520
521bool Context::isBlendEnabled() const
522{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000523 return mState.blend.blend;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000524}
525
526void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
527{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000528 mState.blend.sourceBlendRGB = sourceRGB;
529 mState.blend.destBlendRGB = destRGB;
530 mState.blend.sourceBlendAlpha = sourceAlpha;
531 mState.blend.destBlendAlpha = destAlpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000532}
533
534void Context::setBlendColor(float red, float green, float blue, float alpha)
535{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000536 mState.blendColor.red = red;
537 mState.blendColor.green = green;
538 mState.blendColor.blue = blue;
539 mState.blendColor.alpha = alpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000540}
541
542void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
543{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000544 mState.blend.blendEquationRGB = rgbEquation;
545 mState.blend.blendEquationAlpha = alphaEquation;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000546}
547
548void Context::setStencilTest(bool enabled)
549{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000550 mState.depthStencil.stencilTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000551}
552
553bool Context::isStencilTestEnabled() const
554{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000555 return mState.depthStencil.stencilTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000556}
557
558void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
559{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000560 mState.depthStencil.stencilFunc = stencilFunc;
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000561 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000562 mState.depthStencil.stencilMask = stencilMask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000563}
564
565void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
566{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000567 mState.depthStencil.stencilBackFunc = stencilBackFunc;
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000568 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000569 mState.depthStencil.stencilBackMask = stencilBackMask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000570}
571
572void Context::setStencilWritemask(GLuint stencilWritemask)
573{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000574 mState.depthStencil.stencilWritemask = stencilWritemask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000575}
576
577void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
578{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000579 mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000580}
581
582void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
583{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000584 mState.depthStencil.stencilFail = stencilFail;
585 mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
586 mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000587}
588
589void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
590{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000591 mState.depthStencil.stencilBackFail = stencilBackFail;
592 mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
593 mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000594}
595
596void Context::setPolygonOffsetFill(bool enabled)
597{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000598 mState.rasterizer.polygonOffsetFill = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000599}
600
601bool Context::isPolygonOffsetFillEnabled() const
602{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000603 return mState.rasterizer.polygonOffsetFill;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000604}
605
606void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
607{
shannon.woods@transgaming.com31c4f232013-02-28 23:14:18 +0000608 // An application can pass NaN values here, so handle this gracefully
609 mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
610 mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000611}
612
613void Context::setSampleAlphaToCoverage(bool enabled)
614{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000615 mState.blend.sampleAlphaToCoverage = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000616}
617
618bool Context::isSampleAlphaToCoverageEnabled() const
619{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000620 return mState.blend.sampleAlphaToCoverage;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000621}
622
623void Context::setSampleCoverage(bool enabled)
624{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000625 mState.sampleCoverage = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000626}
627
628bool Context::isSampleCoverageEnabled() const
629{
630 return mState.sampleCoverage;
631}
632
633void Context::setSampleCoverageParams(GLclampf value, bool invert)
634{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000635 mState.sampleCoverageValue = value;
636 mState.sampleCoverageInvert = invert;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000637}
638
639void Context::setScissorTest(bool enabled)
640{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000641 mState.scissorTest = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000642}
643
644bool Context::isScissorTestEnabled() const
645{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000646 return mState.scissorTest;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000647}
648
649void Context::setDither(bool enabled)
650{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000651 mState.blend.dither = enabled;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000652}
653
654bool Context::isDitherEnabled() const
655{
daniel@transgaming.comf39967e2012-11-28 19:35:56 +0000656 return mState.blend.dither;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000657}
658
659void Context::setLineWidth(GLfloat width)
660{
661 mState.lineWidth = width;
662}
663
664void Context::setGenerateMipmapHint(GLenum hint)
665{
666 mState.generateMipmapHint = hint;
667}
668
669void Context::setFragmentShaderDerivativeHint(GLenum hint)
670{
671 mState.fragmentShaderDerivativeHint = hint;
672 // TODO: Propagate the hint to shader translator so we can write
673 // ddx, ddx_coarse, or ddx_fine depending on the hint.
674 // Ignore for now. It is valid for implementations to ignore hint.
675}
676
677void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
678{
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +0000679 mState.viewport.x = x;
680 mState.viewport.y = y;
681 mState.viewport.width = width;
682 mState.viewport.height = height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000683}
684
685void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
686{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000687 mState.scissor.x = x;
688 mState.scissor.y = y;
689 mState.scissor.width = width;
690 mState.scissor.height = height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000691}
692
Geoff Langc8325162013-08-09 13:26:56 -0400693void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height)
694{
695 *x = mState.scissor.x;
696 *y = mState.scissor.y;
697 *width = mState.scissor.width;
698 *height = mState.scissor.height;
699}
700
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000701void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
702{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000703 mState.blend.colorMaskRed = red;
704 mState.blend.colorMaskGreen = green;
705 mState.blend.colorMaskBlue = blue;
706 mState.blend.colorMaskAlpha = alpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000707}
708
709void Context::setDepthMask(bool mask)
710{
daniel@transgaming.com2e258642012-11-28 19:36:18 +0000711 mState.depthStencil.depthMask = mask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000712}
713
714void Context::setActiveSampler(unsigned int active)
715{
716 mState.activeSampler = active;
717}
718
719GLuint Context::getReadFramebufferHandle() const
720{
721 return mState.readFramebuffer;
722}
723
724GLuint Context::getDrawFramebufferHandle() const
725{
726 return mState.drawFramebuffer;
727}
728
729GLuint Context::getRenderbufferHandle() const
730{
731 return mState.renderbuffer.id();
732}
733
Jamie Madilld8db8662013-07-02 11:57:04 -0400734GLuint Context::getVertexArrayHandle() const
735{
736 return mState.vertexArray;
737}
738
Jamie Madilldc356042013-07-19 16:36:57 -0400739GLuint Context::getSamplerHandle(GLuint textureUnit) const
740{
741 ASSERT(textureUnit < ArraySize(mState.samplers));
742 return mState.samplers[textureUnit];
743}
744
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000745GLuint Context::getArrayBufferHandle() const
746{
747 return mState.arrayBuffer.id();
748}
749
750GLuint Context::getActiveQuery(GLenum target) const
751{
752 Query *queryObject = NULL;
753
754 switch (target)
755 {
756 case GL_ANY_SAMPLES_PASSED_EXT:
757 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get();
758 break;
759 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
760 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get();
761 break;
762 default:
763 ASSERT(false);
764 }
765
766 if (queryObject)
767 {
768 return queryObject->id();
769 }
770 else
771 {
772 return 0;
773 }
774}
775
776void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
777{
Jamie Madill57a89722013-07-02 11:57:03 -0400778 getCurrentVertexArray()->enableAttribute(attribNum, enabled);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000779}
780
Jamie Madilla857c362013-07-02 11:57:02 -0400781const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000782{
Jamie Madill57a89722013-07-02 11:57:03 -0400783 return getCurrentVertexArray()->getVertexAttribute(attribNum);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000784}
785
Jamie Madilla857c362013-07-02 11:57:02 -0400786const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
787{
788 ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
789 return mState.vertexAttribCurrentValues[attribNum];
790}
791
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000792void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
shannon.woods%transgaming.com@gtempaccount.com8de4e6a2013-04-13 03:37:44 +0000793 bool pureInteger, GLsizei stride, const void *pointer)
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000794{
Jamie Madill57a89722013-07-02 11:57:03 -0400795 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000796}
797
798const void *Context::getVertexAttribPointer(unsigned int attribNum) const
799{
Jamie Madill57a89722013-07-02 11:57:03 -0400800 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000801}
802
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000803void Context::setPackAlignment(GLint alignment)
804{
Jamie Madill950a7752013-09-18 14:36:18 -0400805 mState.pack.alignment = alignment;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000806}
807
808GLint Context::getPackAlignment() const
809{
Jamie Madill950a7752013-09-18 14:36:18 -0400810 return mState.pack.alignment;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000811}
812
813void Context::setUnpackAlignment(GLint alignment)
814{
Jamie Madill950a7752013-09-18 14:36:18 -0400815 mState.unpack.alignment = alignment;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000816}
817
818GLint Context::getUnpackAlignment() const
819{
Jamie Madill950a7752013-09-18 14:36:18 -0400820 return mState.unpack.alignment;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000821}
822
823void Context::setPackReverseRowOrder(bool reverseRowOrder)
824{
Jamie Madill950a7752013-09-18 14:36:18 -0400825 mState.pack.reverseRowOrder = reverseRowOrder;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000826}
827
828bool Context::getPackReverseRowOrder() const
829{
Jamie Madill950a7752013-09-18 14:36:18 -0400830 return mState.pack.reverseRowOrder;
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000831}
832
Jamie Madill88f18f42013-09-18 14:36:19 -0400833const PixelUnpackState &Context::getUnpackState() const
834{
835 return mState.unpack;
836}
837
838const PixelPackState &Context::getPackState() const
839{
840 return mState.pack;
841}
842
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000843GLuint Context::createBuffer()
844{
845 return mResourceManager->createBuffer();
846}
847
848GLuint Context::createProgram()
849{
850 return mResourceManager->createProgram();
851}
852
853GLuint Context::createShader(GLenum type)
854{
855 return mResourceManager->createShader(type);
856}
857
858GLuint Context::createTexture()
859{
860 return mResourceManager->createTexture();
861}
862
863GLuint Context::createRenderbuffer()
864{
865 return mResourceManager->createRenderbuffer();
866}
867
Jamie Madillcd055f82013-07-26 11:55:15 -0400868GLsync Context::createFenceSync(GLenum condition)
869{
870 GLuint handle = mResourceManager->createFenceSync();
871
872 gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
873 ASSERT(fenceSync);
874
875 fenceSync->set(condition);
876
877 return reinterpret_cast<GLsync>(handle);
878}
879
Jamie Madill57a89722013-07-02 11:57:03 -0400880GLuint Context::createVertexArray()
881{
882 GLuint handle = mVertexArrayHandleAllocator.allocate();
883
Jamie Madilld1028542013-07-02 11:57:04 -0400884 // Although the spec states VAO state is not initialized until the object is bound,
885 // we create it immediately. The resulting behaviour is transparent to the application,
886 // since it's not currently possible to access the state until the object is bound.
Jamie Madill57a89722013-07-02 11:57:03 -0400887 mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
888
889 return handle;
890}
891
Jamie Madilldc356042013-07-19 16:36:57 -0400892GLuint Context::createSampler()
893{
894 return mResourceManager->createSampler();
895}
896
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000897// Returns an unused framebuffer name
898GLuint Context::createFramebuffer()
899{
900 GLuint handle = mFramebufferHandleAllocator.allocate();
901
902 mFramebufferMap[handle] = NULL;
903
904 return handle;
905}
906
Jamie Madill33dc8432013-07-26 11:55:05 -0400907GLuint Context::createFenceNV()
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000908{
Jamie Madill33dc8432013-07-26 11:55:05 -0400909 GLuint handle = mFenceNVHandleAllocator.allocate();
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000910
Jamie Madill33dc8432013-07-26 11:55:05 -0400911 mFenceNVMap[handle] = new FenceNV(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000912
913 return handle;
914}
915
916// Returns an unused query name
917GLuint Context::createQuery()
918{
919 GLuint handle = mQueryHandleAllocator.allocate();
920
921 mQueryMap[handle] = NULL;
922
923 return handle;
924}
925
926void Context::deleteBuffer(GLuint buffer)
927{
928 if (mResourceManager->getBuffer(buffer))
929 {
930 detachBuffer(buffer);
931 }
932
933 mResourceManager->deleteBuffer(buffer);
934}
935
936void Context::deleteShader(GLuint shader)
937{
938 mResourceManager->deleteShader(shader);
939}
940
941void Context::deleteProgram(GLuint program)
942{
943 mResourceManager->deleteProgram(program);
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000944}
945
946void Context::deleteTexture(GLuint texture)
947{
948 if (mResourceManager->getTexture(texture))
949 {
950 detachTexture(texture);
951 }
952
953 mResourceManager->deleteTexture(texture);
954}
955
956void Context::deleteRenderbuffer(GLuint renderbuffer)
957{
958 if (mResourceManager->getRenderbuffer(renderbuffer))
959 {
960 detachRenderbuffer(renderbuffer);
961 }
962
963 mResourceManager->deleteRenderbuffer(renderbuffer);
964}
965
Jamie Madillcd055f82013-07-26 11:55:15 -0400966void Context::deleteFenceSync(GLsync fenceSync)
967{
968 // The spec specifies the underlying Fence object is not deleted until all current
969 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
970 // and since our API is currently designed for being called from a single thread, we can delete
971 // the fence immediately.
972 mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
973}
974
Jamie Madill57a89722013-07-02 11:57:03 -0400975void Context::deleteVertexArray(GLuint vertexArray)
976{
977 auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
978
979 if (vertexArrayObject != mVertexArrayMap.end())
980 {
981 detachVertexArray(vertexArray);
982
983 mVertexArrayHandleAllocator.release(vertexArrayObject->first);
984 delete vertexArrayObject->second;
985 mVertexArrayMap.erase(vertexArrayObject);
986 }
987}
988
Jamie Madilldc356042013-07-19 16:36:57 -0400989void Context::deleteSampler(GLuint sampler)
990{
991 if (mResourceManager->getSampler(sampler))
992 {
993 detachSampler(sampler);
994 }
995
996 mResourceManager->deleteSampler(sampler);
997}
998
apatrick@chromium.org144f2802012-07-12 01:42:34 +0000999void Context::deleteFramebuffer(GLuint framebuffer)
1000{
1001 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
1002
1003 if (framebufferObject != mFramebufferMap.end())
1004 {
1005 detachFramebuffer(framebuffer);
1006
1007 mFramebufferHandleAllocator.release(framebufferObject->first);
1008 delete framebufferObject->second;
1009 mFramebufferMap.erase(framebufferObject);
1010 }
1011}
1012
Jamie Madill33dc8432013-07-26 11:55:05 -04001013void Context::deleteFenceNV(GLuint fence)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001014{
Jamie Madill33dc8432013-07-26 11:55:05 -04001015 FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001016
Jamie Madill33dc8432013-07-26 11:55:05 -04001017 if (fenceObject != mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001018 {
Jamie Madill33dc8432013-07-26 11:55:05 -04001019 mFenceNVHandleAllocator.release(fenceObject->first);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001020 delete fenceObject->second;
Jamie Madill33dc8432013-07-26 11:55:05 -04001021 mFenceNVMap.erase(fenceObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001022 }
1023}
1024
1025void Context::deleteQuery(GLuint query)
1026{
1027 QueryMap::iterator queryObject = mQueryMap.find(query);
1028 if (queryObject != mQueryMap.end())
1029 {
1030 mQueryHandleAllocator.release(queryObject->first);
1031 if (queryObject->second)
1032 {
1033 queryObject->second->release();
1034 }
1035 mQueryMap.erase(queryObject);
1036 }
1037}
1038
1039Buffer *Context::getBuffer(GLuint handle)
1040{
1041 return mResourceManager->getBuffer(handle);
1042}
1043
1044Shader *Context::getShader(GLuint handle)
1045{
1046 return mResourceManager->getShader(handle);
1047}
1048
1049Program *Context::getProgram(GLuint handle)
1050{
1051 return mResourceManager->getProgram(handle);
1052}
1053
1054Texture *Context::getTexture(GLuint handle)
1055{
1056 return mResourceManager->getTexture(handle);
1057}
1058
1059Renderbuffer *Context::getRenderbuffer(GLuint handle)
1060{
1061 return mResourceManager->getRenderbuffer(handle);
1062}
1063
Jamie Madillcd055f82013-07-26 11:55:15 -04001064FenceSync *Context::getFenceSync(GLsync handle) const
1065{
1066 return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
1067}
1068
Jamie Madill57a89722013-07-02 11:57:03 -04001069VertexArray *Context::getVertexArray(GLuint handle) const
1070{
1071 auto vertexArray = mVertexArrayMap.find(handle);
1072
1073 if (vertexArray == mVertexArrayMap.end())
1074 {
1075 return NULL;
1076 }
1077 else
1078 {
1079 return vertexArray->second;
1080 }
1081}
1082
Jamie Madilldc356042013-07-19 16:36:57 -04001083Sampler *Context::getSampler(GLuint handle) const
1084{
1085 return mResourceManager->getSampler(handle);
1086}
1087
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001088Framebuffer *Context::getReadFramebuffer()
1089{
1090 return getFramebuffer(mState.readFramebuffer);
1091}
1092
1093Framebuffer *Context::getDrawFramebuffer()
1094{
1095 return mBoundDrawFramebuffer;
1096}
1097
Jamie Madill57a89722013-07-02 11:57:03 -04001098VertexArray *Context::getCurrentVertexArray() const
1099{
1100 VertexArray *vao = getVertexArray(mState.vertexArray);
1101 ASSERT(vao != NULL);
1102 return vao;
1103}
1104
Jamie Madilldc356042013-07-19 16:36:57 -04001105bool Context::isSampler(GLuint samplerName) const
1106{
1107 return mResourceManager->isSampler(samplerName);
1108}
1109
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001110void Context::bindArrayBuffer(unsigned int buffer)
1111{
1112 mResourceManager->checkBufferAllocation(buffer);
1113
1114 mState.arrayBuffer.set(getBuffer(buffer));
1115}
1116
1117void Context::bindElementArrayBuffer(unsigned int buffer)
1118{
1119 mResourceManager->checkBufferAllocation(buffer);
1120
Jamie Madill57a89722013-07-02 11:57:03 -04001121 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001122}
1123
1124void Context::bindTexture2D(GLuint texture)
1125{
1126 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
1127
1128 mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
1129}
1130
1131void Context::bindTextureCubeMap(GLuint texture)
1132{
1133 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
1134
1135 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
1136}
1137
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001138void Context::bindTexture3D(GLuint texture)
1139{
1140 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
1141
1142 mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));
1143}
1144
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001145void Context::bindTexture2DArray(GLuint texture)
1146{
1147 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
1148
1149 mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture));
1150}
1151
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001152void Context::bindReadFramebuffer(GLuint framebuffer)
1153{
1154 if (!getFramebuffer(framebuffer))
1155 {
daniel@transgaming.com16418b12012-11-28 19:32:22 +00001156 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001157 }
1158
1159 mState.readFramebuffer = framebuffer;
1160}
1161
1162void Context::bindDrawFramebuffer(GLuint framebuffer)
1163{
1164 if (!getFramebuffer(framebuffer))
1165 {
daniel@transgaming.com16418b12012-11-28 19:32:22 +00001166 mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001167 }
1168
1169 mState.drawFramebuffer = framebuffer;
1170
1171 mBoundDrawFramebuffer = getFramebuffer(framebuffer);
1172}
1173
1174void Context::bindRenderbuffer(GLuint renderbuffer)
1175{
1176 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1177
1178 mState.renderbuffer.set(getRenderbuffer(renderbuffer));
1179}
1180
Jamie Madill57a89722013-07-02 11:57:03 -04001181void Context::bindVertexArray(GLuint vertexArray)
1182{
1183 if (!getVertexArray(vertexArray))
1184 {
1185 mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
1186 }
1187
1188 mState.vertexArray = vertexArray;
1189}
1190
Jamie Madilldc356042013-07-19 16:36:57 -04001191void Context::bindSampler(GLuint textureUnit, GLuint sampler)
1192{
1193 ASSERT(textureUnit < ArraySize(mState.samplers));
1194 mResourceManager->checkSamplerAllocation(sampler);
1195
1196 mState.samplers[textureUnit] = sampler;
1197}
1198
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001199void Context::bindGenericUniformBuffer(GLuint buffer)
1200{
1201 mResourceManager->checkBufferAllocation(buffer);
1202
1203 mState.genericUniformBuffer.set(getBuffer(buffer));
1204}
1205
1206void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001207{
1208 mResourceManager->checkBufferAllocation(buffer);
1209
1210 mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
1211}
1212
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001213void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1214{
1215 mResourceManager->checkBufferAllocation(buffer);
1216
1217 mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
1218}
1219
1220void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00001221{
1222 mResourceManager->checkBufferAllocation(buffer);
1223
1224 mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size);
1225}
1226
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001227void Context::bindCopyReadBuffer(GLuint buffer)
1228{
1229 mResourceManager->checkBufferAllocation(buffer);
1230
1231 mState.copyReadBuffer.set(getBuffer(buffer));
1232}
1233
1234void Context::bindCopyWriteBuffer(GLuint buffer)
1235{
1236 mResourceManager->checkBufferAllocation(buffer);
1237
1238 mState.copyWriteBuffer.set(getBuffer(buffer));
1239}
1240
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001241void Context::bindPixelPackBuffer(GLuint buffer)
1242{
1243 mResourceManager->checkBufferAllocation(buffer);
1244
Jamie Madill950a7752013-09-18 14:36:18 -04001245 mState.pack.pixelBuffer.set(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001246}
1247
1248void Context::bindPixelUnpackBuffer(GLuint buffer)
1249{
1250 mResourceManager->checkBufferAllocation(buffer);
1251
Jamie Madill950a7752013-09-18 14:36:18 -04001252 mState.unpack.pixelBuffer.set(getBuffer(buffer));
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001253}
1254
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001255void Context::useProgram(GLuint program)
1256{
1257 GLuint priorProgram = mState.currentProgram;
1258 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
1259
1260 if (priorProgram != program)
1261 {
1262 Program *newProgram = mResourceManager->getProgram(program);
1263 Program *oldProgram = mResourceManager->getProgram(priorProgram);
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001264 mCurrentProgramBinary.set(NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001265
1266 if (newProgram)
1267 {
1268 newProgram->addRef();
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001269 mCurrentProgramBinary.set(newProgram->getProgramBinary());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001270 }
1271
1272 if (oldProgram)
1273 {
1274 oldProgram->release();
1275 }
1276 }
1277}
1278
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001279void Context::linkProgram(GLuint program)
1280{
1281 Program *programObject = mResourceManager->getProgram(program);
1282
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001283 bool linked = programObject->link();
1284
1285 // if the current program was relinked successfully we
1286 // need to install the new executables
1287 if (linked && program == mState.currentProgram)
1288 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001289 mCurrentProgramBinary.set(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001290 }
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001291}
1292
1293void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
1294{
1295 Program *programObject = mResourceManager->getProgram(program);
1296
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001297 bool loaded = programObject->setProgramBinary(binary, length);
1298
1299 // if the current program was reloaded successfully we
1300 // need to install the new executables
1301 if (loaded && program == mState.currentProgram)
1302 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001303 mCurrentProgramBinary.set(programObject->getProgramBinary());
daniel@transgaming.com12394cf2012-07-24 18:37:59 +00001304 }
1305
daniel@transgaming.com95d29422012-07-24 18:36:10 +00001306}
1307
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001308void Context::beginQuery(GLenum target, GLuint query)
1309{
1310 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1311 // of zero, if the active query object name for <target> is non-zero (for the
1312 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1313 // the active query for either target is non-zero), if <id> is the name of an
1314 // existing query object whose type does not match <target>, or if <id> is the
1315 // active query object name for any query type, the error INVALID_OPERATION is
1316 // generated.
1317
1318 // Ensure no other queries are active
1319 // NOTE: If other queries than occlusion are supported, we will need to check
1320 // separately that:
1321 // a) The query ID passed is not the current active query for any target/type
1322 // b) There are no active queries for the requested target (and in the case
1323 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1324 // no query may be active for either if glBeginQuery targets either.
1325 for (int i = 0; i < QUERY_TYPE_COUNT; i++)
1326 {
1327 if (mState.activeQuery[i].get() != NULL)
1328 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001329 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001330 }
1331 }
1332
1333 QueryType qType;
1334 switch (target)
1335 {
1336 case GL_ANY_SAMPLES_PASSED_EXT:
1337 qType = QUERY_ANY_SAMPLES_PASSED;
1338 break;
1339 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1340 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1341 break;
1342 default:
1343 ASSERT(false);
1344 return;
1345 }
1346
1347 Query *queryObject = getQuery(query, true, target);
1348
1349 // check that name was obtained with glGenQueries
1350 if (!queryObject)
1351 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001352 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001353 }
1354
1355 // check for type mismatch
1356 if (queryObject->getType() != target)
1357 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001358 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001359 }
1360
1361 // set query as active for specified target
1362 mState.activeQuery[qType].set(queryObject);
1363
1364 // begin query
1365 queryObject->begin();
1366}
1367
1368void Context::endQuery(GLenum target)
1369{
1370 QueryType qType;
1371
1372 switch (target)
1373 {
1374 case GL_ANY_SAMPLES_PASSED_EXT:
1375 qType = QUERY_ANY_SAMPLES_PASSED;
1376 break;
1377 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1378 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1379 break;
1380 default:
1381 ASSERT(false);
1382 return;
1383 }
1384
1385 Query *queryObject = mState.activeQuery[qType].get();
1386
1387 if (queryObject == NULL)
1388 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001389 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001390 }
1391
1392 queryObject->end();
1393
1394 mState.activeQuery[qType].set(NULL);
1395}
1396
1397void Context::setFramebufferZero(Framebuffer *buffer)
1398{
1399 delete mFramebufferMap[0];
1400 mFramebufferMap[0] = buffer;
1401 if (mState.drawFramebuffer == 0)
1402 {
1403 mBoundDrawFramebuffer = buffer;
1404 }
1405}
1406
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001407void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001408{
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001409 const bool color = gl::IsColorRenderingSupported(internalformat, this);
1410 const bool depth = gl::IsDepthRenderingSupported(internalformat, this);
1411 const bool stencil = gl::IsStencilRenderingSupported(internalformat, this);
1412
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001413 RenderbufferStorage *renderbuffer = NULL;
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001414
1415 if (color)
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001416 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001417 renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001418 }
1419 else if (depth && stencil)
1420 {
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001421 renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
Geoff Lang2e1dcd52013-05-29 10:34:08 -04001422 }
1423 else if (depth)
1424 {
1425 renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
1426 }
1427 else if (stencil)
1428 {
1429 renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
1430 }
1431 else
1432 {
1433 UNREACHABLE();
1434 return;
daniel@transgaming.com70062c92012-11-28 19:32:30 +00001435 }
1436
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001437 Renderbuffer *renderbufferObject = mState.renderbuffer.get();
1438 renderbufferObject->setStorage(renderbuffer);
1439}
1440
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001441Framebuffer *Context::getFramebuffer(unsigned int handle) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001442{
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001443 FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001444
1445 if (framebuffer == mFramebufferMap.end())
1446 {
1447 return NULL;
1448 }
1449 else
1450 {
1451 return framebuffer->second;
1452 }
1453}
1454
Jamie Madill33dc8432013-07-26 11:55:05 -04001455FenceNV *Context::getFenceNV(unsigned int handle)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001456{
Jamie Madill33dc8432013-07-26 11:55:05 -04001457 FenceNVMap::iterator fence = mFenceNVMap.find(handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001458
Jamie Madill33dc8432013-07-26 11:55:05 -04001459 if (fence == mFenceNVMap.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001460 {
1461 return NULL;
1462 }
1463 else
1464 {
1465 return fence->second;
1466 }
1467}
1468
1469Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1470{
1471 QueryMap::iterator query = mQueryMap.find(handle);
1472
1473 if (query == mQueryMap.end())
1474 {
1475 return NULL;
1476 }
1477 else
1478 {
1479 if (!query->second && create)
1480 {
shannon.woods@transgaming.comb32e1982013-02-28 23:02:59 +00001481 query->second = new Query(mRenderer, type, handle);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001482 query->second->addRef();
1483 }
1484 return query->second;
1485 }
1486}
1487
1488Buffer *Context::getArrayBuffer()
1489{
1490 return mState.arrayBuffer.get();
1491}
1492
1493Buffer *Context::getElementArrayBuffer()
1494{
Jamie Madill57a89722013-07-02 11:57:03 -04001495 return getCurrentVertexArray()->getElementArrayBuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001496}
1497
daniel@transgaming.com62a28462012-07-24 18:33:59 +00001498ProgramBinary *Context::getCurrentProgramBinary()
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001499{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +00001500 return mCurrentProgramBinary.get();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001501}
1502
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001503Texture *Context::getTargetTexture(GLenum target) const
1504{
1505 if (!ValidTextureTarget(this, target))
1506 {
1507 return NULL;
1508 }
1509
1510 switch (target)
1511 {
1512 case GL_TEXTURE_2D: return getTexture2D();
1513 case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
1514 case GL_TEXTURE_3D: return getTexture3D();
1515 case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
1516 default: return NULL;
1517 }
1518}
1519
1520GLuint Context::getTargetFramebufferHandle(GLenum target) const
1521{
1522 if (!ValidFramebufferTarget(target))
1523 {
1524 return GL_INVALID_INDEX;
1525 }
1526
1527 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1528 {
1529 return mState.readFramebuffer;
1530 }
1531 else
1532 {
1533 return mState.drawFramebuffer;
1534 }
1535}
1536
1537Framebuffer *Context::getTargetFramebuffer(GLenum target) const
1538{
1539 GLuint framebufferHandle = getTargetFramebufferHandle(target);
1540 return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle));
1541}
1542
1543Texture2D *Context::getTexture2D() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001544{
1545 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1546}
1547
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001548TextureCubeMap *Context::getTextureCubeMap() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001549{
1550 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1551}
1552
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001553Texture3D *Context::getTexture3D() const
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001554{
1555 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1556}
1557
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001558Texture2DArray *Context::getTexture2DArray() const
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001559{
1560 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1561}
1562
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001563Buffer *Context::getGenericUniformBuffer()
1564{
1565 return mState.genericUniformBuffer.get();
1566}
1567
1568Buffer *Context::getGenericTransformFeedbackBuffer()
1569{
1570 return mState.genericTransformFeedbackBuffer.get();
1571}
1572
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001573Buffer *Context::getCopyReadBuffer()
1574{
1575 return mState.copyReadBuffer.get();
1576}
1577
1578Buffer *Context::getCopyWriteBuffer()
1579{
1580 return mState.copyWriteBuffer.get();
1581}
1582
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001583Buffer *Context::getPixelPackBuffer()
1584{
Jamie Madill950a7752013-09-18 14:36:18 -04001585 return mState.pack.pixelBuffer.get();
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001586}
1587
1588Buffer *Context::getPixelUnpackBuffer()
1589{
Jamie Madill950a7752013-09-18 14:36:18 -04001590 return mState.unpack.pixelBuffer.get();
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001591}
1592
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001593Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001594{
1595 GLuint texid = mState.samplerTexture[type][sampler].id();
1596
1597 if (texid == 0) // Special case: 0 refers to different initial textures based on the target
1598 {
1599 switch (type)
1600 {
1601 default: UNREACHABLE();
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001602 case TEXTURE_2D: return mTexture2DZero.get();
1603 case TEXTURE_CUBE: return mTextureCubeMapZero.get();
1604 case TEXTURE_3D: return mTexture3DZero.get();
1605 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001606 }
1607 }
1608
1609 return mState.samplerTexture[type][sampler].get();
1610}
1611
1612bool Context::getBooleanv(GLenum pname, GLboolean *params)
1613{
1614 switch (pname)
1615 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001616 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1617 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1618 case GL_DEPTH_WRITEMASK: *params = mState.depthStencil.depthMask; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001619 case GL_COLOR_WRITEMASK:
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001620 params[0] = mState.blend.colorMaskRed;
1621 params[1] = mState.blend.colorMaskGreen;
1622 params[2] = mState.blend.colorMaskBlue;
1623 params[3] = mState.blend.colorMaskAlpha;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001624 break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001625 case GL_CULL_FACE: *params = mState.rasterizer.cullFace; break;
1626 case GL_POLYGON_OFFSET_FILL: *params = mState.rasterizer.polygonOffsetFill; break;
1627 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.blend.sampleAlphaToCoverage; break;
1628 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +00001629 case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001630 case GL_STENCIL_TEST: *params = mState.depthStencil.stencilTest; break;
1631 case GL_DEPTH_TEST: *params = mState.depthStencil.depthTest; break;
1632 case GL_BLEND: *params = mState.blend.blend; break;
1633 case GL_DITHER: *params = mState.blend.dither; break;
1634 case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
shannonwoods@chromium.orgabf14cc2013-05-30 00:20:58 +00001635 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = GL_FALSE; UNIMPLEMENTED(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001636 default:
1637 return false;
1638 }
1639
1640 return true;
1641}
1642
1643bool Context::getFloatv(GLenum pname, GLfloat *params)
1644{
1645 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1646 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1647 // GetIntegerv as its native query function. As it would require conversion in any
1648 // case, this should make no difference to the calling application.
1649 switch (pname)
1650 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001651 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1652 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1653 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1654 case GL_POLYGON_OFFSET_FACTOR: *params = mState.rasterizer.polygonOffsetFactor; break;
1655 case GL_POLYGON_OFFSET_UNITS: *params = mState.rasterizer.polygonOffsetUnits; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001656 case GL_ALIASED_LINE_WIDTH_RANGE:
1657 params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
1658 params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
1659 break;
1660 case GL_ALIASED_POINT_SIZE_RANGE:
1661 params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
1662 params[1] = getMaximumPointSize();
1663 break;
1664 case GL_DEPTH_RANGE:
1665 params[0] = mState.zNear;
1666 params[1] = mState.zFar;
1667 break;
1668 case GL_COLOR_CLEAR_VALUE:
1669 params[0] = mState.colorClearValue.red;
1670 params[1] = mState.colorClearValue.green;
1671 params[2] = mState.colorClearValue.blue;
1672 params[3] = mState.colorClearValue.alpha;
1673 break;
1674 case GL_BLEND_COLOR:
1675 params[0] = mState.blendColor.red;
1676 params[1] = mState.blendColor.green;
1677 params[2] = mState.blendColor.blue;
1678 params[3] = mState.blendColor.alpha;
1679 break;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00001680 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1681 if (!supportsTextureFilterAnisotropy())
1682 {
1683 return false;
1684 }
1685 *params = mMaxTextureAnisotropy;
1686 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001687 default:
1688 return false;
1689 }
1690
1691 return true;
1692}
1693
1694bool Context::getIntegerv(GLenum pname, GLint *params)
1695{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00001696 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1697 {
1698 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1699
1700 if (colorAttachment >= mRenderer->getMaxRenderTargets())
1701 {
1702 // return true to stop further operation in the parent call
1703 return gl::error(GL_INVALID_OPERATION, true);
1704 }
1705
1706 Framebuffer *framebuffer = getDrawFramebuffer();
1707
1708 *params = framebuffer->getDrawBufferState(colorAttachment);
1709 return true;
1710 }
1711
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001712 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1713 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1714 // GetIntegerv as its native query function. As it would require conversion in any
1715 // case, this should make no difference to the calling application. You may find it in
1716 // Context::getFloatv.
1717 switch (pname)
1718 {
Jamie Madill1caff072013-07-19 16:36:56 -04001719 case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
1720 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
1721 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mRenderer->getMaxVertexUniformVectors() * 4; break;
1722 case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
1723 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
1724 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
1725 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
1726 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
1727 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mRenderer->getMaxFragmentUniformVectors() * 4; break;
1728 case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break;
1729 case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
1730 case GL_MAX_DRAW_BUFFERS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
1731 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
1732 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
1733 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
1734 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getCurrentVertexArray()->getElementArrayBufferId(); break;
1735 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1736 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
1737 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
1738 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
1739 case GL_VERTEX_ARRAY_BINDING: *params = mState.vertexArray; break;
1740 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
Jamie Madill950a7752013-09-18 14:36:18 -04001741 case GL_PACK_ALIGNMENT: *params = mState.pack.alignment; break;
1742 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mState.pack.reverseRowOrder; break;
1743 case GL_UNPACK_ALIGNMENT: *params = mState.unpack.alignment; break;
Jamie Madill1caff072013-07-19 16:36:56 -04001744 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
1745 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1746 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
1747 case GL_STENCIL_FUNC: *params = mState.depthStencil.stencilFunc; break;
1748 case GL_STENCIL_REF: *params = mState.stencilRef; break;
Jamie Madillb155bbc2014-01-13 09:51:03 -05001749 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mState.depthStencil.stencilMask); break;
Jamie Madill1caff072013-07-19 16:36:56 -04001750 case GL_STENCIL_BACK_FUNC: *params = mState.depthStencil.stencilBackFunc; break;
1751 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
Jamie Madillb155bbc2014-01-13 09:51:03 -05001752 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mState.depthStencil.stencilBackMask); break;
Jamie Madill1caff072013-07-19 16:36:56 -04001753 case GL_STENCIL_FAIL: *params = mState.depthStencil.stencilFail; break;
1754 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilPassDepthFail; break;
1755 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilPassDepthPass; break;
1756 case GL_STENCIL_BACK_FAIL: *params = mState.depthStencil.stencilBackFail; break;
1757 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilBackPassDepthFail; break;
1758 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilBackPassDepthPass; break;
1759 case GL_DEPTH_FUNC: *params = mState.depthStencil.depthFunc; break;
1760 case GL_BLEND_SRC_RGB: *params = mState.blend.sourceBlendRGB; break;
1761 case GL_BLEND_SRC_ALPHA: *params = mState.blend.sourceBlendAlpha; break;
1762 case GL_BLEND_DST_RGB: *params = mState.blend.destBlendRGB; break;
1763 case GL_BLEND_DST_ALPHA: *params = mState.blend.destBlendAlpha; break;
1764 case GL_BLEND_EQUATION_RGB: *params = mState.blend.blendEquationRGB; break;
1765 case GL_BLEND_EQUATION_ALPHA: *params = mState.blend.blendEquationAlpha; break;
Jamie Madillb155bbc2014-01-13 09:51:03 -05001766 case GL_STENCIL_WRITEMASK: *params = clampToInt(mState.depthStencil.stencilWritemask); break;
1767 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mState.depthStencil.stencilBackWritemask); break;
Jamie Madill1caff072013-07-19 16:36:56 -04001768 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
1769 case GL_SUBPIXEL_BITS: *params = 4; break;
1770 case GL_MAX_TEXTURE_SIZE: *params = getMaximum2DTextureDimension(); break;
1771 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = getMaximumCubeTextureDimension(); break;
1772 case GL_MAX_3D_TEXTURE_SIZE: *params = getMaximum3DTextureDimension(); break;
1773 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = getMaximum2DArrayTextureLayers(); break;
1774 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = getUniformBufferOffsetAlignment(); break;
1775 case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = getMaximumCombinedUniformBufferBindings(); break;
1776 case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mRenderer->getMaxVertexShaderUniformBuffers(); break;
1777 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mRenderer->getMaxFragmentShaderUniformBuffers(); break;
1778 case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = getMaximumCombinedUniformBufferBindings(); break;
Jamie Madillee7010d2013-10-17 10:45:47 -04001779 case GL_MAJOR_VERSION: *params = mClientVersion; break;
1780 case GL_MINOR_VERSION: *params = 0; break;
Jamie Madill13a2f852013-12-11 16:35:08 -05001781 case GL_MAX_ELEMENTS_INDICES: *params = mRenderer->getMaxRecommendedElementsIndices(); break;
1782 case GL_MAX_ELEMENTS_VERTICES: *params = mRenderer->getMaxRecommendedElementsVertices(); break;
Jamie Madill1caff072013-07-19 16:36:56 -04001783 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = 0; UNIMPLEMENTED(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001784 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1785 params[0] = mNumCompressedTextureFormats;
1786 break;
1787 case GL_MAX_SAMPLES_ANGLE:
1788 {
1789 GLsizei maxSamples = getMaxSupportedSamples();
1790 if (maxSamples != 0)
1791 {
1792 *params = maxSamples;
1793 }
1794 else
1795 {
1796 return false;
1797 }
1798
1799 break;
1800 }
1801 case GL_SAMPLE_BUFFERS:
1802 case GL_SAMPLES:
1803 {
1804 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1805 if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1806 {
1807 switch (pname)
1808 {
1809 case GL_SAMPLE_BUFFERS:
1810 if (framebuffer->getSamples() != 0)
1811 {
1812 *params = 1;
1813 }
1814 else
1815 {
1816 *params = 0;
1817 }
1818 break;
1819 case GL_SAMPLES:
1820 *params = framebuffer->getSamples();
1821 break;
1822 }
1823 }
1824 else
1825 {
1826 *params = 0;
1827 }
1828 }
1829 break;
daniel@transgaming.com42944b02012-09-27 17:45:57 +00001830 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1831 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1832 {
Geoff Lang005df412013-10-16 14:12:50 -04001833 GLenum internalFormat, format, type;
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00001834 if (getCurrentReadFormatType(&internalFormat, &format, &type))
daniel@transgaming.com42944b02012-09-27 17:45:57 +00001835 {
1836 if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
1837 *params = format;
1838 else
1839 *params = type;
1840 }
1841 }
1842 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001843 case GL_MAX_VIEWPORT_DIMS:
1844 {
shannon.woods@transgaming.com8ce2f8f2013-02-28 23:07:10 +00001845 params[0] = mMaxViewportDimension;
1846 params[1] = mMaxViewportDimension;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001847 }
1848 break;
1849 case GL_COMPRESSED_TEXTURE_FORMATS:
1850 {
1851 if (supportsDXT1Textures())
1852 {
1853 *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
1854 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1855 }
1856 if (supportsDXT3Textures())
1857 {
1858 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
1859 }
1860 if (supportsDXT5Textures())
1861 {
1862 *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1863 }
1864 }
1865 break;
1866 case GL_VIEWPORT:
daniel@transgaming.com3884e2c2012-11-28 19:41:00 +00001867 params[0] = mState.viewport.x;
1868 params[1] = mState.viewport.y;
1869 params[2] = mState.viewport.width;
1870 params[3] = mState.viewport.height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001871 break;
1872 case GL_SCISSOR_BOX:
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001873 params[0] = mState.scissor.x;
1874 params[1] = mState.scissor.y;
1875 params[2] = mState.scissor.width;
1876 params[3] = mState.scissor.height;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001877 break;
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001878 case GL_CULL_FACE_MODE: *params = mState.rasterizer.cullMode; break;
1879 case GL_FRONT_FACE: *params = mState.rasterizer.frontFace; break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001880 case GL_RED_BITS:
1881 case GL_GREEN_BITS:
1882 case GL_BLUE_BITS:
1883 case GL_ALPHA_BITS:
1884 {
1885 gl::Framebuffer *framebuffer = getDrawFramebuffer();
shannon.woods%transgaming.com@gtempaccount.com882434c2013-04-13 03:34:14 +00001886 gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001887
1888 if (colorbuffer)
1889 {
1890 switch (pname)
1891 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00001892 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1893 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1894 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1895 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001896 }
1897 }
1898 else
1899 {
1900 *params = 0;
1901 }
1902 }
1903 break;
1904 case GL_DEPTH_BITS:
1905 {
1906 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1907 gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1908
1909 if (depthbuffer)
1910 {
1911 *params = depthbuffer->getDepthSize();
1912 }
1913 else
1914 {
1915 *params = 0;
1916 }
1917 }
1918 break;
1919 case GL_STENCIL_BITS:
1920 {
1921 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1922 gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1923
1924 if (stencilbuffer)
1925 {
1926 *params = stencilbuffer->getStencilSize();
1927 }
1928 else
1929 {
1930 *params = 0;
1931 }
1932 }
1933 break;
1934 case GL_TEXTURE_BINDING_2D:
1935 {
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00001936 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001937 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001938 gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001939 return false;
1940 }
1941
1942 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1943 }
1944 break;
1945 case GL_TEXTURE_BINDING_CUBE_MAP:
1946 {
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00001947 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001948 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00001949 gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001950 return false;
1951 }
1952
1953 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1954 }
1955 break;
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00001956 case GL_TEXTURE_BINDING_3D:
1957 {
1958 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1959 {
1960 gl::error(GL_INVALID_OPERATION);
1961 return false;
1962 }
1963
1964 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();
1965 }
1966 break;
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00001967 case GL_TEXTURE_BINDING_2D_ARRAY:
1968 {
1969 if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
1970 {
1971 gl::error(GL_INVALID_OPERATION);
1972 return false;
1973 }
1974
1975 *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id();
1976 }
1977 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00001978 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1979 *params = mResetStrategy;
1980 break;
1981 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1982 *params = 1;
1983 break;
1984 case GL_PROGRAM_BINARY_FORMATS_OES:
1985 *params = GL_PROGRAM_BINARY_ANGLE;
1986 break;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00001987 case GL_UNIFORM_BUFFER_BINDING:
1988 *params = mState.genericUniformBuffer.id();
1989 break;
1990 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1991 *params = mState.genericTransformFeedbackBuffer.id();
1992 break;
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00001993 case GL_COPY_READ_BUFFER_BINDING:
1994 *params = mState.copyReadBuffer.id();
1995 break;
1996 case GL_COPY_WRITE_BUFFER_BINDING:
1997 *params = mState.copyWriteBuffer.id();
1998 break;
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00001999 case GL_PIXEL_PACK_BUFFER_BINDING:
Jamie Madill950a7752013-09-18 14:36:18 -04002000 *params = mState.pack.pixelBuffer.id();
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00002001 break;
2002 case GL_PIXEL_UNPACK_BUFFER_BINDING:
Jamie Madill950a7752013-09-18 14:36:18 -04002003 *params = mState.unpack.pixelBuffer.id();
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00002004 break;
Geoff Lang23c81692013-08-12 10:46:58 -04002005 case GL_NUM_EXTENSIONS:
2006 *params = static_cast<GLint>(getNumExtensions());
2007 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002008 default:
2009 return false;
2010 }
2011
2012 return true;
2013}
2014
Jamie Madill0fda9862013-07-19 16:36:55 -04002015bool Context::getInteger64v(GLenum pname, GLint64 *params)
2016{
2017 switch (pname)
2018 {
2019 case GL_MAX_ELEMENT_INDEX:
2020 *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
2021 break;
2022 case GL_MAX_UNIFORM_BLOCK_SIZE:
2023 *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
2024 break;
2025 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2026 {
2027 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
2028 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
2029 *params = uniformBufferComponents + defaultBufferComponents;
2030 }
2031 break;
2032 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2033 {
2034 GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
2035 GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
2036 *params = uniformBufferComponents + defaultBufferComponents;
2037 }
2038 break;
2039 case GL_MAX_SERVER_WAIT_TIMEOUT:
Jamie Madill5215e1a2013-07-26 11:55:19 -04002040 // We do not wait for server fence objects internally, so report a max timeout of zero.
2041 *params = 0;
Jamie Madill0fda9862013-07-19 16:36:55 -04002042 break;
2043 default:
2044 return false;
2045 }
2046
2047 return true;
2048}
2049
Shannon Woods1b2fb852013-08-19 14:28:48 -04002050bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
2051{
2052 switch (target)
2053 {
2054 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2055 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2056 {
2057 *data = mState.transformFeedbackBuffers[index].id();
2058 }
2059 break;
2060 case GL_UNIFORM_BUFFER_BINDING:
2061 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2062 {
2063 *data = mState.uniformBuffers[index].id();
2064 }
2065 break;
2066 default:
2067 return false;
2068 }
2069
2070 return true;
2071}
2072
2073bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
2074{
2075 switch (target)
2076 {
2077 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2078 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2079 {
2080 *data = mState.transformFeedbackBuffers[index].getOffset();
2081 }
2082 break;
2083 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2084 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2085 {
2086 *data = mState.transformFeedbackBuffers[index].getSize();
2087 }
2088 break;
2089 case GL_UNIFORM_BUFFER_START:
2090 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2091 {
2092 *data = mState.uniformBuffers[index].getOffset();
2093 }
2094 break;
2095 case GL_UNIFORM_BUFFER_SIZE:
2096 if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2097 {
2098 *data = mState.uniformBuffers[index].getSize();
2099 }
2100 break;
2101 default:
2102 return false;
2103 }
2104
2105 return true;
2106}
2107
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002108bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
2109{
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00002110 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2111 {
2112 *type = GL_INT;
2113 *numParams = 1;
2114 return true;
2115 }
2116
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002117 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2118 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2119 // to the fact that it is stored internally as a float, and so would require conversion
2120 // if returned from Context::getIntegerv. Since this conversion is already implemented
2121 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2122 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2123 // application.
2124 switch (pname)
2125 {
2126 case GL_COMPRESSED_TEXTURE_FORMATS:
2127 {
2128 *type = GL_INT;
2129 *numParams = mNumCompressedTextureFormats;
2130 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002131 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002132 case GL_SHADER_BINARY_FORMATS:
2133 {
2134 *type = GL_INT;
2135 *numParams = 0;
2136 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002137 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002138 case GL_MAX_VERTEX_ATTRIBS:
2139 case GL_MAX_VERTEX_UNIFORM_VECTORS:
2140 case GL_MAX_VARYING_VECTORS:
2141 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2142 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2143 case GL_MAX_TEXTURE_IMAGE_UNITS:
2144 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2145 case GL_MAX_RENDERBUFFER_SIZE:
shannon.woods%transgaming.com@gtempaccount.com9790c472013-04-13 03:28:23 +00002146 case GL_MAX_COLOR_ATTACHMENTS_EXT:
shannon.woods%transgaming.com@gtempaccount.combc373e52013-04-13 03:31:23 +00002147 case GL_MAX_DRAW_BUFFERS_EXT:
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002148 case GL_NUM_SHADER_BINARY_FORMATS:
2149 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2150 case GL_ARRAY_BUFFER_BINDING:
2151 case GL_FRAMEBUFFER_BINDING:
2152 case GL_RENDERBUFFER_BINDING:
2153 case GL_CURRENT_PROGRAM:
2154 case GL_PACK_ALIGNMENT:
2155 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2156 case GL_UNPACK_ALIGNMENT:
2157 case GL_GENERATE_MIPMAP_HINT:
2158 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2159 case GL_RED_BITS:
2160 case GL_GREEN_BITS:
2161 case GL_BLUE_BITS:
2162 case GL_ALPHA_BITS:
2163 case GL_DEPTH_BITS:
2164 case GL_STENCIL_BITS:
2165 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2166 case GL_CULL_FACE_MODE:
2167 case GL_FRONT_FACE:
2168 case GL_ACTIVE_TEXTURE:
2169 case GL_STENCIL_FUNC:
2170 case GL_STENCIL_VALUE_MASK:
2171 case GL_STENCIL_REF:
2172 case GL_STENCIL_FAIL:
2173 case GL_STENCIL_PASS_DEPTH_FAIL:
2174 case GL_STENCIL_PASS_DEPTH_PASS:
2175 case GL_STENCIL_BACK_FUNC:
2176 case GL_STENCIL_BACK_VALUE_MASK:
2177 case GL_STENCIL_BACK_REF:
2178 case GL_STENCIL_BACK_FAIL:
2179 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2180 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2181 case GL_DEPTH_FUNC:
2182 case GL_BLEND_SRC_RGB:
2183 case GL_BLEND_SRC_ALPHA:
2184 case GL_BLEND_DST_RGB:
2185 case GL_BLEND_DST_ALPHA:
2186 case GL_BLEND_EQUATION_RGB:
2187 case GL_BLEND_EQUATION_ALPHA:
2188 case GL_STENCIL_WRITEMASK:
2189 case GL_STENCIL_BACK_WRITEMASK:
2190 case GL_STENCIL_CLEAR_VALUE:
2191 case GL_SUBPIXEL_BITS:
2192 case GL_MAX_TEXTURE_SIZE:
2193 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2194 case GL_SAMPLE_BUFFERS:
2195 case GL_SAMPLES:
2196 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2197 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2198 case GL_TEXTURE_BINDING_2D:
2199 case GL_TEXTURE_BINDING_CUBE_MAP:
2200 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
2201 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
2202 case GL_PROGRAM_BINARY_FORMATS_OES:
2203 {
2204 *type = GL_INT;
2205 *numParams = 1;
2206 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002207 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002208 case GL_MAX_SAMPLES_ANGLE:
2209 {
2210 if (getMaxSupportedSamples() != 0)
2211 {
2212 *type = GL_INT;
2213 *numParams = 1;
2214 }
2215 else
2216 {
2217 return false;
2218 }
2219 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002220 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002221 case GL_MAX_VIEWPORT_DIMS:
2222 {
2223 *type = GL_INT;
2224 *numParams = 2;
2225 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002226 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002227 case GL_VIEWPORT:
2228 case GL_SCISSOR_BOX:
2229 {
2230 *type = GL_INT;
2231 *numParams = 4;
2232 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002233 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002234 case GL_SHADER_COMPILER:
2235 case GL_SAMPLE_COVERAGE_INVERT:
2236 case GL_DEPTH_WRITEMASK:
2237 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
2238 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
2239 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2240 case GL_SAMPLE_COVERAGE:
2241 case GL_SCISSOR_TEST:
2242 case GL_STENCIL_TEST:
2243 case GL_DEPTH_TEST:
2244 case GL_BLEND:
2245 case GL_DITHER:
2246 case GL_CONTEXT_ROBUST_ACCESS_EXT:
2247 {
2248 *type = GL_BOOL;
2249 *numParams = 1;
2250 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002251 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002252 case GL_COLOR_WRITEMASK:
2253 {
2254 *type = GL_BOOL;
2255 *numParams = 4;
2256 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002257 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002258 case GL_POLYGON_OFFSET_FACTOR:
2259 case GL_POLYGON_OFFSET_UNITS:
2260 case GL_SAMPLE_COVERAGE_VALUE:
2261 case GL_DEPTH_CLEAR_VALUE:
2262 case GL_LINE_WIDTH:
2263 {
2264 *type = GL_FLOAT;
2265 *numParams = 1;
2266 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002267 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002268 case GL_ALIASED_LINE_WIDTH_RANGE:
2269 case GL_ALIASED_POINT_SIZE_RANGE:
2270 case GL_DEPTH_RANGE:
2271 {
2272 *type = GL_FLOAT;
2273 *numParams = 2;
2274 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002275 return true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002276 case GL_COLOR_CLEAR_VALUE:
2277 case GL_BLEND_COLOR:
2278 {
2279 *type = GL_FLOAT;
2280 *numParams = 4;
2281 }
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002282 return true;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00002283 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2284 if (!supportsTextureFilterAnisotropy())
2285 {
2286 return false;
2287 }
2288 *type = GL_FLOAT;
2289 *numParams = 1;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002290 return true;
2291 }
2292
2293 if (mClientVersion < 3)
2294 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002295 return false;
2296 }
2297
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002298 // Check for ES3.0+ parameter names
2299 switch (pname)
2300 {
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00002301 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2302 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002303 case GL_UNIFORM_BUFFER_BINDING:
2304 case GL_TRANSFORM_FEEDBACK_BINDING:
shannon.woods%transgaming.com@gtempaccount.com51171882013-04-13 03:39:10 +00002305 case GL_COPY_READ_BUFFER_BINDING:
2306 case GL_COPY_WRITE_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc926e5f2013-04-13 03:39:18 +00002307 case GL_PIXEL_PACK_BUFFER_BINDING:
2308 case GL_PIXEL_UNPACK_BUFFER_BINDING:
shannon.woods%transgaming.com@gtempaccount.comc416e1c2013-04-13 03:45:05 +00002309 case GL_TEXTURE_BINDING_3D:
shannon.woods%transgaming.com@gtempaccount.com90dbc442013-04-13 03:46:14 +00002310 case GL_TEXTURE_BINDING_2D_ARRAY:
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00002311 case GL_MAX_3D_TEXTURE_SIZE:
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00002312 case GL_MAX_ARRAY_TEXTURE_LAYERS:
shannonwoods@chromium.orgf2d76f82013-05-30 00:06:32 +00002313 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2314 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2315 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
Jamie Madillefb3bd12013-07-02 11:57:05 -04002316 case GL_VERTEX_ARRAY_BINDING:
Jamie Madill38850df2013-07-19 16:36:55 -04002317 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2318 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
Geoff Lang23c81692013-08-12 10:46:58 -04002319 case GL_NUM_EXTENSIONS:
Jamie Madillee7010d2013-10-17 10:45:47 -04002320 case GL_MAJOR_VERSION:
2321 case GL_MINOR_VERSION:
Jamie Madill13a2f852013-12-11 16:35:08 -05002322 case GL_MAX_ELEMENTS_INDICES:
2323 case GL_MAX_ELEMENTS_VERTICES:
Jamie Madill2e503552013-12-19 13:48:34 -05002324 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002325 {
2326 *type = GL_INT;
2327 *numParams = 1;
2328 }
2329 return true;
Jamie Madill0fda9862013-07-19 16:36:55 -04002330
2331 case GL_MAX_ELEMENT_INDEX:
2332 case GL_MAX_UNIFORM_BLOCK_SIZE:
2333 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2334 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2335 case GL_MAX_SERVER_WAIT_TIMEOUT:
2336 {
2337 *type = GL_INT_64_ANGLEX;
2338 *numParams = 1;
2339 }
2340 return true;
Jamie Madill2e503552013-12-19 13:48:34 -05002341
2342 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2343 {
2344 *type = GL_BOOL;
2345 *numParams = 1;
2346 }
2347 return true;
shannon.woods%transgaming.com@gtempaccount.com667a29c2013-04-13 03:39:04 +00002348 }
2349
2350 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002351}
2352
Shannon Woods1b2fb852013-08-19 14:28:48 -04002353bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
2354{
2355 if (mClientVersion < 3)
2356 {
2357 return false;
2358 }
2359
2360 switch (target)
2361 {
2362 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2363 case GL_UNIFORM_BUFFER_BINDING:
2364 {
2365 *type = GL_INT;
2366 *numParams = 1;
2367 }
2368 return true;
2369 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2370 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2371 case GL_UNIFORM_BUFFER_START:
2372 case GL_UNIFORM_BUFFER_SIZE:
2373 {
2374 *type = GL_INT_64_ANGLEX;
2375 *numParams = 1;
2376 }
2377 }
2378
2379 return false;
2380}
2381
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002382// Applies the render target surface, depth stencil surface, viewport rectangle and
daniel@transgaming.com12985182012-12-20 20:56:31 +00002383// scissor rectangle to the renderer
2384bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002385{
2386 Framebuffer *framebufferObject = getDrawFramebuffer();
2387
2388 if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
2389 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002390 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002391 }
2392
daniel@transgaming.com8a8b24c2012-11-28 19:36:26 +00002393 mRenderer->applyRenderTarget(framebufferObject);
2394
daniel@transgaming.com12985182012-12-20 20:56:31 +00002395 if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
shannon.woods@transgaming.com0b236e22013-01-25 21:57:07 +00002396 ignoreViewport))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002397 {
daniel@transgaming.com3ca082c2012-11-28 19:41:07 +00002398 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002399 }
2400
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +00002401 mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002402
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002403 return true;
2404}
2405
2406// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
2407void Context::applyState(GLenum drawMode)
2408{
Nicolas Capensfd396552013-06-18 21:41:30 -04002409 Framebuffer *framebufferObject = getDrawFramebuffer();
2410 int samples = framebufferObject->getSamples();
2411
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +00002412 mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
Nicolas Capensfd396552013-06-18 21:41:30 -04002413 mState.rasterizer.multiSample = (samples != 0);
shannon.woods@transgaming.comdd2524c2013-02-28 23:04:33 +00002414 mRenderer->setRasterizerState(mState.rasterizer);
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002415
2416 unsigned int mask = 0;
2417 if (mState.sampleCoverage)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002418 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002419 if (mState.sampleCoverageValue != 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002420 {
Nicolas Capensfd396552013-06-18 21:41:30 -04002421
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002422 float threshold = 0.5f;
2423
Nicolas Capensfd396552013-06-18 21:41:30 -04002424 for (int i = 0; i < samples; ++i)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002425 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002426 mask <<= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002427
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002428 if ((i + 1) * mState.sampleCoverageValue >= threshold)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002429 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002430 threshold += 1.0f;
2431 mask |= 1;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002432 }
2433 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002434 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002435
2436 if (mState.sampleCoverageInvert)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002437 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002438 mask = ~mask;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002439 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002440 }
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002441 else
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002442 {
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002443 mask = 0xFFFFFFFF;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002444 }
Geoff Langc142e9d2013-09-30 15:19:47 -04002445 mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask);
daniel@transgaming.com2e258642012-11-28 19:36:18 +00002446
daniel@transgaming.com08c331d2012-11-28 19:38:39 +00002447 mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +00002448 mState.rasterizer.frontFace == GL_CCW);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002449}
2450
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002451// Applies the shaders and shader constants to the Direct3D 9 device
Geoff Lang0550d032014-01-30 11:29:07 -05002452void Context::applyShaders(ProgramBinary *programBinary, bool rasterizerDiscard)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002453{
Geoff Lang0550d032014-01-30 11:29:07 -05002454 mRenderer->applyShaders(programBinary, rasterizerDiscard);
2455
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002456 programBinary->applyUniforms();
2457}
2458
Geoff Lange2e0ce02013-09-17 17:05:08 -04002459bool Context::getCurrentTextureAndSamplerState(ProgramBinary *programBinary, SamplerType type, int index, Texture **outTexture,
2460 TextureType *outTextureType, SamplerState *outSampler)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002461{
Geoff Lange2e0ce02013-09-17 17:05:08 -04002462 int textureUnit = programBinary->getSamplerMapping(type, index); // OpenGL texture image unit index
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002463
Geoff Lange2e0ce02013-09-17 17:05:08 -04002464 if (textureUnit != -1)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002465 {
Geoff Lange2e0ce02013-09-17 17:05:08 -04002466 TextureType textureType = programBinary->getSamplerTextureType(type, index);
2467 Texture *texture = getSamplerTexture(textureUnit, textureType);
2468
2469 SamplerState samplerState;
2470 texture->getSamplerState(&samplerState);
2471
2472 if (mState.samplers[textureUnit] != 0)
2473 {
2474 Sampler *samplerObject = getSampler(mState.samplers[textureUnit]);
2475 samplerObject->getState(&samplerState);
2476 }
2477
2478 *outTexture = texture;
2479 *outTextureType = textureType;
2480 *outSampler = samplerState;
2481
2482 return true;
2483 }
2484 else
2485 {
2486 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002487 }
2488}
2489
Geoff Lange2e0ce02013-09-17 17:05:08 -04002490void Context::generateSwizzles(ProgramBinary *programBinary)
2491{
2492 generateSwizzles(programBinary, SAMPLER_PIXEL);
2493
2494 if (mSupportsVertexTexture)
2495 {
2496 generateSwizzles(programBinary, SAMPLER_VERTEX);
2497 }
2498}
2499
2500void Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
2501{
2502 // Range of Direct3D samplers of given sampler type
2503 int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
2504 int samplerRange = programBinary->getUsedSamplerRange(type);
2505
2506 for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
2507 {
2508 Texture *texture = NULL;
2509 TextureType textureType;
2510 SamplerState samplerState;
2511 if (getCurrentTextureAndSamplerState(programBinary, type, samplerIndex, &texture, &textureType, &samplerState) && texture->isSwizzled())
2512 {
2513 mRenderer->generateSwizzle(texture);
2514 }
2515 }
2516}
2517
2518// Applies the textures and sampler states to the Direct3D 9 device
2519void Context::applyTextures(ProgramBinary *programBinary)
2520{
2521 applyTextures(programBinary, SAMPLER_PIXEL);
2522
2523 if (mSupportsVertexTexture)
2524 {
2525 applyTextures(programBinary, SAMPLER_VERTEX);
2526 }
2527}
2528
2529// For each Direct3D sampler of either the pixel or vertex stage,
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002530// looks up the corresponding OpenGL texture image unit and texture type,
2531// and sets the texture and its addressing/filtering state (or NULL when inactive).
Geoff Lange2e0ce02013-09-17 17:05:08 -04002532void Context::applyTextures(ProgramBinary *programBinary, SamplerType type)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002533{
Geoff Langcdf22f92013-10-31 10:38:23 -04002534 FramebufferTextureSerialSet boundFramebufferTextures = getBoundFramebufferTextureSerials();
2535
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +00002536 // Range of Direct3D samplers of given sampler type
2537 int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002538 int samplerRange = programBinary->getUsedSamplerRange(type);
2539
2540 for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
2541 {
Geoff Lange2e0ce02013-09-17 17:05:08 -04002542 Texture *texture = NULL;
2543 TextureType textureType;
2544 SamplerState samplerState;
2545 if (getCurrentTextureAndSamplerState(programBinary, type, samplerIndex, &texture, &textureType, &samplerState))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002546 {
Geoff Lange2e0ce02013-09-17 17:05:08 -04002547 if (texture->isSamplerComplete(samplerState) &&
2548 boundFramebufferTextures.find(texture->getTextureSerial()) == boundFramebufferTextures.end())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002549 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002550 mRenderer->setSamplerState(type, samplerIndex, samplerState);
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002551 mRenderer->setTexture(type, samplerIndex, texture);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002552 texture->resetDirty();
2553 }
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002554 else
2555 {
2556 mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
2557 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002558 }
2559 else
2560 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002561 mRenderer->setTexture(type, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002562 }
2563 }
2564
2565 for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
2566 {
daniel@transgaming.come33c8bf2013-01-11 04:11:33 +00002567 mRenderer->setTexture(type, samplerIndex, NULL);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002568 }
2569}
2570
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002571bool Context::applyUniformBuffers()
2572{
2573 Program *programObject = getProgram(mState.currentProgram);
2574 ProgramBinary *programBinary = programObject->getProgramBinary();
2575
2576 std::vector<gl::Buffer*> boundBuffers;
2577
2578 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
2579 {
2580 GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
2581 const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
2582 if (boundBuffer.id() == 0)
2583 {
2584 // undefined behaviour
2585 return false;
2586 }
2587 else
2588 {
2589 gl::Buffer *uniformBuffer = boundBuffer.get();
2590 ASSERT(uniformBuffer);
2591 boundBuffers.push_back(uniformBuffer);
2592 }
2593 }
2594
2595 return programBinary->applyUniformBuffers(boundBuffers);
2596}
2597
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002598
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002599
2600void Context::clear(GLbitfield mask)
2601{
Geoff Lang0550d032014-01-30 11:29:07 -05002602 if (isRasterizerDiscardEnabled())
2603 {
2604 return;
2605 }
2606
Geoff Langda507fe2013-08-20 12:01:42 -04002607 ClearParameters clearParams = { 0 };
Geoff Langda507fe2013-08-20 12:01:42 -04002608 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2609 {
2610 clearParams.clearColor[i] = false;
2611 }
2612 clearParams.colorFClearValue = mState.colorClearValue;
2613 clearParams.colorClearType = GL_FLOAT;
2614 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2615 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2616 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2617 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2618 clearParams.clearDepth = false;
2619 clearParams.depthClearValue = mState.depthClearValue;
2620 clearParams.clearStencil = false;
2621 clearParams.stencilClearValue = mState.stencilClearValue;
2622 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2623 clearParams.scissorEnabled = mState.scissorTest;
2624 clearParams.scissor = mState.scissor;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002625
Geoff Lang0b833232013-08-21 10:13:29 -04002626 Framebuffer *framebufferObject = getDrawFramebuffer();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002627 if (mask & GL_COLOR_BUFFER_BIT)
2628 {
shannon.woods%transgaming.com@gtempaccount.comdae24092013-04-13 03:31:31 +00002629 if (framebufferObject->hasEnabledColorAttachment())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002630 {
Geoff Langda507fe2013-08-20 12:01:42 -04002631 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2632 {
2633 clearParams.clearColor[i] = true;
2634 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002635 }
2636 }
2637
2638 if (mask & GL_DEPTH_BUFFER_BIT)
2639 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00002640 if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002641 {
Geoff Langda507fe2013-08-20 12:01:42 -04002642 clearParams.clearDepth = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002643 }
2644 }
2645
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002646 if (mask & GL_STENCIL_BUFFER_BIT)
2647 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002648 if (framebufferObject->getStencilbufferType() != GL_NONE)
2649 {
daniel@transgaming.comd62d7142012-11-28 19:40:28 +00002650 rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002651 if (!depthStencil)
2652 {
2653 ERR("Depth stencil pointer unexpectedly null.");
2654 return;
2655 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002656
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +00002657 if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002658 {
Geoff Langda507fe2013-08-20 12:01:42 -04002659 clearParams.clearStencil = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002660 }
2661 }
2662 }
2663
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002664
daniel@transgaming.com12985182012-12-20 20:56:31 +00002665 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002666 {
2667 return;
2668 }
2669
daniel@transgaming.com084a2572012-11-28 20:55:17 +00002670 mRenderer->clear(clearParams, framebufferObject);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002671}
2672
Geoff Lang42359ca2013-08-21 13:25:17 -04002673void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
2674{
Geoff Lang0550d032014-01-30 11:29:07 -05002675 if (isRasterizerDiscardEnabled())
2676 {
2677 return;
2678 }
Geoff Lang42359ca2013-08-21 13:25:17 -04002679
Geoff Lang0550d032014-01-30 11:29:07 -05002680 // glClearBufferfv can be called to clear the color buffer or depth buffer
Geoff Lang42359ca2013-08-21 13:25:17 -04002681 ClearParameters clearParams = { 0 };
2682
2683 if (buffer == GL_COLOR)
2684 {
2685 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2686 {
2687 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2688 }
2689 clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
2690 clearParams.colorClearType = GL_FLOAT;
2691 }
2692 else
2693 {
2694 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2695 {
2696 clearParams.clearColor[i] = false;
2697 }
2698 clearParams.colorFClearValue = mState.colorClearValue;
2699 clearParams.colorClearType = GL_FLOAT;
2700 }
2701
2702 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2703 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2704 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2705 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2706
2707 if (buffer == GL_DEPTH)
2708 {
2709 clearParams.clearDepth = true;
2710 clearParams.depthClearValue = values[0];
2711 }
2712 else
2713 {
2714 clearParams.clearDepth = false;
2715 clearParams.depthClearValue = mState.depthClearValue;
2716 }
2717
2718 clearParams.clearStencil = false;
2719 clearParams.stencilClearValue = mState.stencilClearValue;
2720 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2721 clearParams.scissorEnabled = mState.scissorTest;
2722 clearParams.scissor = mState.scissor;
2723
2724 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2725 {
2726 return;
2727 }
2728
2729 mRenderer->clear(clearParams, getDrawFramebuffer());
2730}
2731
2732void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
2733{
Geoff Lang0550d032014-01-30 11:29:07 -05002734 if (isRasterizerDiscardEnabled())
2735 {
2736 return;
2737 }
Geoff Lang42359ca2013-08-21 13:25:17 -04002738
Geoff Lang0550d032014-01-30 11:29:07 -05002739 // glClearBufferuv can only be called to clear a color buffer
Geoff Lang42359ca2013-08-21 13:25:17 -04002740 ClearParameters clearParams = { 0 };
2741 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2742 {
2743 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2744 }
2745 clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
2746 clearParams.colorClearType = GL_UNSIGNED_INT;
2747 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2748 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2749 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2750 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2751 clearParams.clearDepth = false;
2752 clearParams.depthClearValue = mState.depthClearValue;
2753 clearParams.clearStencil = false;
2754 clearParams.stencilClearValue = mState.stencilClearValue;
2755 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2756 clearParams.scissorEnabled = mState.scissorTest;
2757 clearParams.scissor = mState.scissor;
2758
2759 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2760 {
2761 return;
2762 }
2763
2764 mRenderer->clear(clearParams, getDrawFramebuffer());
2765}
2766
2767void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
2768{
Geoff Lang0550d032014-01-30 11:29:07 -05002769 if (isRasterizerDiscardEnabled())
2770 {
2771 return;
2772 }
Geoff Lang42359ca2013-08-21 13:25:17 -04002773
Geoff Lang0550d032014-01-30 11:29:07 -05002774 // glClearBufferfv can be called to clear the color buffer or stencil buffer
Geoff Lang42359ca2013-08-21 13:25:17 -04002775 ClearParameters clearParams = { 0 };
2776
2777 if (buffer == GL_COLOR)
2778 {
2779 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2780 {
2781 clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2782 }
2783 clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
2784 clearParams.colorClearType = GL_INT;
2785 }
2786 else
2787 {
2788 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2789 {
2790 clearParams.clearColor[i] = false;
2791 }
2792 clearParams.colorFClearValue = mState.colorClearValue;
2793 clearParams.colorClearType = GL_FLOAT;
2794 }
2795
2796 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2797 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2798 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2799 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2800
2801 clearParams.clearDepth = false;
2802 clearParams.depthClearValue = mState.depthClearValue;
2803
2804 if (buffer == GL_STENCIL)
2805 {
2806 clearParams.clearStencil = true;
2807 clearParams.stencilClearValue = values[1];
2808 }
2809 else
2810 {
2811 clearParams.clearStencil = false;
2812 clearParams.stencilClearValue = mState.stencilClearValue;
2813 }
2814 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2815
2816 clearParams.scissorEnabled = mState.scissorTest;
2817 clearParams.scissor = mState.scissor;
2818
2819 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2820 {
2821 return;
2822 }
2823
2824 mRenderer->clear(clearParams, getDrawFramebuffer());
2825}
2826
2827void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
2828{
Geoff Lang0550d032014-01-30 11:29:07 -05002829 if (isRasterizerDiscardEnabled())
2830 {
2831 return;
2832 }
Geoff Lang42359ca2013-08-21 13:25:17 -04002833
Geoff Lang0550d032014-01-30 11:29:07 -05002834 // glClearBufferfi can only be called to clear a depth stencil buffer
Geoff Lang42359ca2013-08-21 13:25:17 -04002835 ClearParameters clearParams = { 0 };
2836 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2837 {
2838 clearParams.clearColor[i] = false;
2839 }
2840 clearParams.colorFClearValue = mState.colorClearValue;
2841 clearParams.colorClearType = GL_FLOAT;
2842 clearParams.colorMaskRed = mState.blend.colorMaskRed;
2843 clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2844 clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2845 clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2846 clearParams.clearDepth = true;
2847 clearParams.depthClearValue = depth;
2848 clearParams.clearStencil = true;
2849 clearParams.stencilClearValue = stencil;
2850 clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2851 clearParams.scissorEnabled = mState.scissorTest;
2852 clearParams.scissor = mState.scissor;
2853
2854 if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
2855 {
2856 return;
2857 }
2858
2859 mRenderer->clear(clearParams, getDrawFramebuffer());
2860}
2861
2862void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2863 GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2864{
2865 Framebuffer *framebuffer = getReadFramebuffer();
2866
2867 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2868 {
2869 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
2870 }
2871
2872 if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
2873 {
2874 return gl::error(GL_INVALID_OPERATION);
2875 }
2876
Geoff Lang005df412013-10-16 14:12:50 -04002877 GLenum sizedInternalFormat = IsSizedInternalFormat(format, mClientVersion) ? format
2878 : GetSizedInternalFormat(format, type, mClientVersion);
Geoff Lang42359ca2013-08-21 13:25:17 -04002879
2880 GLsizei outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, getPackAlignment());
2881 // sized query sanity check
2882 if (bufSize)
2883 {
2884 int requiredSize = outputPitch * height;
2885 if (requiredSize > *bufSize)
2886 {
2887 return gl::error(GL_INVALID_OPERATION);
2888 }
2889 }
2890
2891 mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
2892}
2893
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002894void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
2895{
2896 if (!mState.currentProgram)
2897 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002898 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002899 }
2900
Geoff Lange2e0ce02013-09-17 17:05:08 -04002901 ProgramBinary *programBinary = getCurrentProgramBinary();
2902 programBinary->applyUniforms();
2903
2904 generateSwizzles(programBinary);
2905
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002906 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002907 {
2908 return;
2909 }
2910
daniel@transgaming.com12985182012-12-20 20:56:31 +00002911 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002912 {
2913 return;
2914 }
2915
2916 applyState(mode);
2917
Jamie Madill57a89722013-07-02 11:57:03 -04002918 GLenum err = mRenderer->applyVertexBuffer(programBinary, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, first, count, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002919 if (err != GL_NO_ERROR)
2920 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002921 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002922 }
2923
Geoff Lang0550d032014-01-30 11:29:07 -05002924 applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
Geoff Lange2e0ce02013-09-17 17:05:08 -04002925 applyTextures(programBinary);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002926
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002927 if (!applyUniformBuffers())
2928 {
2929 return;
2930 }
2931
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002932 if (!programBinary->validateSamplers(NULL))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002933 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002934 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002935 }
2936
daniel@transgaming.com087e5782012-09-17 21:28:47 +00002937 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002938 {
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002939 mRenderer->drawArrays(mode, count, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002940 }
2941}
2942
2943void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
2944{
2945 if (!mState.currentProgram)
2946 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002947 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002948 }
2949
Jamie Madill57a89722013-07-02 11:57:03 -04002950 VertexArray *vao = getCurrentVertexArray();
2951 if (!indices && !vao->getElementArrayBuffer())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002952 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002953 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002954 }
Geoff Lange2e0ce02013-09-17 17:05:08 -04002955
2956 ProgramBinary *programBinary = getCurrentProgramBinary();
2957 programBinary->applyUniforms();
2958
2959 generateSwizzles(programBinary);
2960
daniel@transgaming.com91207b72012-11-28 20:56:43 +00002961 if (!mRenderer->applyPrimitiveType(mode, count))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002962 {
2963 return;
2964 }
2965
daniel@transgaming.com12985182012-12-20 20:56:31 +00002966 if (!applyRenderTarget(mode, false))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002967 {
2968 return;
2969 }
2970
2971 applyState(mode);
2972
daniel@transgaming.com31240482012-11-28 21:06:41 +00002973 rx::TranslatedIndexData indexInfo;
Jamie Madill57a89722013-07-02 11:57:03 -04002974 GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002975 if (err != GL_NO_ERROR)
2976 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002977 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002978 }
2979
2980 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
Jamie Madill57a89722013-07-02 11:57:03 -04002981 err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002982 if (err != GL_NO_ERROR)
2983 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002984 return gl::error(err);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002985 }
2986
Geoff Lang0550d032014-01-30 11:29:07 -05002987 applyShaders(programBinary, mState.rasterizer.rasterizerDiscard);
Geoff Lange2e0ce02013-09-17 17:05:08 -04002988 applyTextures(programBinary);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002989
shannonwoods@chromium.org1bddfb92013-05-30 00:11:29 +00002990 if (!applyUniformBuffers())
2991 {
2992 return;
2993 }
2994
daniel@transgaming.com92025f52012-11-28 20:52:54 +00002995 if (!programBinary->validateSamplers(NULL))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002996 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00002997 return gl::error(GL_INVALID_OPERATION);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00002998 }
2999
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003000 if (!skipDraw(mode))
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003001 {
Jamie Madill57a89722013-07-02 11:57:03 -04003002 mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003003 }
3004}
3005
3006// Implements glFlush when block is false, glFinish when block is true
3007void Context::sync(bool block)
3008{
daniel@transgaming.comef21ab22012-10-31 17:52:47 +00003009 mRenderer->sync(block);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003010}
3011
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003012void Context::recordInvalidEnum()
3013{
3014 mInvalidEnum = true;
3015}
3016
3017void Context::recordInvalidValue()
3018{
3019 mInvalidValue = true;
3020}
3021
3022void Context::recordInvalidOperation()
3023{
3024 mInvalidOperation = true;
3025}
3026
3027void Context::recordOutOfMemory()
3028{
3029 mOutOfMemory = true;
3030}
3031
3032void Context::recordInvalidFramebufferOperation()
3033{
3034 mInvalidFramebufferOperation = true;
3035}
3036
3037// Get one of the recorded errors and clear its flag, if any.
3038// [OpenGL ES 2.0.24] section 2.5 page 13.
3039GLenum Context::getError()
3040{
3041 if (mInvalidEnum)
3042 {
3043 mInvalidEnum = false;
3044
3045 return GL_INVALID_ENUM;
3046 }
3047
3048 if (mInvalidValue)
3049 {
3050 mInvalidValue = false;
3051
3052 return GL_INVALID_VALUE;
3053 }
3054
3055 if (mInvalidOperation)
3056 {
3057 mInvalidOperation = false;
3058
3059 return GL_INVALID_OPERATION;
3060 }
3061
3062 if (mOutOfMemory)
3063 {
3064 mOutOfMemory = false;
3065
3066 return GL_OUT_OF_MEMORY;
3067 }
3068
3069 if (mInvalidFramebufferOperation)
3070 {
3071 mInvalidFramebufferOperation = false;
3072
3073 return GL_INVALID_FRAMEBUFFER_OPERATION;
3074 }
3075
3076 return GL_NO_ERROR;
3077}
3078
3079GLenum Context::getResetStatus()
3080{
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00003081 if (mResetStatus == GL_NO_ERROR && !mContextLost)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003082 {
daniel@transgaming.comf688c0d2012-10-31 17:52:57 +00003083 // mResetStatus will be set by the markContextLost callback
3084 // in the case a notification is sent
3085 mRenderer->testDeviceLost(true);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003086 }
3087
3088 GLenum status = mResetStatus;
3089
3090 if (mResetStatus != GL_NO_ERROR)
3091 {
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +00003092 ASSERT(mContextLost);
3093
daniel@transgaming.com621ce052012-10-31 17:52:29 +00003094 if (mRenderer->testDeviceResettable())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003095 {
3096 mResetStatus = GL_NO_ERROR;
3097 }
3098 }
3099
3100 return status;
3101}
3102
3103bool Context::isResetNotificationEnabled()
3104{
3105 return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
3106}
3107
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00003108int Context::getClientVersion() const
3109{
3110 return mClientVersion;
3111}
3112
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00003113int Context::getMajorShaderModel() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003114{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00003115 return mMajorShaderModel;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003116}
3117
3118float Context::getMaximumPointSize() const
3119{
shannon.woods@transgaming.combd8c10c2013-01-25 21:15:03 +00003120 return mMaximumPointSize;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003121}
3122
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003123unsigned int Context::getMaximumCombinedTextureImageUnits() const
3124{
shannon.woods@transgaming.com76cd88c2013-01-25 21:54:36 +00003125 return mRenderer->getMaxCombinedTextureImageUnits();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003126}
3127
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00003128unsigned int Context::getMaximumCombinedUniformBufferBindings() const
3129{
3130 return mRenderer->getMaxVertexShaderUniformBuffers() +
3131 mRenderer->getMaxFragmentShaderUniformBuffers();
3132}
3133
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003134int Context::getMaxSupportedSamples() const
3135{
daniel@transgaming.comb7833982012-10-31 18:31:46 +00003136 return mRenderer->getMaxSupportedSamples();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003137}
3138
Geoff Lang005df412013-10-16 14:12:50 -04003139GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
Geoff Lang0e120e32013-05-29 10:23:55 -04003140{
3141 return mRenderer->getMaxSupportedFormatSamples(internalFormat);
3142}
3143
Geoff Lang005df412013-10-16 14:12:50 -04003144GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
Shannon Woods52f1e7e2013-07-08 10:32:17 -04003145{
3146 return mRenderer->getNumSampleCounts(internalFormat);
3147}
3148
Geoff Lang005df412013-10-16 14:12:50 -04003149void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
Shannon Woods52f1e7e2013-07-08 10:32:17 -04003150{
3151 mRenderer->getSampleCounts(internalFormat, bufSize, params);
3152}
3153
shannon.woods%transgaming.com@gtempaccount.com34089352013-04-13 03:36:57 +00003154unsigned int Context::getMaxTransformFeedbackBufferBindings() const
3155{
3156 return mRenderer->getMaxTransformFeedbackBuffers();
3157}
3158
shannonwoods@chromium.org97c3d502013-05-30 00:04:34 +00003159GLintptr Context::getUniformBufferOffsetAlignment() const
3160{
3161 // setting a large alignment forces uniform buffers to bind with zero offset
3162 return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
3163}
3164
shannon.woods%transgaming.com@gtempaccount.com89ae1132013-04-13 03:28:43 +00003165unsigned int Context::getMaximumRenderTargets() const
3166{
3167 return mRenderer->getMaxRenderTargets();
3168}
3169
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003170bool Context::supportsEventQueries() const
3171{
3172 return mSupportsEventQueries;
3173}
3174
3175bool Context::supportsOcclusionQueries() const
3176{
3177 return mSupportsOcclusionQueries;
3178}
3179
shannon.woods@transgaming.combec04bf2013-01-25 21:53:52 +00003180bool Context::supportsBGRATextures() const
3181{
3182 return mSupportsBGRATextures;
3183}
3184
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003185bool Context::supportsDXT1Textures() const
3186{
3187 return mSupportsDXT1Textures;
3188}
3189
3190bool Context::supportsDXT3Textures() const
3191{
3192 return mSupportsDXT3Textures;
3193}
3194
3195bool Context::supportsDXT5Textures() const
3196{
3197 return mSupportsDXT5Textures;
3198}
3199
3200bool Context::supportsFloat32Textures() const
3201{
3202 return mSupportsFloat32Textures;
3203}
3204
3205bool Context::supportsFloat32LinearFilter() const
3206{
3207 return mSupportsFloat32LinearFilter;
3208}
3209
3210bool Context::supportsFloat32RenderableTextures() const
3211{
3212 return mSupportsFloat32RenderableTextures;
3213}
3214
3215bool Context::supportsFloat16Textures() const
3216{
3217 return mSupportsFloat16Textures;
3218}
3219
3220bool Context::supportsFloat16LinearFilter() const
3221{
3222 return mSupportsFloat16LinearFilter;
3223}
3224
3225bool Context::supportsFloat16RenderableTextures() const
3226{
3227 return mSupportsFloat16RenderableTextures;
3228}
3229
3230int Context::getMaximumRenderbufferDimension() const
3231{
3232 return mMaxRenderbufferDimension;
3233}
3234
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003235int Context::getMaximum2DTextureDimension() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003236{
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003237 return mMax2DTextureDimension;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003238}
3239
3240int Context::getMaximumCubeTextureDimension() const
3241{
3242 return mMaxCubeTextureDimension;
3243}
3244
shannon.woods%transgaming.com@gtempaccount.comc1fdf6b2013-04-13 03:44:41 +00003245int Context::getMaximum3DTextureDimension() const
3246{
3247 return mMax3DTextureDimension;
3248}
3249
shannon.woods%transgaming.com@gtempaccount.coma98a8112013-04-13 03:45:57 +00003250int Context::getMaximum2DArrayTextureLayers() const
3251{
3252 return mMax2DArrayTextureLayers;
3253}
3254
Geoff Langce635692013-09-24 13:56:32 -04003255int Context::getMaximum2DTextureLevel() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003256{
Geoff Langce635692013-09-24 13:56:32 -04003257 return mMax2DTextureLevel;
3258}
3259
3260int Context::getMaximumCubeTextureLevel() const
3261{
3262 return mMaxCubeTextureLevel;
3263}
3264
3265int Context::getMaximum3DTextureLevel() const
3266{
3267 return mMax3DTextureLevel;
3268}
3269
3270int Context::getMaximum2DArrayTextureLevel() const
3271{
3272 return mMax2DArrayTextureLevel;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003273}
3274
3275bool Context::supportsLuminanceTextures() const
3276{
3277 return mSupportsLuminanceTextures;
3278}
3279
3280bool Context::supportsLuminanceAlphaTextures() const
3281{
3282 return mSupportsLuminanceAlphaTextures;
3283}
3284
Geoff Lang632192d2013-10-04 13:40:46 -04003285bool Context::supportsRGTextures() const
3286{
3287 return mSupportsRGTextures;
3288}
3289
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003290bool Context::supportsDepthTextures() const
3291{
3292 return mSupportsDepthTextures;
3293}
3294
3295bool Context::supports32bitIndices() const
3296{
3297 return mSupports32bitIndices;
3298}
3299
3300bool Context::supportsNonPower2Texture() const
3301{
3302 return mSupportsNonPower2Texture;
3303}
3304
3305bool Context::supportsInstancing() const
3306{
3307 return mSupportsInstancing;
3308}
3309
daniel@transgaming.com07ab8412012-07-12 15:17:09 +00003310bool Context::supportsTextureFilterAnisotropy() const
3311{
3312 return mSupportsTextureFilterAnisotropy;
3313}
3314
3315float Context::getTextureMaxAnisotropy() const
3316{
3317 return mMaxTextureAnisotropy;
3318}
3319
Geoff Lang005df412013-10-16 14:12:50 -04003320bool Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003321{
3322 Framebuffer *framebuffer = getReadFramebuffer();
3323 if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
3324 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00003325 return gl::error(GL_INVALID_OPERATION, false);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003326 }
3327
shannon.woods%transgaming.com@gtempaccount.com89ae1132013-04-13 03:28:43 +00003328 Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003329 if (!renderbuffer)
3330 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +00003331 return gl::error(GL_INVALID_OPERATION, false);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003332 }
3333
shannonwoods@chromium.org44a4f982013-05-30 00:13:49 +00003334 *internalFormat = renderbuffer->getActualFormat();
shannonwoods@chromium.orgf6fb9592013-05-30 00:09:40 +00003335 *format = gl::GetFormat(renderbuffer->getActualFormat(), mClientVersion);
3336 *type = gl::GetType(renderbuffer->getActualFormat(), mClientVersion);
daniel@transgaming.com42944b02012-09-27 17:45:57 +00003337
3338 return true;
3339}
3340
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003341void Context::detachBuffer(GLuint buffer)
3342{
3343 // [OpenGL ES 2.0.24] section 2.9 page 22:
3344 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3345 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3346
3347 if (mState.arrayBuffer.id() == buffer)
3348 {
3349 mState.arrayBuffer.set(NULL);
3350 }
3351
Jamie Madill57a89722013-07-02 11:57:03 -04003352 // mark as freed among the vertex array objects
3353 for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003354 {
Jamie Madill57a89722013-07-02 11:57:03 -04003355 vaoIt->second->detachBuffer(buffer);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003356 }
3357}
3358
3359void Context::detachTexture(GLuint texture)
3360{
3361 // [OpenGL ES 2.0.24] section 3.8 page 84:
3362 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3363 // rebound to texture object zero
3364
3365 for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3366 {
shannon.woods@transgaming.com233fe952013-01-25 21:51:57 +00003367 for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003368 {
3369 if (mState.samplerTexture[type][sampler].id() == texture)
3370 {
3371 mState.samplerTexture[type][sampler].set(NULL);
3372 }
3373 }
3374 }
3375
3376 // [OpenGL ES 2.0.24] section 4.4 page 112:
3377 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3378 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3379 // image was attached in the currently bound framebuffer.
3380
3381 Framebuffer *readFramebuffer = getReadFramebuffer();
3382 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3383
3384 if (readFramebuffer)
3385 {
3386 readFramebuffer->detachTexture(texture);
3387 }
3388
3389 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3390 {
3391 drawFramebuffer->detachTexture(texture);
3392 }
3393}
3394
3395void Context::detachFramebuffer(GLuint framebuffer)
3396{
3397 // [OpenGL ES 2.0.24] section 4.4 page 107:
3398 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3399 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3400
3401 if (mState.readFramebuffer == framebuffer)
3402 {
3403 bindReadFramebuffer(0);
3404 }
3405
3406 if (mState.drawFramebuffer == framebuffer)
3407 {
3408 bindDrawFramebuffer(0);
3409 }
3410}
3411
3412void Context::detachRenderbuffer(GLuint renderbuffer)
3413{
3414 // [OpenGL ES 2.0.24] section 4.4 page 109:
3415 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3416 // had been executed with the target RENDERBUFFER and name of zero.
3417
3418 if (mState.renderbuffer.id() == renderbuffer)
3419 {
3420 bindRenderbuffer(0);
3421 }
3422
3423 // [OpenGL ES 2.0.24] section 4.4 page 111:
3424 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3425 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3426 // point to which this image was attached in the currently bound framebuffer.
3427
3428 Framebuffer *readFramebuffer = getReadFramebuffer();
3429 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3430
3431 if (readFramebuffer)
3432 {
3433 readFramebuffer->detachRenderbuffer(renderbuffer);
3434 }
3435
3436 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3437 {
3438 drawFramebuffer->detachRenderbuffer(renderbuffer);
3439 }
3440}
3441
Jamie Madill57a89722013-07-02 11:57:03 -04003442void Context::detachVertexArray(GLuint vertexArray)
3443{
3444 // [OpenGL ES 3.0.2] section 2.10 page 43:
3445 // If a vertex array object that is currently bound is deleted, the binding
3446 // for that object reverts to zero and the default vertex array becomes current.
3447 if (mState.vertexArray == vertexArray)
3448 {
3449 bindVertexArray(0);
3450 }
3451}
3452
Jamie Madilldc356042013-07-19 16:36:57 -04003453void Context::detachSampler(GLuint sampler)
3454{
3455 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3456 // If a sampler object that is currently bound to one or more texture units is
3457 // deleted, it is as though BindSampler is called once for each texture unit to
3458 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3459 for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
3460 {
3461 if (mState.samplers[textureUnit] == sampler)
3462 {
3463 mState.samplers[textureUnit] = 0;
3464 }
3465 }
3466}
3467
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003468Texture *Context::getIncompleteTexture(TextureType type)
3469{
3470 Texture *t = mIncompleteTextures[type].get();
3471
3472 if (t == NULL)
3473 {
Jamie Madill88f18f42013-09-18 14:36:19 -04003474 const GLubyte color[] = { 0, 0, 0, 255 };
3475 const PixelUnpackState incompleteUnpackState(1);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003476
3477 switch (type)
3478 {
3479 default:
3480 UNREACHABLE();
3481 // default falls through to TEXTURE_2D
3482
3483 case TEXTURE_2D:
3484 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +00003485 Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04003486 incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003487 t = incomplete2d;
3488 }
3489 break;
3490
3491 case TEXTURE_CUBE:
3492 {
daniel@transgaming.com370482e2012-11-28 19:32:13 +00003493 TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003494
Jamie Madill88f18f42013-09-18 14:36:19 -04003495 incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3496 incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3497 incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3498 incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3499 incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3500 incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003501
3502 t = incompleteCube;
3503 }
3504 break;
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00003505
3506 case TEXTURE_3D:
3507 {
3508 Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04003509 incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00003510
3511 t = incomplete3d;
3512 }
3513 break;
3514
3515 case TEXTURE_2D_ARRAY:
3516 {
3517 Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
Jamie Madill88f18f42013-09-18 14:36:19 -04003518 incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
shannonwoods@chromium.org18029cd2013-05-30 00:14:06 +00003519
3520 t = incomplete2darray;
3521 }
3522 break;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003523 }
3524
3525 mIncompleteTextures[type].set(t);
3526 }
3527
3528 return t;
3529}
3530
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003531bool Context::skipDraw(GLenum drawMode)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003532{
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003533 if (drawMode == GL_POINTS)
3534 {
3535 // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
3536 // which affects varying interpolation. Since the value of gl_PointSize is
3537 // undefined when not written, just skip drawing to avoid unexpected results.
3538 if (!getCurrentProgramBinary()->usesPointSize())
3539 {
3540 // This is stictly speaking not an error, but developers should be
3541 // notified of risking undefined behavior.
3542 ERR("Point rendering without writing to gl_PointSize.");
3543
3544 return true;
3545 }
3546 }
daniel@transgaming.com97c852b2012-12-20 20:56:23 +00003547 else if (IsTriangleMode(drawMode))
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003548 {
daniel@transgaming.comf39967e2012-11-28 19:35:56 +00003549 if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
daniel@transgaming.com087e5782012-09-17 21:28:47 +00003550 {
3551 return true;
3552 }
3553 }
3554
3555 return false;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003556}
3557
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003558void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003559{
3560 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003561 mState.vertexAttribCurrentValues[index].setFloatValues(values);
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003562}
3563
3564void Context::setVertexAttribu(GLuint index, const GLuint values[4])
3565{
3566 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003567 mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
shannon.woods%transgaming.com@gtempaccount.coma8885862013-04-13 03:37:53 +00003568}
3569
3570void Context::setVertexAttribi(GLuint index, const GLint values[4])
3571{
3572 ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
Jamie Madilla857c362013-07-02 11:57:02 -04003573 mState.vertexAttribCurrentValues[index].setIntValues(values);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003574}
3575
3576void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
3577{
Jamie Madill57a89722013-07-02 11:57:03 -04003578 getCurrentVertexArray()->setVertexAttribDivisor(index, divisor);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003579}
3580
Jamie Madille29d1672013-07-19 16:36:57 -04003581void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
3582{
3583 mResourceManager->checkSamplerAllocation(sampler);
3584
3585 Sampler *samplerObject = getSampler(sampler);
3586 ASSERT(samplerObject);
3587
3588 switch (pname)
3589 {
3590 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
3591 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
3592 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
3593 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
3594 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
3595 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
3596 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
3597 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast<GLenum>(param)); break;
3598 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast<GLenum>(param)); break;
3599 default: UNREACHABLE(); break;
3600 }
3601}
3602
3603void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
3604{
3605 mResourceManager->checkSamplerAllocation(sampler);
3606
3607 Sampler *samplerObject = getSampler(sampler);
3608 ASSERT(samplerObject);
3609
3610 switch (pname)
3611 {
Jamie Madill9675b802013-07-19 16:36:59 -04003612 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround<GLenum>(param)); break;
3613 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround<GLenum>(param)); break;
3614 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround<GLenum>(param)); break;
3615 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround<GLenum>(param)); break;
3616 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround<GLenum>(param)); break;
Jamie Madille29d1672013-07-19 16:36:57 -04003617 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
3618 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
Jamie Madill9675b802013-07-19 16:36:59 -04003619 case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround<GLenum>(param)); break;
3620 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround<GLenum>(param)); break;
Jamie Madille29d1672013-07-19 16:36:57 -04003621 default: UNREACHABLE(); break;
3622 }
3623}
3624
Jamie Madill9675b802013-07-19 16:36:59 -04003625GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
3626{
3627 mResourceManager->checkSamplerAllocation(sampler);
3628
3629 Sampler *samplerObject = getSampler(sampler);
3630 ASSERT(samplerObject);
3631
3632 switch (pname)
3633 {
3634 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
3635 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
3636 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
3637 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
3638 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
3639 case GL_TEXTURE_MIN_LOD: return uiround<GLint>(samplerObject->getMinLod());
3640 case GL_TEXTURE_MAX_LOD: return uiround<GLint>(samplerObject->getMaxLod());
3641 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getComparisonMode());
3642 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getComparisonFunc());
3643 default: UNREACHABLE(); return 0;
3644 }
3645}
3646
3647GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
3648{
3649 mResourceManager->checkSamplerAllocation(sampler);
3650
3651 Sampler *samplerObject = getSampler(sampler);
3652 ASSERT(samplerObject);
3653
3654 switch (pname)
3655 {
3656 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
3657 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
3658 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
3659 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
3660 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
3661 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
3662 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
3663 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getComparisonMode());
3664 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getComparisonFunc());
3665 default: UNREACHABLE(); return 0;
3666 }
3667}
3668
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003669// keep list sorted in following order
3670// OES extensions
3671// EXT extensions
3672// Vendor extensions
3673void Context::initExtensionString()
3674{
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003675 // Do not report extension in GLES 3 contexts for now
3676 if (mClientVersion == 2)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003677 {
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003678 // OES extensions
3679 if (supports32bitIndices())
3680 {
3681 mExtensionStringList.push_back("GL_OES_element_index_uint");
3682 }
3683
3684 mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
3685 mExtensionStringList.push_back("GL_OES_get_program_binary");
3686 mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
3687 if (mRenderer->getDerivativeInstructionSupport())
3688 {
3689 mExtensionStringList.push_back("GL_OES_standard_derivatives");
3690 }
3691
3692 if (supportsFloat16Textures())
3693 {
3694 mExtensionStringList.push_back("GL_OES_texture_half_float");
3695 }
3696 if (supportsFloat16LinearFilter())
3697 {
3698 mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
3699 }
3700 if (supportsFloat32Textures())
3701 {
3702 mExtensionStringList.push_back("GL_OES_texture_float");
3703 }
3704 if (supportsFloat32LinearFilter())
3705 {
3706 mExtensionStringList.push_back("GL_OES_texture_float_linear");
3707 }
3708
Geoff Lang632192d2013-10-04 13:40:46 -04003709 if (supportsRGTextures())
3710 {
3711 mExtensionStringList.push_back("GL_EXT_texture_rg");
3712 }
3713
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003714 if (supportsNonPower2Texture())
3715 {
3716 mExtensionStringList.push_back("GL_OES_texture_npot");
3717 }
3718
3719 // Multi-vendor (EXT) extensions
3720 if (supportsOcclusionQueries())
3721 {
3722 mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
3723 }
3724
3725 mExtensionStringList.push_back("GL_EXT_read_format_bgra");
3726 mExtensionStringList.push_back("GL_EXT_robustness");
3727
3728 if (supportsDXT1Textures())
3729 {
3730 mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
3731 }
3732
3733 if (supportsTextureFilterAnisotropy())
3734 {
3735 mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
3736 }
3737
3738 if (supportsBGRATextures())
3739 {
3740 mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
3741 }
3742
3743 if (mRenderer->getMaxRenderTargets() > 1)
3744 {
3745 mExtensionStringList.push_back("GL_EXT_draw_buffers");
3746 }
3747
3748 mExtensionStringList.push_back("GL_EXT_texture_storage");
Jamie Madill2aeb26a2013-07-08 14:02:55 -04003749 mExtensionStringList.push_back("GL_EXT_frag_depth");
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003750
3751 // ANGLE-specific extensions
3752 if (supportsDepthTextures())
3753 {
3754 mExtensionStringList.push_back("GL_ANGLE_depth_texture");
3755 }
3756
3757 mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
3758 if (getMaxSupportedSamples() != 0)
3759 {
3760 mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
3761 }
3762
3763 if (supportsInstancing())
3764 {
3765 mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
3766 }
3767
3768 mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
3769
3770 if (supportsDXT3Textures())
3771 {
3772 mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
3773 }
3774 if (supportsDXT5Textures())
3775 {
3776 mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
3777 }
3778
3779 mExtensionStringList.push_back("GL_ANGLE_texture_usage");
3780 mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
3781
3782 // Other vendor-specific extensions
3783 if (supportsEventQueries())
3784 {
3785 mExtensionStringList.push_back("GL_NV_fence");
3786 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003787 }
3788
Geoff Lang1ec57f82013-10-16 11:43:23 -04003789 if (mClientVersion == 3)
3790 {
3791 mExtensionStringList.push_back("GL_EXT_color_buffer_float");
3792 }
3793
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003794 // Join the extension strings to one long string for use with GetString
3795 std::stringstream strstr;
3796 for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
daniel@transgaming.com7629bb62013-01-11 04:12:28 +00003797 {
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003798 strstr << mExtensionStringList[extensionIndex];
3799 strstr << " ";
daniel@transgaming.com7629bb62013-01-11 04:12:28 +00003800 }
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003801
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003802 mCombinedExtensionsString = makeStaticString(strstr.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003803}
3804
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003805const char *Context::getCombinedExtensionsString() const
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003806{
shannonwoods@chromium.org302df742013-05-30 00:05:54 +00003807 return mCombinedExtensionsString;
3808}
3809
3810const char *Context::getExtensionString(const GLuint index) const
3811{
3812 ASSERT(index < mExtensionStringList.size());
3813 return mExtensionStringList[index].c_str();
3814}
3815
3816unsigned int Context::getNumExtensions() const
3817{
3818 return mExtensionStringList.size();
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003819}
3820
3821void Context::initRendererString()
3822{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00003823 std::ostringstream rendererString;
3824 rendererString << "ANGLE (";
3825 rendererString << mRenderer->getRendererDescription();
3826 rendererString << ")";
3827
3828 mRendererString = makeStaticString(rendererString.str());
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003829}
3830
3831const char *Context::getRendererString() const
3832{
daniel@transgaming.comca1ac1f2013-01-11 04:13:05 +00003833 return mRendererString;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003834}
3835
Geoff Langcdf22f92013-10-31 10:38:23 -04003836Context::FramebufferTextureSerialSet Context::getBoundFramebufferTextureSerials()
3837{
3838 FramebufferTextureSerialSet set;
3839
3840 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3841 for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
3842 {
3843 Renderbuffer *renderBuffer = drawFramebuffer->getColorbuffer(i);
3844 if (renderBuffer && renderBuffer->getTextureSerial() != 0)
3845 {
3846 set.insert(renderBuffer->getTextureSerial());
3847 }
3848 }
3849
3850 Renderbuffer *depthStencilBuffer = drawFramebuffer->getDepthOrStencilbuffer();
3851 if (depthStencilBuffer && depthStencilBuffer->getTextureSerial() != 0)
3852 {
3853 set.insert(depthStencilBuffer->getTextureSerial());
3854 }
3855
3856 return set;
3857}
3858
Geoff Lang758d5b22013-06-11 11:42:50 -04003859void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3860 GLbitfield mask, GLenum filter)
3861{
3862 Framebuffer *readFramebuffer = getReadFramebuffer();
3863 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3864
3865 bool blitRenderTarget = false;
Geoff Lang685806d2013-06-12 11:16:36 -04003866 bool blitDepth = false;
3867 bool blitStencil = false;
Geoff Lang758d5b22013-06-11 11:42:50 -04003868 if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003869 {
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003870 blitRenderTarget = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04003871 }
3872 if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
3873 {
Geoff Lang685806d2013-06-12 11:16:36 -04003874 blitStencil = true;
Geoff Lang758d5b22013-06-11 11:42:50 -04003875 }
3876 if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
3877 {
Geoff Lang685806d2013-06-12 11:16:36 -04003878 blitDepth = true;
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003879 }
3880
Geoff Lang125deab2013-08-09 13:34:16 -04003881 gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
3882 gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
Geoff Lang685806d2013-06-12 11:16:36 -04003883 if (blitRenderTarget || blitDepth || blitStencil)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003884 {
Geoff Lang125deab2013-08-09 13:34:16 -04003885 const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL;
3886 mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
Geoff Lang685806d2013-06-12 11:16:36 -04003887 blitRenderTarget, blitDepth, blitStencil, filter);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003888 }
3889}
3890
shannonwoods@chromium.orgd63ef892013-05-30 00:10:56 +00003891void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
3892 GLint x, GLint y, GLsizei width, GLsizei height)
3893{
3894 Framebuffer *frameBuffer = NULL;
3895 switch (target)
3896 {
3897 case GL_FRAMEBUFFER:
3898 case GL_DRAW_FRAMEBUFFER:
3899 frameBuffer = getDrawFramebuffer();
3900 break;
3901 case GL_READ_FRAMEBUFFER:
3902 frameBuffer = getReadFramebuffer();
3903 break;
3904 default:
3905 UNREACHABLE();
3906 }
3907
3908 if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
3909 {
3910 for (int i = 0; i < numAttachments; ++i)
3911 {
3912 rx::RenderTarget *renderTarget = NULL;
3913
3914 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
3915 {
3916 gl::Renderbuffer *renderBuffer = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
3917 if (renderBuffer)
3918 {
3919 renderTarget = renderBuffer->getRenderTarget();
3920 }
3921 }
3922 else if (attachments[i] == GL_COLOR)
3923 {
3924 gl::Renderbuffer *renderBuffer = frameBuffer->getColorbuffer(0);
3925 if (renderBuffer)
3926 {
3927 renderTarget = renderBuffer->getRenderTarget();
3928 }
3929 }
3930 else
3931 {
3932 gl::Renderbuffer *renderBuffer = NULL;
3933 switch (attachments[i])
3934 {
3935 case GL_DEPTH_ATTACHMENT:
3936 case GL_DEPTH:
3937 renderBuffer = frameBuffer->getDepthbuffer();
3938 break;
3939 case GL_STENCIL_ATTACHMENT:
3940 case GL_STENCIL:
3941 renderBuffer = frameBuffer->getStencilbuffer();
3942 break;
3943 case GL_DEPTH_STENCIL_ATTACHMENT:
3944 renderBuffer = frameBuffer->getDepthOrStencilbuffer();
3945 break;
3946 default:
3947 UNREACHABLE();
3948 }
3949
3950 if (renderBuffer)
3951 {
3952 renderTarget = renderBuffer->getDepthStencil();
3953 }
3954 }
3955
3956 if (renderTarget)
3957 {
3958 renderTarget->invalidate(x, y, width, height);
3959 }
3960 }
3961 }
3962}
3963
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003964}
3965
3966extern "C"
3967{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00003968gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003969{
shannon.woods%transgaming.com@gtempaccount.comdaea4b42013-04-13 03:28:54 +00003970 return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003971}
3972
3973void glDestroyContext(gl::Context *context)
3974{
3975 delete context;
3976
3977 if (context == gl::getContext())
3978 {
3979 gl::makeCurrent(NULL, NULL, NULL);
3980 }
3981}
3982
3983void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
3984{
3985 gl::makeCurrent(context, display, surface);
3986}
3987
3988gl::Context *glGetCurrentContext()
3989{
3990 return gl::getContext();
3991}
daniel@transgaming.com621ce052012-10-31 17:52:29 +00003992
apatrick@chromium.org144f2802012-07-12 01:42:34 +00003993}