blob: 90ec71e425701d4f2b74085add0881e6be560bf4 [file] [log] [blame]
Shannon Woods53a94a82014-06-24 15:20:36 -04001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// State.cpp: Implements the State class, encapsulating raw GL state.
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/State.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040010
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
12#include "libANGLE/Caps.h"
13#include "libANGLE/Framebuffer.h"
14#include "libANGLE/FramebufferAttachment.h"
15#include "libANGLE/Query.h"
16#include "libANGLE/VertexArray.h"
17#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040018
19namespace gl
20{
Geoff Lang76b10c92014-09-05 16:28:14 -040021
Shannon Woods53a94a82014-06-24 15:20:36 -040022State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050023 : mMaxDrawBuffers(0),
24 mMaxCombinedTextureImageUnits(0),
25 mDepthClearValue(0),
26 mStencilClearValue(0),
27 mScissorTest(false),
28 mSampleCoverage(false),
29 mSampleCoverageValue(0),
30 mSampleCoverageInvert(false),
31 mStencilRef(0),
32 mStencilBackRef(0),
33 mLineWidth(0),
34 mGenerateMipmapHint(GL_NONE),
35 mFragmentShaderDerivativeHint(GL_NONE),
36 mNearZ(0),
37 mFarZ(0),
38 mReadFramebuffer(nullptr),
39 mDrawFramebuffer(nullptr),
40 mProgram(nullptr),
41 mVertexArray(nullptr),
42 mActiveSampler(0),
43 mPrimitiveRestart(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040044{
Jamie Madill1b94d432015-08-07 13:23:23 -040045 // Initialize dirty bit masks
46 // TODO(jmadill): additional ES3 state
47 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
48 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongadff67b2015-10-14 10:34:45 -040049 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
50 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
51 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
52 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040053
Jamie Madill1b94d432015-08-07 13:23:23 -040054 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
55 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Minmin Gongadff67b2015-10-14 10:34:45 -040056 mPackStateBitMask.set(DIRTY_BIT_PACK_ROW_LENGTH);
57 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_ROWS);
58 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040059
Jamie Madill1b94d432015-08-07 13:23:23 -040060 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
61 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
62 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
63 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
64 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
65 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
66 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
67 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
68 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
69 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
70 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang242468f2015-09-24 14:15:41 -040071
72 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
73 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR);
Geoff Lang76b10c92014-09-05 16:28:14 -040074}
75
76State::~State()
77{
78 reset();
79}
80
Jamie Madillc185cb82015-04-28 12:39:08 -040081void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040082{
Shannon Woods2df6a602014-09-26 16:12:07 -040083 mMaxDrawBuffers = caps.maxDrawBuffers;
84 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040085
Jamie Madillf75ab352015-03-16 10:46:52 -040086 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040087
88 mDepthClearValue = 1.0f;
89 mStencilClearValue = 0;
90
91 mRasterizer.rasterizerDiscard = false;
92 mRasterizer.cullFace = false;
93 mRasterizer.cullMode = GL_BACK;
94 mRasterizer.frontFace = GL_CCW;
95 mRasterizer.polygonOffsetFill = false;
96 mRasterizer.polygonOffsetFactor = 0.0f;
97 mRasterizer.polygonOffsetUnits = 0.0f;
98 mRasterizer.pointDrawMode = false;
99 mRasterizer.multiSample = false;
100 mScissorTest = false;
101 mScissor.x = 0;
102 mScissor.y = 0;
103 mScissor.width = 0;
104 mScissor.height = 0;
105
106 mBlend.blend = false;
107 mBlend.sourceBlendRGB = GL_ONE;
108 mBlend.sourceBlendAlpha = GL_ONE;
109 mBlend.destBlendRGB = GL_ZERO;
110 mBlend.destBlendAlpha = GL_ZERO;
111 mBlend.blendEquationRGB = GL_FUNC_ADD;
112 mBlend.blendEquationAlpha = GL_FUNC_ADD;
113 mBlend.sampleAlphaToCoverage = false;
114 mBlend.dither = true;
115
116 mBlendColor.red = 0;
117 mBlendColor.green = 0;
118 mBlendColor.blue = 0;
119 mBlendColor.alpha = 0;
120
121 mDepthStencil.depthTest = false;
122 mDepthStencil.depthFunc = GL_LESS;
123 mDepthStencil.depthMask = true;
124 mDepthStencil.stencilTest = false;
125 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700126 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
127 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400128 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700129 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
130 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400131 mDepthStencil.stencilFail = GL_KEEP;
132 mDepthStencil.stencilPassDepthFail = GL_KEEP;
133 mDepthStencil.stencilPassDepthPass = GL_KEEP;
134 mDepthStencil.stencilBackFail = GL_KEEP;
135 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
136 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
137
138 mStencilRef = 0;
139 mStencilBackRef = 0;
140
141 mSampleCoverage = false;
142 mSampleCoverageValue = 1.0f;
143 mSampleCoverageInvert = false;
144 mGenerateMipmapHint = GL_DONT_CARE;
145 mFragmentShaderDerivativeHint = GL_DONT_CARE;
146
147 mLineWidth = 1.0f;
148
149 mViewport.x = 0;
150 mViewport.y = 0;
151 mViewport.width = 0;
152 mViewport.height = 0;
153 mNearZ = 0.0f;
154 mFarZ = 1.0f;
155
156 mBlend.colorMaskRed = true;
157 mBlend.colorMaskGreen = true;
158 mBlend.colorMaskBlue = true;
159 mBlend.colorMaskAlpha = true;
160
Geoff Lang76b10c92014-09-05 16:28:14 -0400161 mActiveSampler = 0;
162
Shannon Woods23e05002014-09-22 19:07:27 -0400163 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400164
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400165 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
166
Geoff Lang76b10c92014-09-05 16:28:14 -0400167 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
168 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
169 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400170 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400171 // TODO: These could also be enabled via extension
172 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
173 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400174 }
175
Geoff Lang76b10c92014-09-05 16:28:14 -0400176 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400177
178 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
179 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
180 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
181
Geoff Lang7dd2e102014-11-10 15:19:26 -0500182 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400183
184 mReadFramebuffer = NULL;
185 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500186
187 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400188}
189
Geoff Lang76b10c92014-09-05 16:28:14 -0400190void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400191{
Geoff Lang76b10c92014-09-05 16:28:14 -0400192 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400193 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400194 TextureBindingVector &textureVector = bindingVec->second;
195 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400196 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400197 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400198 }
199 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400200 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
201 {
202 mSamplers[samplerIdx].set(NULL);
203 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400204
Shannon Woods53a94a82014-06-24 15:20:36 -0400205 mArrayBuffer.set(NULL);
206 mRenderbuffer.set(NULL);
207
Geoff Lang7dd2e102014-11-10 15:19:26 -0500208 if (mProgram)
209 {
210 mProgram->release();
211 }
212 mProgram = NULL;
213
Shannon Woods53a94a82014-06-24 15:20:36 -0400214 mTransformFeedback.set(NULL);
215
216 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
217 {
218 i->second.set(NULL);
219 }
220
221 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400222 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400223 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400224 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400225 }
226
Shannon Woods53a94a82014-06-24 15:20:36 -0400227 mCopyReadBuffer.set(NULL);
228 mCopyWriteBuffer.set(NULL);
229
230 mPack.pixelBuffer.set(NULL);
231 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500232
233 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400234
235 // TODO(jmadill): Is this necessary?
236 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400237}
238
239const RasterizerState &State::getRasterizerState() const
240{
241 return mRasterizer;
242}
243
244const BlendState &State::getBlendState() const
245{
246 return mBlend;
247}
248
249const DepthStencilState &State::getDepthStencilState() const
250{
251 return mDepthStencil;
252}
253
Jamie Madillf75ab352015-03-16 10:46:52 -0400254void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400255{
256 mColorClearValue.red = red;
257 mColorClearValue.green = green;
258 mColorClearValue.blue = blue;
259 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400260 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400261}
262
Jamie Madillf75ab352015-03-16 10:46:52 -0400263void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400264{
265 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400266 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400267}
268
Jamie Madillf75ab352015-03-16 10:46:52 -0400269void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400270{
271 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400272 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400273}
274
Shannon Woods53a94a82014-06-24 15:20:36 -0400275void State::setColorMask(bool red, bool green, bool blue, bool alpha)
276{
277 mBlend.colorMaskRed = red;
278 mBlend.colorMaskGreen = green;
279 mBlend.colorMaskBlue = blue;
280 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400281 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400282}
283
284void State::setDepthMask(bool mask)
285{
286 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400287 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400288}
289
290bool State::isRasterizerDiscardEnabled() const
291{
292 return mRasterizer.rasterizerDiscard;
293}
294
295void State::setRasterizerDiscard(bool enabled)
296{
297 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400298 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400299}
300
301bool State::isCullFaceEnabled() const
302{
303 return mRasterizer.cullFace;
304}
305
306void State::setCullFace(bool enabled)
307{
308 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400309 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400310}
311
312void State::setCullMode(GLenum mode)
313{
314 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400315 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400316}
317
318void State::setFrontFace(GLenum front)
319{
320 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400321 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400322}
323
324bool State::isDepthTestEnabled() const
325{
326 return mDepthStencil.depthTest;
327}
328
329void State::setDepthTest(bool enabled)
330{
331 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400332 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400333}
334
335void State::setDepthFunc(GLenum depthFunc)
336{
337 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400338 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400339}
340
341void State::setDepthRange(float zNear, float zFar)
342{
343 mNearZ = zNear;
344 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400345 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400346}
347
Geoff Langd42f5b82015-04-16 14:03:29 -0400348float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400349{
Geoff Langd42f5b82015-04-16 14:03:29 -0400350 return mNearZ;
351}
352
353float State::getFarPlane() const
354{
355 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400356}
357
358bool State::isBlendEnabled() const
359{
360 return mBlend.blend;
361}
362
363void State::setBlend(bool enabled)
364{
365 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400366 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400367}
368
369void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
370{
371 mBlend.sourceBlendRGB = sourceRGB;
372 mBlend.destBlendRGB = destRGB;
373 mBlend.sourceBlendAlpha = sourceAlpha;
374 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400375 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400376}
377
378void State::setBlendColor(float red, float green, float blue, float alpha)
379{
380 mBlendColor.red = red;
381 mBlendColor.green = green;
382 mBlendColor.blue = blue;
383 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400384 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400385}
386
387void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
388{
389 mBlend.blendEquationRGB = rgbEquation;
390 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400391 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400392}
393
394const ColorF &State::getBlendColor() const
395{
396 return mBlendColor;
397}
398
399bool State::isStencilTestEnabled() const
400{
401 return mDepthStencil.stencilTest;
402}
403
404void State::setStencilTest(bool enabled)
405{
406 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400407 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400408}
409
410void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
411{
412 mDepthStencil.stencilFunc = stencilFunc;
413 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
414 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400415 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400416}
417
418void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
419{
420 mDepthStencil.stencilBackFunc = stencilBackFunc;
421 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
422 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400423 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400424}
425
426void State::setStencilWritemask(GLuint stencilWritemask)
427{
428 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400429 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400430}
431
432void State::setStencilBackWritemask(GLuint stencilBackWritemask)
433{
434 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400435 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400436}
437
438void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
439{
440 mDepthStencil.stencilFail = stencilFail;
441 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
442 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400443 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400444}
445
446void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
447{
448 mDepthStencil.stencilBackFail = stencilBackFail;
449 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
450 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400451 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400452}
453
454GLint State::getStencilRef() const
455{
456 return mStencilRef;
457}
458
459GLint State::getStencilBackRef() const
460{
461 return mStencilBackRef;
462}
463
464bool State::isPolygonOffsetFillEnabled() const
465{
466 return mRasterizer.polygonOffsetFill;
467}
468
469void State::setPolygonOffsetFill(bool enabled)
470{
Jamie Madill1b94d432015-08-07 13:23:23 -0400471 mRasterizer.polygonOffsetFill = enabled;
472 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400473}
474
475void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
476{
477 // An application can pass NaN values here, so handle this gracefully
478 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
479 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400480 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400481}
482
483bool State::isSampleAlphaToCoverageEnabled() const
484{
485 return mBlend.sampleAlphaToCoverage;
486}
487
488void State::setSampleAlphaToCoverage(bool enabled)
489{
490 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400491 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400492}
493
494bool State::isSampleCoverageEnabled() const
495{
496 return mSampleCoverage;
497}
498
499void State::setSampleCoverage(bool enabled)
500{
501 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400502 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400503}
504
505void State::setSampleCoverageParams(GLclampf value, bool invert)
506{
507 mSampleCoverageValue = value;
508 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400509 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400510}
511
Geoff Lang0fbb6002015-04-16 11:11:53 -0400512GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400513{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400514 return mSampleCoverageValue;
515}
Shannon Woods53a94a82014-06-24 15:20:36 -0400516
Geoff Lang0fbb6002015-04-16 11:11:53 -0400517bool State::getSampleCoverageInvert() const
518{
519 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400520}
521
522bool State::isScissorTestEnabled() const
523{
524 return mScissorTest;
525}
526
527void State::setScissorTest(bool enabled)
528{
529 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400530 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400531}
532
533void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
534{
535 mScissor.x = x;
536 mScissor.y = y;
537 mScissor.width = width;
538 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400539 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400540}
541
542const Rectangle &State::getScissor() const
543{
544 return mScissor;
545}
546
547bool State::isDitherEnabled() const
548{
549 return mBlend.dither;
550}
551
552void State::setDither(bool enabled)
553{
554 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400555 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400556}
557
Jamie Madillb4b53c52015-02-03 15:22:48 -0500558bool State::isPrimitiveRestartEnabled() const
559{
560 return mPrimitiveRestart;
561}
562
563void State::setPrimitiveRestart(bool enabled)
564{
565 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400566 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500567}
568
Shannon Woods53a94a82014-06-24 15:20:36 -0400569void State::setEnableFeature(GLenum feature, bool enabled)
570{
571 switch (feature)
572 {
573 case GL_CULL_FACE: setCullFace(enabled); break;
574 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
575 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
576 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
577 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
578 case GL_STENCIL_TEST: setStencilTest(enabled); break;
579 case GL_DEPTH_TEST: setDepthTest(enabled); break;
580 case GL_BLEND: setBlend(enabled); break;
581 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500582 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400583 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
584 default: UNREACHABLE();
585 }
586}
587
588bool State::getEnableFeature(GLenum feature)
589{
590 switch (feature)
591 {
592 case GL_CULL_FACE: return isCullFaceEnabled();
593 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
594 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
595 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
596 case GL_SCISSOR_TEST: return isScissorTestEnabled();
597 case GL_STENCIL_TEST: return isStencilTestEnabled();
598 case GL_DEPTH_TEST: return isDepthTestEnabled();
599 case GL_BLEND: return isBlendEnabled();
600 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500601 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400602 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
603 default: UNREACHABLE(); return false;
604 }
605}
606
607void State::setLineWidth(GLfloat width)
608{
609 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400610 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400611}
612
Geoff Lang4b3f4162015-04-16 13:22:05 -0400613float State::getLineWidth() const
614{
615 return mLineWidth;
616}
617
Shannon Woods53a94a82014-06-24 15:20:36 -0400618void State::setGenerateMipmapHint(GLenum hint)
619{
620 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400621 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400622}
623
624void State::setFragmentShaderDerivativeHint(GLenum hint)
625{
626 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400627 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400628 // TODO: Propagate the hint to shader translator so we can write
629 // ddx, ddx_coarse, or ddx_fine depending on the hint.
630 // Ignore for now. It is valid for implementations to ignore hint.
631}
632
633void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
634{
635 mViewport.x = x;
636 mViewport.y = y;
637 mViewport.width = width;
638 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400639 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400640}
641
642const Rectangle &State::getViewport() const
643{
644 return mViewport;
645}
646
647void State::setActiveSampler(unsigned int active)
648{
649 mActiveSampler = active;
650}
651
652unsigned int State::getActiveSampler() const
653{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700654 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400655}
656
Geoff Lang76b10c92014-09-05 16:28:14 -0400657void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400658{
Geoff Lang76b10c92014-09-05 16:28:14 -0400659 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400660}
661
Geoff Lang76b10c92014-09-05 16:28:14 -0400662Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400663{
Jamie Madill5864ac22015-01-12 14:43:07 -0500664 const auto it = mSamplerTextures.find(type);
665 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400666 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500667 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400668}
669
Geoff Lang76b10c92014-09-05 16:28:14 -0400670GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400671{
Jamie Madill5864ac22015-01-12 14:43:07 -0500672 const auto it = mSamplerTextures.find(type);
673 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400674 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500675 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400676}
677
Jamie Madille6382c32014-11-07 15:05:26 -0500678void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400679{
680 // Textures have a detach method on State rather than a simple
681 // removeBinding, because the zero/null texture objects are managed
682 // separately, and don't have to go through the Context's maps or
683 // the ResourceManager.
684
685 // [OpenGL ES 2.0.24] section 3.8 page 84:
686 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
687 // rebound to texture object zero
688
Geoff Lang76b10c92014-09-05 16:28:14 -0400689 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400690 {
Jamie Madille6382c32014-11-07 15:05:26 -0500691 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400692 TextureBindingVector &textureVector = bindingVec->second;
693 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400694 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400695 BindingPointer<Texture> &binding = textureVector[textureIdx];
696 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400697 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500698 auto it = zeroTextures.find(textureType);
699 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500700 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500701 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400702 }
703 }
704 }
705
706 // [OpenGL ES 2.0.24] section 4.4 page 112:
707 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
708 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
709 // image was attached in the currently bound framebuffer.
710
711 if (mReadFramebuffer)
712 {
713 mReadFramebuffer->detachTexture(texture);
714 }
715
716 if (mDrawFramebuffer)
717 {
718 mDrawFramebuffer->detachTexture(texture);
719 }
720}
721
Jamie Madille6382c32014-11-07 15:05:26 -0500722void State::initializeZeroTextures(const TextureMap &zeroTextures)
723{
724 for (const auto &zeroTexture : zeroTextures)
725 {
726 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
727
728 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
729 {
730 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
731 }
732 }
733}
734
Shannon Woods53a94a82014-06-24 15:20:36 -0400735void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
736{
737 mSamplers[textureUnit].set(sampler);
738}
739
740GLuint State::getSamplerId(GLuint textureUnit) const
741{
Geoff Lang76b10c92014-09-05 16:28:14 -0400742 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400743 return mSamplers[textureUnit].id();
744}
745
746Sampler *State::getSampler(GLuint textureUnit) const
747{
748 return mSamplers[textureUnit].get();
749}
750
751void State::detachSampler(GLuint sampler)
752{
753 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
754 // If a sampler object that is currently bound to one or more texture units is
755 // deleted, it is as though BindSampler is called once for each texture unit to
756 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400757 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400758 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400759 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
760 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400761 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400762 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400763 }
764 }
765}
766
767void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
768{
769 mRenderbuffer.set(renderbuffer);
770}
771
772GLuint State::getRenderbufferId() const
773{
774 return mRenderbuffer.id();
775}
776
777Renderbuffer *State::getCurrentRenderbuffer()
778{
779 return mRenderbuffer.get();
780}
781
782void State::detachRenderbuffer(GLuint renderbuffer)
783{
784 // [OpenGL ES 2.0.24] section 4.4 page 109:
785 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
786 // had been executed with the target RENDERBUFFER and name of zero.
787
788 if (mRenderbuffer.id() == renderbuffer)
789 {
790 mRenderbuffer.set(NULL);
791 }
792
793 // [OpenGL ES 2.0.24] section 4.4 page 111:
794 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
795 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
796 // point to which this image was attached in the currently bound framebuffer.
797
798 Framebuffer *readFramebuffer = mReadFramebuffer;
799 Framebuffer *drawFramebuffer = mDrawFramebuffer;
800
801 if (readFramebuffer)
802 {
803 readFramebuffer->detachRenderbuffer(renderbuffer);
804 }
805
806 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
807 {
808 drawFramebuffer->detachRenderbuffer(renderbuffer);
809 }
810
811}
812
813void State::setReadFramebufferBinding(Framebuffer *framebuffer)
814{
815 mReadFramebuffer = framebuffer;
816}
817
818void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
819{
820 mDrawFramebuffer = framebuffer;
821}
822
823Framebuffer *State::getTargetFramebuffer(GLenum target) const
824{
825 switch (target)
826 {
827 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
828 case GL_DRAW_FRAMEBUFFER_ANGLE:
829 case GL_FRAMEBUFFER: return mDrawFramebuffer;
830 default: UNREACHABLE(); return NULL;
831 }
832}
833
834Framebuffer *State::getReadFramebuffer()
835{
836 return mReadFramebuffer;
837}
838
839Framebuffer *State::getDrawFramebuffer()
840{
841 return mDrawFramebuffer;
842}
843
844const Framebuffer *State::getReadFramebuffer() const
845{
846 return mReadFramebuffer;
847}
848
849const Framebuffer *State::getDrawFramebuffer() const
850{
851 return mDrawFramebuffer;
852}
853
854bool State::removeReadFramebufferBinding(GLuint framebuffer)
855{
Jamie Madill77a72f62015-04-14 11:18:32 -0400856 if (mReadFramebuffer != nullptr &&
857 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400858 {
859 mReadFramebuffer = NULL;
860 return true;
861 }
862
863 return false;
864}
865
866bool State::removeDrawFramebufferBinding(GLuint framebuffer)
867{
Jamie Madill77a72f62015-04-14 11:18:32 -0400868 if (mReadFramebuffer != nullptr &&
869 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400870 {
871 mDrawFramebuffer = NULL;
872 return true;
873 }
874
875 return false;
876}
877
878void State::setVertexArrayBinding(VertexArray *vertexArray)
879{
880 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000881 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
882 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400883}
884
885GLuint State::getVertexArrayId() const
886{
887 ASSERT(mVertexArray != NULL);
888 return mVertexArray->id();
889}
890
891VertexArray *State::getVertexArray() const
892{
893 ASSERT(mVertexArray != NULL);
894 return mVertexArray;
895}
896
897bool State::removeVertexArrayBinding(GLuint vertexArray)
898{
899 if (mVertexArray->id() == vertexArray)
900 {
901 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000902 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
903 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400904 return true;
905 }
906
907 return false;
908}
909
Geoff Lang7dd2e102014-11-10 15:19:26 -0500910void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400911{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500912 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400913 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500914 if (mProgram)
915 {
916 mProgram->release();
917 }
918
919 mProgram = newProgram;
920
921 if (mProgram)
922 {
923 newProgram->addRef();
924 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400925 }
926}
927
Geoff Lang7dd2e102014-11-10 15:19:26 -0500928Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400929{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500930 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400931}
932
933void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
934{
935 mTransformFeedback.set(transformFeedback);
936}
937
938TransformFeedback *State::getCurrentTransformFeedback() const
939{
940 return mTransformFeedback.get();
941}
942
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000943bool State::isTransformFeedbackActiveUnpaused() const
944{
945 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400946 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000947}
948
Shannon Woods53a94a82014-06-24 15:20:36 -0400949void State::detachTransformFeedback(GLuint transformFeedback)
950{
951 if (mTransformFeedback.id() == transformFeedback)
952 {
953 mTransformFeedback.set(NULL);
954 }
955}
956
957bool State::isQueryActive() const
958{
959 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
960 i != mActiveQueries.end(); i++)
961 {
962 if (i->second.get() != NULL)
963 {
964 return true;
965 }
966 }
967
968 return false;
969}
970
971void State::setActiveQuery(GLenum target, Query *query)
972{
973 mActiveQueries[target].set(query);
974}
975
976GLuint State::getActiveQueryId(GLenum target) const
977{
978 const Query *query = getActiveQuery(target);
979 return (query ? query->id() : 0u);
980}
981
982Query *State::getActiveQuery(GLenum target) const
983{
Jamie Madill5864ac22015-01-12 14:43:07 -0500984 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400985
Jamie Madill5864ac22015-01-12 14:43:07 -0500986 // All query types should already exist in the activeQueries map
987 ASSERT(it != mActiveQueries.end());
988
989 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400990}
991
992void State::setArrayBufferBinding(Buffer *buffer)
993{
994 mArrayBuffer.set(buffer);
995}
996
997GLuint State::getArrayBufferId() const
998{
999 return mArrayBuffer.id();
1000}
1001
1002bool State::removeArrayBufferBinding(GLuint buffer)
1003{
1004 if (mArrayBuffer.id() == buffer)
1005 {
1006 mArrayBuffer.set(NULL);
1007 return true;
1008 }
1009
1010 return false;
1011}
1012
1013void State::setGenericUniformBufferBinding(Buffer *buffer)
1014{
1015 mGenericUniformBuffer.set(buffer);
1016}
1017
1018void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1019{
1020 mUniformBuffers[index].set(buffer, offset, size);
1021}
1022
Geoff Lang5d124a62015-09-15 13:03:27 -04001023const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001024{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001025 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001026 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001027}
1028
Shannon Woods53a94a82014-06-24 15:20:36 -04001029void State::setCopyReadBufferBinding(Buffer *buffer)
1030{
1031 mCopyReadBuffer.set(buffer);
1032}
1033
1034void State::setCopyWriteBufferBinding(Buffer *buffer)
1035{
1036 mCopyWriteBuffer.set(buffer);
1037}
1038
1039void State::setPixelPackBufferBinding(Buffer *buffer)
1040{
1041 mPack.pixelBuffer.set(buffer);
1042}
1043
1044void State::setPixelUnpackBufferBinding(Buffer *buffer)
1045{
1046 mUnpack.pixelBuffer.set(buffer);
1047}
1048
1049Buffer *State::getTargetBuffer(GLenum target) const
1050{
1051 switch (target)
1052 {
1053 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1054 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1055 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001056 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001057 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1058 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001059 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001060 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1061 default: UNREACHABLE(); return NULL;
1062 }
1063}
1064
1065void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1066{
1067 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001068 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001069}
1070
1071void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1072{
Shannon Woods23e05002014-09-22 19:07:27 -04001073 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001074 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001075 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001076}
1077
1078void State::setVertexAttribu(GLuint index, const GLuint values[4])
1079{
Shannon Woods23e05002014-09-22 19:07:27 -04001080 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001081 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001082 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001083}
1084
1085void State::setVertexAttribi(GLuint index, const GLint values[4])
1086{
Shannon Woods23e05002014-09-22 19:07:27 -04001087 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001088 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001089 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001090}
1091
Jamie Madill0b9e9032015-08-17 11:51:52 +00001092void State::setVertexAttribState(unsigned int attribNum,
1093 Buffer *boundBuffer,
1094 GLint size,
1095 GLenum type,
1096 bool normalized,
1097 bool pureInteger,
1098 GLsizei stride,
1099 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001100{
1101 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001102 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
1103}
1104
1105void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1106{
1107 getVertexArray()->setVertexAttribDivisor(index, divisor);
1108 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001109}
1110
Shannon Woods53a94a82014-06-24 15:20:36 -04001111const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1112{
Shannon Woods23e05002014-09-22 19:07:27 -04001113 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001114 return mVertexAttribCurrentValues[attribNum];
1115}
1116
Shannon Woods53a94a82014-06-24 15:20:36 -04001117const void *State::getVertexAttribPointer(unsigned int attribNum) const
1118{
1119 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1120}
1121
1122void State::setPackAlignment(GLint alignment)
1123{
1124 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001125 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001126}
1127
1128GLint State::getPackAlignment() const
1129{
1130 return mPack.alignment;
1131}
1132
1133void State::setPackReverseRowOrder(bool reverseRowOrder)
1134{
1135 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001136 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001137}
1138
1139bool State::getPackReverseRowOrder() const
1140{
1141 return mPack.reverseRowOrder;
1142}
1143
Minmin Gongadff67b2015-10-14 10:34:45 -04001144void State::setPackRowLength(GLint rowLength)
1145{
1146 mPack.rowLength = rowLength;
1147 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1148}
1149
1150GLint State::getPackRowLength() const
1151{
1152 return mPack.rowLength;
1153}
1154
1155void State::setPackSkipRows(GLint skipRows)
1156{
1157 mPack.skipRows = skipRows;
1158 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1159}
1160
1161GLint State::getPackSkipRows() const
1162{
1163 return mPack.skipRows;
1164}
1165
1166void State::setPackSkipPixels(GLint skipPixels)
1167{
1168 mPack.skipPixels = skipPixels;
1169 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1170}
1171
1172GLint State::getPackSkipPixels() const
1173{
1174 return mPack.skipPixels;
1175}
1176
Shannon Woods53a94a82014-06-24 15:20:36 -04001177const PixelPackState &State::getPackState() const
1178{
1179 return mPack;
1180}
1181
Jamie Madill87de3622015-03-16 10:41:44 -04001182PixelPackState &State::getPackState()
1183{
1184 return mPack;
1185}
1186
Shannon Woods53a94a82014-06-24 15:20:36 -04001187void State::setUnpackAlignment(GLint alignment)
1188{
1189 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001190 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001191}
1192
1193GLint State::getUnpackAlignment() const
1194{
1195 return mUnpack.alignment;
1196}
1197
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001198void State::setUnpackRowLength(GLint rowLength)
1199{
1200 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001201 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001202}
1203
1204GLint State::getUnpackRowLength() const
1205{
1206 return mUnpack.rowLength;
1207}
1208
Minmin Gongadff67b2015-10-14 10:34:45 -04001209void State::setUnpackImageHeight(GLint imageHeight)
1210{
1211 mUnpack.imageHeight = imageHeight;
1212 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1213}
1214
1215GLint State::getUnpackImageHeight() const
1216{
1217 return mUnpack.imageHeight;
1218}
1219
1220void State::setUnpackSkipImages(GLint skipImages)
1221{
1222 mUnpack.skipImages = skipImages;
1223 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1224}
1225
1226GLint State::getUnpackSkipImages() const
1227{
1228 return mUnpack.skipImages;
1229}
1230
1231void State::setUnpackSkipRows(GLint skipRows)
1232{
1233 mUnpack.skipRows = skipRows;
1234 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1235}
1236
1237GLint State::getUnpackSkipRows() const
1238{
1239 return mUnpack.skipRows;
1240}
1241
1242void State::setUnpackSkipPixels(GLint skipPixels)
1243{
1244 mUnpack.skipPixels = skipPixels;
1245 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1246}
1247
1248GLint State::getUnpackSkipPixels() const
1249{
1250 return mUnpack.skipPixels;
1251}
1252
Shannon Woods53a94a82014-06-24 15:20:36 -04001253const PixelUnpackState &State::getUnpackState() const
1254{
1255 return mUnpack;
1256}
1257
Jamie Madill67102f02015-03-16 10:41:42 -04001258PixelUnpackState &State::getUnpackState()
1259{
1260 return mUnpack;
1261}
1262
Shannon Woods53a94a82014-06-24 15:20:36 -04001263void State::getBooleanv(GLenum pname, GLboolean *params)
1264{
1265 switch (pname)
1266 {
1267 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1268 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1269 case GL_COLOR_WRITEMASK:
1270 params[0] = mBlend.colorMaskRed;
1271 params[1] = mBlend.colorMaskGreen;
1272 params[2] = mBlend.colorMaskBlue;
1273 params[3] = mBlend.colorMaskAlpha;
1274 break;
1275 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1276 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1277 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1278 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1279 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1280 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1281 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1282 case GL_BLEND: *params = mBlend.blend; break;
1283 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001284 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1285 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001286 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1287 *params = mPrimitiveRestart;
1288 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001289 default:
1290 UNREACHABLE();
1291 break;
1292 }
1293}
1294
1295void State::getFloatv(GLenum pname, GLfloat *params)
1296{
1297 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1298 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1299 // GetIntegerv as its native query function. As it would require conversion in any
1300 // case, this should make no difference to the calling application.
1301 switch (pname)
1302 {
1303 case GL_LINE_WIDTH: *params = mLineWidth; break;
1304 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1305 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1306 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1307 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1308 case GL_DEPTH_RANGE:
1309 params[0] = mNearZ;
1310 params[1] = mFarZ;
1311 break;
1312 case GL_COLOR_CLEAR_VALUE:
1313 params[0] = mColorClearValue.red;
1314 params[1] = mColorClearValue.green;
1315 params[2] = mColorClearValue.blue;
1316 params[3] = mColorClearValue.alpha;
1317 break;
1318 case GL_BLEND_COLOR:
1319 params[0] = mBlendColor.red;
1320 params[1] = mBlendColor.green;
1321 params[2] = mBlendColor.blue;
1322 params[3] = mBlendColor.alpha;
1323 break;
1324 default:
1325 UNREACHABLE();
1326 break;
1327 }
1328}
1329
Jamie Madill48faf802014-11-06 15:27:22 -05001330void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001331{
1332 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1333 {
1334 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001335 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001336 Framebuffer *framebuffer = mDrawFramebuffer;
1337 *params = framebuffer->getDrawBufferState(colorAttachment);
1338 return;
1339 }
1340
1341 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1342 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1343 // GetIntegerv as its native query function. As it would require conversion in any
1344 // case, this should make no difference to the calling application. You may find it in
1345 // State::getFloatv.
1346 switch (pname)
1347 {
1348 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001349 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001350 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1351 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1352 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1353 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1354 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001355 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001356 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1357 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001358 case GL_PACK_ROW_LENGTH:
1359 *params = mPack.rowLength;
1360 break;
1361 case GL_PACK_SKIP_ROWS:
1362 *params = mPack.skipRows;
1363 break;
1364 case GL_PACK_SKIP_PIXELS:
1365 *params = mPack.skipPixels;
1366 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001367 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001368 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001369 case GL_UNPACK_IMAGE_HEIGHT:
1370 *params = mUnpack.imageHeight;
1371 break;
1372 case GL_UNPACK_SKIP_IMAGES:
1373 *params = mUnpack.skipImages;
1374 break;
1375 case GL_UNPACK_SKIP_ROWS:
1376 *params = mUnpack.skipRows;
1377 break;
1378 case GL_UNPACK_SKIP_PIXELS:
1379 *params = mUnpack.skipPixels;
1380 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001381 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1382 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001383 case GL_ACTIVE_TEXTURE:
1384 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1385 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001386 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1387 case GL_STENCIL_REF: *params = mStencilRef; break;
1388 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1389 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1390 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1391 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1392 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1393 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1394 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1395 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1396 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1397 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1398 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1399 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1400 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1401 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1402 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1403 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1404 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1405 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1406 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1407 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001408 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1409 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001410 case GL_SAMPLE_BUFFERS:
1411 case GL_SAMPLES:
1412 {
1413 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001414 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 {
1416 switch (pname)
1417 {
1418 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001419 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001420 {
1421 *params = 1;
1422 }
1423 else
1424 {
1425 *params = 0;
1426 }
1427 break;
1428 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001429 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001430 break;
1431 }
1432 }
1433 else
1434 {
1435 *params = 0;
1436 }
1437 }
1438 break;
1439 case GL_VIEWPORT:
1440 params[0] = mViewport.x;
1441 params[1] = mViewport.y;
1442 params[2] = mViewport.width;
1443 params[3] = mViewport.height;
1444 break;
1445 case GL_SCISSOR_BOX:
1446 params[0] = mScissor.x;
1447 params[1] = mScissor.y;
1448 params[2] = mScissor.width;
1449 params[3] = mScissor.height;
1450 break;
1451 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1452 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1453 case GL_RED_BITS:
1454 case GL_GREEN_BITS:
1455 case GL_BLUE_BITS:
1456 case GL_ALPHA_BITS:
1457 {
1458 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001459 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001460
1461 if (colorbuffer)
1462 {
1463 switch (pname)
1464 {
1465 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1466 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1467 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1468 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1469 }
1470 }
1471 else
1472 {
1473 *params = 0;
1474 }
1475 }
1476 break;
1477 case GL_DEPTH_BITS:
1478 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001479 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1480 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001481
1482 if (depthbuffer)
1483 {
1484 *params = depthbuffer->getDepthSize();
1485 }
1486 else
1487 {
1488 *params = 0;
1489 }
1490 }
1491 break;
1492 case GL_STENCIL_BITS:
1493 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001494 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1495 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001496
1497 if (stencilbuffer)
1498 {
1499 *params = stencilbuffer->getStencilSize();
1500 }
1501 else
1502 {
1503 *params = 0;
1504 }
1505 }
1506 break;
1507 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001508 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001509 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001510 break;
1511 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001512 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001513 *params =
1514 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001515 break;
1516 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001517 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001518 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001519 break;
1520 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001521 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001522 *params =
1523 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001524 break;
1525 case GL_UNIFORM_BUFFER_BINDING:
1526 *params = mGenericUniformBuffer.id();
1527 break;
1528 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001529 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001530 break;
1531 case GL_COPY_READ_BUFFER_BINDING:
1532 *params = mCopyReadBuffer.id();
1533 break;
1534 case GL_COPY_WRITE_BUFFER_BINDING:
1535 *params = mCopyWriteBuffer.id();
1536 break;
1537 case GL_PIXEL_PACK_BUFFER_BINDING:
1538 *params = mPack.pixelBuffer.id();
1539 break;
1540 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1541 *params = mUnpack.pixelBuffer.id();
1542 break;
1543 default:
1544 UNREACHABLE();
1545 break;
1546 }
1547}
1548
1549bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1550{
1551 switch (target)
1552 {
1553 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001554 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001555 {
Geoff Lang045536b2015-03-27 15:17:18 -04001556 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001557 }
1558 break;
1559 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001560 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001561 {
1562 *data = mUniformBuffers[index].id();
1563 }
1564 break;
1565 default:
1566 return false;
1567 }
1568
1569 return true;
1570}
1571
1572bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1573{
1574 switch (target)
1575 {
1576 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001577 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001578 {
Geoff Lang045536b2015-03-27 15:17:18 -04001579 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001580 }
1581 break;
1582 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001583 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001584 {
Geoff Lang045536b2015-03-27 15:17:18 -04001585 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001586 }
1587 break;
1588 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001589 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001590 {
1591 *data = mUniformBuffers[index].getOffset();
1592 }
1593 break;
1594 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001595 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001596 {
1597 *data = mUniformBuffers[index].getSize();
1598 }
1599 break;
1600 default:
1601 return false;
1602 }
1603
1604 return true;
1605}
1606
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001607bool State::hasMappedBuffer(GLenum target) const
1608{
1609 if (target == GL_ARRAY_BUFFER)
1610 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001611 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001612 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001613 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001614 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001615 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001616 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001617 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1618 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1619 {
1620 return true;
1621 }
1622 }
1623
1624 return false;
1625 }
1626 else
1627 {
1628 Buffer *buffer = getTargetBuffer(target);
1629 return (buffer && buffer->isMapped());
1630 }
1631}
1632
Shannon Woods53a94a82014-06-24 15:20:36 -04001633}