blob: e9e96a2431f208bbd05042c8f138720cdaacc8b2 [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()
23{
Shannon Woods2df6a602014-09-26 16:12:07 -040024 mMaxDrawBuffers = 0;
25 mMaxCombinedTextureImageUnits = 0;
Jamie Madill1b94d432015-08-07 13:23:23 -040026
27 // Initialize dirty bit masks
28 // TODO(jmadill): additional ES3 state
29 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
30 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongadff67b2015-10-14 10:34:45 -040031 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
32 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
33 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
34 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040035
Jamie Madill1b94d432015-08-07 13:23:23 -040036 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
37 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Minmin Gongadff67b2015-10-14 10:34:45 -040038 mPackStateBitMask.set(DIRTY_BIT_PACK_ROW_LENGTH);
39 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_ROWS);
40 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040041
Jamie Madill1b94d432015-08-07 13:23:23 -040042 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
43 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
44 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
45 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
46 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
47 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
48 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
49 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
50 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
51 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
52 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang242468f2015-09-24 14:15:41 -040053
54 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
55 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR);
Geoff Lang76b10c92014-09-05 16:28:14 -040056}
57
58State::~State()
59{
60 reset();
61}
62
Jamie Madillc185cb82015-04-28 12:39:08 -040063void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040064{
Shannon Woods2df6a602014-09-26 16:12:07 -040065 mMaxDrawBuffers = caps.maxDrawBuffers;
66 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040067
Jamie Madillf75ab352015-03-16 10:46:52 -040068 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040069
70 mDepthClearValue = 1.0f;
71 mStencilClearValue = 0;
72
73 mRasterizer.rasterizerDiscard = false;
74 mRasterizer.cullFace = false;
75 mRasterizer.cullMode = GL_BACK;
76 mRasterizer.frontFace = GL_CCW;
77 mRasterizer.polygonOffsetFill = false;
78 mRasterizer.polygonOffsetFactor = 0.0f;
79 mRasterizer.polygonOffsetUnits = 0.0f;
80 mRasterizer.pointDrawMode = false;
81 mRasterizer.multiSample = false;
82 mScissorTest = false;
83 mScissor.x = 0;
84 mScissor.y = 0;
85 mScissor.width = 0;
86 mScissor.height = 0;
87
88 mBlend.blend = false;
89 mBlend.sourceBlendRGB = GL_ONE;
90 mBlend.sourceBlendAlpha = GL_ONE;
91 mBlend.destBlendRGB = GL_ZERO;
92 mBlend.destBlendAlpha = GL_ZERO;
93 mBlend.blendEquationRGB = GL_FUNC_ADD;
94 mBlend.blendEquationAlpha = GL_FUNC_ADD;
95 mBlend.sampleAlphaToCoverage = false;
96 mBlend.dither = true;
97
98 mBlendColor.red = 0;
99 mBlendColor.green = 0;
100 mBlendColor.blue = 0;
101 mBlendColor.alpha = 0;
102
103 mDepthStencil.depthTest = false;
104 mDepthStencil.depthFunc = GL_LESS;
105 mDepthStencil.depthMask = true;
106 mDepthStencil.stencilTest = false;
107 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700108 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
109 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400110 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700111 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
112 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400113 mDepthStencil.stencilFail = GL_KEEP;
114 mDepthStencil.stencilPassDepthFail = GL_KEEP;
115 mDepthStencil.stencilPassDepthPass = GL_KEEP;
116 mDepthStencil.stencilBackFail = GL_KEEP;
117 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
118 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
119
120 mStencilRef = 0;
121 mStencilBackRef = 0;
122
123 mSampleCoverage = false;
124 mSampleCoverageValue = 1.0f;
125 mSampleCoverageInvert = false;
126 mGenerateMipmapHint = GL_DONT_CARE;
127 mFragmentShaderDerivativeHint = GL_DONT_CARE;
128
129 mLineWidth = 1.0f;
130
131 mViewport.x = 0;
132 mViewport.y = 0;
133 mViewport.width = 0;
134 mViewport.height = 0;
135 mNearZ = 0.0f;
136 mFarZ = 1.0f;
137
138 mBlend.colorMaskRed = true;
139 mBlend.colorMaskGreen = true;
140 mBlend.colorMaskBlue = true;
141 mBlend.colorMaskAlpha = true;
142
Geoff Lang76b10c92014-09-05 16:28:14 -0400143 mActiveSampler = 0;
144
Shannon Woods23e05002014-09-22 19:07:27 -0400145 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400146
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400147 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
148
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
150 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
151 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400152 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400153 // TODO: These could also be enabled via extension
154 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
155 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400156 }
157
Geoff Lang76b10c92014-09-05 16:28:14 -0400158 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400159
160 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
161 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
162 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
163
Geoff Lang7dd2e102014-11-10 15:19:26 -0500164 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400165
166 mReadFramebuffer = NULL;
167 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500168
169 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400170}
171
Geoff Lang76b10c92014-09-05 16:28:14 -0400172void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400173{
Geoff Lang76b10c92014-09-05 16:28:14 -0400174 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400176 TextureBindingVector &textureVector = bindingVec->second;
177 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400178 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400179 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400180 }
181 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400182 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
183 {
184 mSamplers[samplerIdx].set(NULL);
185 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400186
Shannon Woods53a94a82014-06-24 15:20:36 -0400187 mArrayBuffer.set(NULL);
188 mRenderbuffer.set(NULL);
189
Geoff Lang7dd2e102014-11-10 15:19:26 -0500190 if (mProgram)
191 {
192 mProgram->release();
193 }
194 mProgram = NULL;
195
Shannon Woods53a94a82014-06-24 15:20:36 -0400196 mTransformFeedback.set(NULL);
197
198 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
199 {
200 i->second.set(NULL);
201 }
202
203 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400204 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400205 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400206 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400207 }
208
Shannon Woods53a94a82014-06-24 15:20:36 -0400209 mCopyReadBuffer.set(NULL);
210 mCopyWriteBuffer.set(NULL);
211
212 mPack.pixelBuffer.set(NULL);
213 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500214
215 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400216
217 // TODO(jmadill): Is this necessary?
218 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400219}
220
221const RasterizerState &State::getRasterizerState() const
222{
223 return mRasterizer;
224}
225
226const BlendState &State::getBlendState() const
227{
228 return mBlend;
229}
230
231const DepthStencilState &State::getDepthStencilState() const
232{
233 return mDepthStencil;
234}
235
Jamie Madillf75ab352015-03-16 10:46:52 -0400236void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400237{
238 mColorClearValue.red = red;
239 mColorClearValue.green = green;
240 mColorClearValue.blue = blue;
241 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400242 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400243}
244
Jamie Madillf75ab352015-03-16 10:46:52 -0400245void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400246{
247 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400248 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400249}
250
Jamie Madillf75ab352015-03-16 10:46:52 -0400251void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400252{
253 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400254 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400255}
256
Shannon Woods53a94a82014-06-24 15:20:36 -0400257void State::setColorMask(bool red, bool green, bool blue, bool alpha)
258{
259 mBlend.colorMaskRed = red;
260 mBlend.colorMaskGreen = green;
261 mBlend.colorMaskBlue = blue;
262 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400263 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400264}
265
266void State::setDepthMask(bool mask)
267{
268 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400269 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400270}
271
272bool State::isRasterizerDiscardEnabled() const
273{
274 return mRasterizer.rasterizerDiscard;
275}
276
277void State::setRasterizerDiscard(bool enabled)
278{
279 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400280 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400281}
282
283bool State::isCullFaceEnabled() const
284{
285 return mRasterizer.cullFace;
286}
287
288void State::setCullFace(bool enabled)
289{
290 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400291 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400292}
293
294void State::setCullMode(GLenum mode)
295{
296 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400297 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400298}
299
300void State::setFrontFace(GLenum front)
301{
302 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400303 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400304}
305
306bool State::isDepthTestEnabled() const
307{
308 return mDepthStencil.depthTest;
309}
310
311void State::setDepthTest(bool enabled)
312{
313 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400314 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400315}
316
317void State::setDepthFunc(GLenum depthFunc)
318{
319 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400320 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400321}
322
323void State::setDepthRange(float zNear, float zFar)
324{
325 mNearZ = zNear;
326 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400327 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400328}
329
Geoff Langd42f5b82015-04-16 14:03:29 -0400330float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400331{
Geoff Langd42f5b82015-04-16 14:03:29 -0400332 return mNearZ;
333}
334
335float State::getFarPlane() const
336{
337 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400338}
339
340bool State::isBlendEnabled() const
341{
342 return mBlend.blend;
343}
344
345void State::setBlend(bool enabled)
346{
347 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400348 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400349}
350
351void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
352{
353 mBlend.sourceBlendRGB = sourceRGB;
354 mBlend.destBlendRGB = destRGB;
355 mBlend.sourceBlendAlpha = sourceAlpha;
356 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400357 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400358}
359
360void State::setBlendColor(float red, float green, float blue, float alpha)
361{
362 mBlendColor.red = red;
363 mBlendColor.green = green;
364 mBlendColor.blue = blue;
365 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400366 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400367}
368
369void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
370{
371 mBlend.blendEquationRGB = rgbEquation;
372 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400373 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400374}
375
376const ColorF &State::getBlendColor() const
377{
378 return mBlendColor;
379}
380
381bool State::isStencilTestEnabled() const
382{
383 return mDepthStencil.stencilTest;
384}
385
386void State::setStencilTest(bool enabled)
387{
388 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400389 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400390}
391
392void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
393{
394 mDepthStencil.stencilFunc = stencilFunc;
395 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
396 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400397 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400398}
399
400void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
401{
402 mDepthStencil.stencilBackFunc = stencilBackFunc;
403 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
404 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400405 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400406}
407
408void State::setStencilWritemask(GLuint stencilWritemask)
409{
410 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400411 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400412}
413
414void State::setStencilBackWritemask(GLuint stencilBackWritemask)
415{
416 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400417 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400418}
419
420void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
421{
422 mDepthStencil.stencilFail = stencilFail;
423 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
424 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400425 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400426}
427
428void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
429{
430 mDepthStencil.stencilBackFail = stencilBackFail;
431 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
432 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400433 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400434}
435
436GLint State::getStencilRef() const
437{
438 return mStencilRef;
439}
440
441GLint State::getStencilBackRef() const
442{
443 return mStencilBackRef;
444}
445
446bool State::isPolygonOffsetFillEnabled() const
447{
448 return mRasterizer.polygonOffsetFill;
449}
450
451void State::setPolygonOffsetFill(bool enabled)
452{
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 mRasterizer.polygonOffsetFill = enabled;
454 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400455}
456
457void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
458{
459 // An application can pass NaN values here, so handle this gracefully
460 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
461 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400462 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400463}
464
465bool State::isSampleAlphaToCoverageEnabled() const
466{
467 return mBlend.sampleAlphaToCoverage;
468}
469
470void State::setSampleAlphaToCoverage(bool enabled)
471{
472 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400473 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400474}
475
476bool State::isSampleCoverageEnabled() const
477{
478 return mSampleCoverage;
479}
480
481void State::setSampleCoverage(bool enabled)
482{
483 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400484 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400485}
486
487void State::setSampleCoverageParams(GLclampf value, bool invert)
488{
489 mSampleCoverageValue = value;
490 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400491 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400492}
493
Geoff Lang0fbb6002015-04-16 11:11:53 -0400494GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400495{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400496 return mSampleCoverageValue;
497}
Shannon Woods53a94a82014-06-24 15:20:36 -0400498
Geoff Lang0fbb6002015-04-16 11:11:53 -0400499bool State::getSampleCoverageInvert() const
500{
501 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400502}
503
504bool State::isScissorTestEnabled() const
505{
506 return mScissorTest;
507}
508
509void State::setScissorTest(bool enabled)
510{
511 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400512 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400513}
514
515void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
516{
517 mScissor.x = x;
518 mScissor.y = y;
519 mScissor.width = width;
520 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400521 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400522}
523
524const Rectangle &State::getScissor() const
525{
526 return mScissor;
527}
528
529bool State::isDitherEnabled() const
530{
531 return mBlend.dither;
532}
533
534void State::setDither(bool enabled)
535{
536 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400537 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400538}
539
Jamie Madillb4b53c52015-02-03 15:22:48 -0500540bool State::isPrimitiveRestartEnabled() const
541{
542 return mPrimitiveRestart;
543}
544
545void State::setPrimitiveRestart(bool enabled)
546{
547 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400548 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500549}
550
Shannon Woods53a94a82014-06-24 15:20:36 -0400551void State::setEnableFeature(GLenum feature, bool enabled)
552{
553 switch (feature)
554 {
555 case GL_CULL_FACE: setCullFace(enabled); break;
556 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
557 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
558 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
559 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
560 case GL_STENCIL_TEST: setStencilTest(enabled); break;
561 case GL_DEPTH_TEST: setDepthTest(enabled); break;
562 case GL_BLEND: setBlend(enabled); break;
563 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500564 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400565 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
566 default: UNREACHABLE();
567 }
568}
569
570bool State::getEnableFeature(GLenum feature)
571{
572 switch (feature)
573 {
574 case GL_CULL_FACE: return isCullFaceEnabled();
575 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
576 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
577 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
578 case GL_SCISSOR_TEST: return isScissorTestEnabled();
579 case GL_STENCIL_TEST: return isStencilTestEnabled();
580 case GL_DEPTH_TEST: return isDepthTestEnabled();
581 case GL_BLEND: return isBlendEnabled();
582 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500583 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400584 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
585 default: UNREACHABLE(); return false;
586 }
587}
588
589void State::setLineWidth(GLfloat width)
590{
591 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400592 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400593}
594
Geoff Lang4b3f4162015-04-16 13:22:05 -0400595float State::getLineWidth() const
596{
597 return mLineWidth;
598}
599
Shannon Woods53a94a82014-06-24 15:20:36 -0400600void State::setGenerateMipmapHint(GLenum hint)
601{
602 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400603 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400604}
605
606void State::setFragmentShaderDerivativeHint(GLenum hint)
607{
608 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400609 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400610 // TODO: Propagate the hint to shader translator so we can write
611 // ddx, ddx_coarse, or ddx_fine depending on the hint.
612 // Ignore for now. It is valid for implementations to ignore hint.
613}
614
615void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
616{
617 mViewport.x = x;
618 mViewport.y = y;
619 mViewport.width = width;
620 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400621 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400622}
623
624const Rectangle &State::getViewport() const
625{
626 return mViewport;
627}
628
629void State::setActiveSampler(unsigned int active)
630{
631 mActiveSampler = active;
632}
633
634unsigned int State::getActiveSampler() const
635{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700636 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400637}
638
Geoff Lang76b10c92014-09-05 16:28:14 -0400639void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400640{
Geoff Lang76b10c92014-09-05 16:28:14 -0400641 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400642}
643
Geoff Lang76b10c92014-09-05 16:28:14 -0400644Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400645{
Jamie Madill5864ac22015-01-12 14:43:07 -0500646 const auto it = mSamplerTextures.find(type);
647 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400648 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500649 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400650}
651
Geoff Lang76b10c92014-09-05 16:28:14 -0400652GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400653{
Jamie Madill5864ac22015-01-12 14:43:07 -0500654 const auto it = mSamplerTextures.find(type);
655 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400656 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500657 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400658}
659
Jamie Madille6382c32014-11-07 15:05:26 -0500660void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400661{
662 // Textures have a detach method on State rather than a simple
663 // removeBinding, because the zero/null texture objects are managed
664 // separately, and don't have to go through the Context's maps or
665 // the ResourceManager.
666
667 // [OpenGL ES 2.0.24] section 3.8 page 84:
668 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
669 // rebound to texture object zero
670
Geoff Lang76b10c92014-09-05 16:28:14 -0400671 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400672 {
Jamie Madille6382c32014-11-07 15:05:26 -0500673 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400674 TextureBindingVector &textureVector = bindingVec->second;
675 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400676 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400677 BindingPointer<Texture> &binding = textureVector[textureIdx];
678 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400679 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500680 auto it = zeroTextures.find(textureType);
681 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500682 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500683 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400684 }
685 }
686 }
687
688 // [OpenGL ES 2.0.24] section 4.4 page 112:
689 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
690 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
691 // image was attached in the currently bound framebuffer.
692
693 if (mReadFramebuffer)
694 {
695 mReadFramebuffer->detachTexture(texture);
696 }
697
698 if (mDrawFramebuffer)
699 {
700 mDrawFramebuffer->detachTexture(texture);
701 }
702}
703
Jamie Madille6382c32014-11-07 15:05:26 -0500704void State::initializeZeroTextures(const TextureMap &zeroTextures)
705{
706 for (const auto &zeroTexture : zeroTextures)
707 {
708 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
709
710 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
711 {
712 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
713 }
714 }
715}
716
Shannon Woods53a94a82014-06-24 15:20:36 -0400717void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
718{
719 mSamplers[textureUnit].set(sampler);
720}
721
722GLuint State::getSamplerId(GLuint textureUnit) const
723{
Geoff Lang76b10c92014-09-05 16:28:14 -0400724 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400725 return mSamplers[textureUnit].id();
726}
727
728Sampler *State::getSampler(GLuint textureUnit) const
729{
730 return mSamplers[textureUnit].get();
731}
732
733void State::detachSampler(GLuint sampler)
734{
735 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
736 // If a sampler object that is currently bound to one or more texture units is
737 // deleted, it is as though BindSampler is called once for each texture unit to
738 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400739 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400740 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400741 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
742 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400743 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400744 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400745 }
746 }
747}
748
749void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
750{
751 mRenderbuffer.set(renderbuffer);
752}
753
754GLuint State::getRenderbufferId() const
755{
756 return mRenderbuffer.id();
757}
758
759Renderbuffer *State::getCurrentRenderbuffer()
760{
761 return mRenderbuffer.get();
762}
763
764void State::detachRenderbuffer(GLuint renderbuffer)
765{
766 // [OpenGL ES 2.0.24] section 4.4 page 109:
767 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
768 // had been executed with the target RENDERBUFFER and name of zero.
769
770 if (mRenderbuffer.id() == renderbuffer)
771 {
772 mRenderbuffer.set(NULL);
773 }
774
775 // [OpenGL ES 2.0.24] section 4.4 page 111:
776 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
777 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
778 // point to which this image was attached in the currently bound framebuffer.
779
780 Framebuffer *readFramebuffer = mReadFramebuffer;
781 Framebuffer *drawFramebuffer = mDrawFramebuffer;
782
783 if (readFramebuffer)
784 {
785 readFramebuffer->detachRenderbuffer(renderbuffer);
786 }
787
788 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
789 {
790 drawFramebuffer->detachRenderbuffer(renderbuffer);
791 }
792
793}
794
795void State::setReadFramebufferBinding(Framebuffer *framebuffer)
796{
797 mReadFramebuffer = framebuffer;
798}
799
800void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
801{
802 mDrawFramebuffer = framebuffer;
803}
804
805Framebuffer *State::getTargetFramebuffer(GLenum target) const
806{
807 switch (target)
808 {
809 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
810 case GL_DRAW_FRAMEBUFFER_ANGLE:
811 case GL_FRAMEBUFFER: return mDrawFramebuffer;
812 default: UNREACHABLE(); return NULL;
813 }
814}
815
816Framebuffer *State::getReadFramebuffer()
817{
818 return mReadFramebuffer;
819}
820
821Framebuffer *State::getDrawFramebuffer()
822{
823 return mDrawFramebuffer;
824}
825
826const Framebuffer *State::getReadFramebuffer() const
827{
828 return mReadFramebuffer;
829}
830
831const Framebuffer *State::getDrawFramebuffer() const
832{
833 return mDrawFramebuffer;
834}
835
836bool State::removeReadFramebufferBinding(GLuint framebuffer)
837{
Jamie Madill77a72f62015-04-14 11:18:32 -0400838 if (mReadFramebuffer != nullptr &&
839 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400840 {
841 mReadFramebuffer = NULL;
842 return true;
843 }
844
845 return false;
846}
847
848bool State::removeDrawFramebufferBinding(GLuint framebuffer)
849{
Jamie Madill77a72f62015-04-14 11:18:32 -0400850 if (mReadFramebuffer != nullptr &&
851 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400852 {
853 mDrawFramebuffer = NULL;
854 return true;
855 }
856
857 return false;
858}
859
860void State::setVertexArrayBinding(VertexArray *vertexArray)
861{
862 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000863 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
864 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400865}
866
867GLuint State::getVertexArrayId() const
868{
869 ASSERT(mVertexArray != NULL);
870 return mVertexArray->id();
871}
872
873VertexArray *State::getVertexArray() const
874{
875 ASSERT(mVertexArray != NULL);
876 return mVertexArray;
877}
878
879bool State::removeVertexArrayBinding(GLuint vertexArray)
880{
881 if (mVertexArray->id() == vertexArray)
882 {
883 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000884 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
885 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400886 return true;
887 }
888
889 return false;
890}
891
Geoff Lang7dd2e102014-11-10 15:19:26 -0500892void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400893{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500894 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400895 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500896 if (mProgram)
897 {
898 mProgram->release();
899 }
900
901 mProgram = newProgram;
902
903 if (mProgram)
904 {
905 newProgram->addRef();
906 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400907 }
908}
909
Geoff Lang7dd2e102014-11-10 15:19:26 -0500910Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400911{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500912 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400913}
914
915void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
916{
917 mTransformFeedback.set(transformFeedback);
918}
919
920TransformFeedback *State::getCurrentTransformFeedback() const
921{
922 return mTransformFeedback.get();
923}
924
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000925bool State::isTransformFeedbackActiveUnpaused() const
926{
927 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400928 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000929}
930
Shannon Woods53a94a82014-06-24 15:20:36 -0400931void State::detachTransformFeedback(GLuint transformFeedback)
932{
933 if (mTransformFeedback.id() == transformFeedback)
934 {
935 mTransformFeedback.set(NULL);
936 }
937}
938
939bool State::isQueryActive() const
940{
941 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
942 i != mActiveQueries.end(); i++)
943 {
944 if (i->second.get() != NULL)
945 {
946 return true;
947 }
948 }
949
950 return false;
951}
952
953void State::setActiveQuery(GLenum target, Query *query)
954{
955 mActiveQueries[target].set(query);
956}
957
958GLuint State::getActiveQueryId(GLenum target) const
959{
960 const Query *query = getActiveQuery(target);
961 return (query ? query->id() : 0u);
962}
963
964Query *State::getActiveQuery(GLenum target) const
965{
Jamie Madill5864ac22015-01-12 14:43:07 -0500966 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400967
Jamie Madill5864ac22015-01-12 14:43:07 -0500968 // All query types should already exist in the activeQueries map
969 ASSERT(it != mActiveQueries.end());
970
971 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400972}
973
974void State::setArrayBufferBinding(Buffer *buffer)
975{
976 mArrayBuffer.set(buffer);
977}
978
979GLuint State::getArrayBufferId() const
980{
981 return mArrayBuffer.id();
982}
983
984bool State::removeArrayBufferBinding(GLuint buffer)
985{
986 if (mArrayBuffer.id() == buffer)
987 {
988 mArrayBuffer.set(NULL);
989 return true;
990 }
991
992 return false;
993}
994
995void State::setGenericUniformBufferBinding(Buffer *buffer)
996{
997 mGenericUniformBuffer.set(buffer);
998}
999
1000void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1001{
1002 mUniformBuffers[index].set(buffer, offset, size);
1003}
1004
Geoff Lang5d124a62015-09-15 13:03:27 -04001005const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001006{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001007 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001008 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001009}
1010
Shannon Woods53a94a82014-06-24 15:20:36 -04001011void State::setCopyReadBufferBinding(Buffer *buffer)
1012{
1013 mCopyReadBuffer.set(buffer);
1014}
1015
1016void State::setCopyWriteBufferBinding(Buffer *buffer)
1017{
1018 mCopyWriteBuffer.set(buffer);
1019}
1020
1021void State::setPixelPackBufferBinding(Buffer *buffer)
1022{
1023 mPack.pixelBuffer.set(buffer);
1024}
1025
1026void State::setPixelUnpackBufferBinding(Buffer *buffer)
1027{
1028 mUnpack.pixelBuffer.set(buffer);
1029}
1030
1031Buffer *State::getTargetBuffer(GLenum target) const
1032{
1033 switch (target)
1034 {
1035 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1036 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1037 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001038 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001039 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1040 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001041 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001042 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1043 default: UNREACHABLE(); return NULL;
1044 }
1045}
1046
1047void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1048{
1049 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001050 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001051}
1052
1053void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1054{
Shannon Woods23e05002014-09-22 19:07:27 -04001055 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001056 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001057 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001058}
1059
1060void State::setVertexAttribu(GLuint index, const GLuint values[4])
1061{
Shannon Woods23e05002014-09-22 19:07:27 -04001062 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001063 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001064 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001065}
1066
1067void State::setVertexAttribi(GLuint index, const GLint values[4])
1068{
Shannon Woods23e05002014-09-22 19:07:27 -04001069 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001070 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001071 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001072}
1073
Jamie Madill0b9e9032015-08-17 11:51:52 +00001074void State::setVertexAttribState(unsigned int attribNum,
1075 Buffer *boundBuffer,
1076 GLint size,
1077 GLenum type,
1078 bool normalized,
1079 bool pureInteger,
1080 GLsizei stride,
1081 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001082{
1083 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001084 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
1085}
1086
1087void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1088{
1089 getVertexArray()->setVertexAttribDivisor(index, divisor);
1090 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001091}
1092
Shannon Woods53a94a82014-06-24 15:20:36 -04001093const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1094{
Shannon Woods23e05002014-09-22 19:07:27 -04001095 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001096 return mVertexAttribCurrentValues[attribNum];
1097}
1098
Shannon Woods53a94a82014-06-24 15:20:36 -04001099const void *State::getVertexAttribPointer(unsigned int attribNum) const
1100{
1101 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1102}
1103
1104void State::setPackAlignment(GLint alignment)
1105{
1106 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001107 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001108}
1109
1110GLint State::getPackAlignment() const
1111{
1112 return mPack.alignment;
1113}
1114
1115void State::setPackReverseRowOrder(bool reverseRowOrder)
1116{
1117 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001118 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001119}
1120
1121bool State::getPackReverseRowOrder() const
1122{
1123 return mPack.reverseRowOrder;
1124}
1125
Minmin Gongadff67b2015-10-14 10:34:45 -04001126void State::setPackRowLength(GLint rowLength)
1127{
1128 mPack.rowLength = rowLength;
1129 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1130}
1131
1132GLint State::getPackRowLength() const
1133{
1134 return mPack.rowLength;
1135}
1136
1137void State::setPackSkipRows(GLint skipRows)
1138{
1139 mPack.skipRows = skipRows;
1140 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1141}
1142
1143GLint State::getPackSkipRows() const
1144{
1145 return mPack.skipRows;
1146}
1147
1148void State::setPackSkipPixels(GLint skipPixels)
1149{
1150 mPack.skipPixels = skipPixels;
1151 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1152}
1153
1154GLint State::getPackSkipPixels() const
1155{
1156 return mPack.skipPixels;
1157}
1158
Shannon Woods53a94a82014-06-24 15:20:36 -04001159const PixelPackState &State::getPackState() const
1160{
1161 return mPack;
1162}
1163
Jamie Madill87de3622015-03-16 10:41:44 -04001164PixelPackState &State::getPackState()
1165{
1166 return mPack;
1167}
1168
Shannon Woods53a94a82014-06-24 15:20:36 -04001169void State::setUnpackAlignment(GLint alignment)
1170{
1171 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001172 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001173}
1174
1175GLint State::getUnpackAlignment() const
1176{
1177 return mUnpack.alignment;
1178}
1179
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001180void State::setUnpackRowLength(GLint rowLength)
1181{
1182 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001183 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001184}
1185
1186GLint State::getUnpackRowLength() const
1187{
1188 return mUnpack.rowLength;
1189}
1190
Minmin Gongadff67b2015-10-14 10:34:45 -04001191void State::setUnpackImageHeight(GLint imageHeight)
1192{
1193 mUnpack.imageHeight = imageHeight;
1194 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1195}
1196
1197GLint State::getUnpackImageHeight() const
1198{
1199 return mUnpack.imageHeight;
1200}
1201
1202void State::setUnpackSkipImages(GLint skipImages)
1203{
1204 mUnpack.skipImages = skipImages;
1205 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1206}
1207
1208GLint State::getUnpackSkipImages() const
1209{
1210 return mUnpack.skipImages;
1211}
1212
1213void State::setUnpackSkipRows(GLint skipRows)
1214{
1215 mUnpack.skipRows = skipRows;
1216 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1217}
1218
1219GLint State::getUnpackSkipRows() const
1220{
1221 return mUnpack.skipRows;
1222}
1223
1224void State::setUnpackSkipPixels(GLint skipPixels)
1225{
1226 mUnpack.skipPixels = skipPixels;
1227 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1228}
1229
1230GLint State::getUnpackSkipPixels() const
1231{
1232 return mUnpack.skipPixels;
1233}
1234
Shannon Woods53a94a82014-06-24 15:20:36 -04001235const PixelUnpackState &State::getUnpackState() const
1236{
1237 return mUnpack;
1238}
1239
Jamie Madill67102f02015-03-16 10:41:42 -04001240PixelUnpackState &State::getUnpackState()
1241{
1242 return mUnpack;
1243}
1244
Shannon Woods53a94a82014-06-24 15:20:36 -04001245void State::getBooleanv(GLenum pname, GLboolean *params)
1246{
1247 switch (pname)
1248 {
1249 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1250 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1251 case GL_COLOR_WRITEMASK:
1252 params[0] = mBlend.colorMaskRed;
1253 params[1] = mBlend.colorMaskGreen;
1254 params[2] = mBlend.colorMaskBlue;
1255 params[3] = mBlend.colorMaskAlpha;
1256 break;
1257 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1258 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1259 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1260 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1261 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1262 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1263 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1264 case GL_BLEND: *params = mBlend.blend; break;
1265 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001266 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1267 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001268 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1269 *params = mPrimitiveRestart;
1270 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001271 default:
1272 UNREACHABLE();
1273 break;
1274 }
1275}
1276
1277void State::getFloatv(GLenum pname, GLfloat *params)
1278{
1279 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1280 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1281 // GetIntegerv as its native query function. As it would require conversion in any
1282 // case, this should make no difference to the calling application.
1283 switch (pname)
1284 {
1285 case GL_LINE_WIDTH: *params = mLineWidth; break;
1286 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1287 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1288 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1289 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1290 case GL_DEPTH_RANGE:
1291 params[0] = mNearZ;
1292 params[1] = mFarZ;
1293 break;
1294 case GL_COLOR_CLEAR_VALUE:
1295 params[0] = mColorClearValue.red;
1296 params[1] = mColorClearValue.green;
1297 params[2] = mColorClearValue.blue;
1298 params[3] = mColorClearValue.alpha;
1299 break;
1300 case GL_BLEND_COLOR:
1301 params[0] = mBlendColor.red;
1302 params[1] = mBlendColor.green;
1303 params[2] = mBlendColor.blue;
1304 params[3] = mBlendColor.alpha;
1305 break;
1306 default:
1307 UNREACHABLE();
1308 break;
1309 }
1310}
1311
Jamie Madill48faf802014-11-06 15:27:22 -05001312void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001313{
1314 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1315 {
1316 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001317 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001318 Framebuffer *framebuffer = mDrawFramebuffer;
1319 *params = framebuffer->getDrawBufferState(colorAttachment);
1320 return;
1321 }
1322
1323 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1324 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1325 // GetIntegerv as its native query function. As it would require conversion in any
1326 // case, this should make no difference to the calling application. You may find it in
1327 // State::getFloatv.
1328 switch (pname)
1329 {
1330 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001331 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001332 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1333 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1334 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1335 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1336 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001337 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001338 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1339 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001340 case GL_PACK_ROW_LENGTH:
1341 *params = mPack.rowLength;
1342 break;
1343 case GL_PACK_SKIP_ROWS:
1344 *params = mPack.skipRows;
1345 break;
1346 case GL_PACK_SKIP_PIXELS:
1347 *params = mPack.skipPixels;
1348 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001349 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001350 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001351 case GL_UNPACK_IMAGE_HEIGHT:
1352 *params = mUnpack.imageHeight;
1353 break;
1354 case GL_UNPACK_SKIP_IMAGES:
1355 *params = mUnpack.skipImages;
1356 break;
1357 case GL_UNPACK_SKIP_ROWS:
1358 *params = mUnpack.skipRows;
1359 break;
1360 case GL_UNPACK_SKIP_PIXELS:
1361 *params = mUnpack.skipPixels;
1362 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001363 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1364 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001365 case GL_ACTIVE_TEXTURE:
1366 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1367 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001368 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1369 case GL_STENCIL_REF: *params = mStencilRef; break;
1370 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1371 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1372 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1373 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1374 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1375 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1376 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1377 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1378 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1379 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1380 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1381 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1382 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1383 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1384 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1385 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1386 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1387 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1388 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1389 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001390 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1391 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001392 case GL_SAMPLE_BUFFERS:
1393 case GL_SAMPLES:
1394 {
1395 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001396 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001397 {
1398 switch (pname)
1399 {
1400 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001401 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001402 {
1403 *params = 1;
1404 }
1405 else
1406 {
1407 *params = 0;
1408 }
1409 break;
1410 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001411 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001412 break;
1413 }
1414 }
1415 else
1416 {
1417 *params = 0;
1418 }
1419 }
1420 break;
1421 case GL_VIEWPORT:
1422 params[0] = mViewport.x;
1423 params[1] = mViewport.y;
1424 params[2] = mViewport.width;
1425 params[3] = mViewport.height;
1426 break;
1427 case GL_SCISSOR_BOX:
1428 params[0] = mScissor.x;
1429 params[1] = mScissor.y;
1430 params[2] = mScissor.width;
1431 params[3] = mScissor.height;
1432 break;
1433 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1434 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1435 case GL_RED_BITS:
1436 case GL_GREEN_BITS:
1437 case GL_BLUE_BITS:
1438 case GL_ALPHA_BITS:
1439 {
1440 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001441 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001442
1443 if (colorbuffer)
1444 {
1445 switch (pname)
1446 {
1447 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1448 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1449 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1450 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1451 }
1452 }
1453 else
1454 {
1455 *params = 0;
1456 }
1457 }
1458 break;
1459 case GL_DEPTH_BITS:
1460 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001461 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1462 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001463
1464 if (depthbuffer)
1465 {
1466 *params = depthbuffer->getDepthSize();
1467 }
1468 else
1469 {
1470 *params = 0;
1471 }
1472 }
1473 break;
1474 case GL_STENCIL_BITS:
1475 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001476 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1477 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001478
1479 if (stencilbuffer)
1480 {
1481 *params = stencilbuffer->getStencilSize();
1482 }
1483 else
1484 {
1485 *params = 0;
1486 }
1487 }
1488 break;
1489 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001490 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001491 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001492 break;
1493 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001494 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001495 *params =
1496 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001497 break;
1498 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001499 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001500 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001501 break;
1502 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001503 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001504 *params =
1505 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001506 break;
1507 case GL_UNIFORM_BUFFER_BINDING:
1508 *params = mGenericUniformBuffer.id();
1509 break;
1510 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001511 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001512 break;
1513 case GL_COPY_READ_BUFFER_BINDING:
1514 *params = mCopyReadBuffer.id();
1515 break;
1516 case GL_COPY_WRITE_BUFFER_BINDING:
1517 *params = mCopyWriteBuffer.id();
1518 break;
1519 case GL_PIXEL_PACK_BUFFER_BINDING:
1520 *params = mPack.pixelBuffer.id();
1521 break;
1522 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1523 *params = mUnpack.pixelBuffer.id();
1524 break;
1525 default:
1526 UNREACHABLE();
1527 break;
1528 }
1529}
1530
1531bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1532{
1533 switch (target)
1534 {
1535 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001536 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001537 {
Geoff Lang045536b2015-03-27 15:17:18 -04001538 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001539 }
1540 break;
1541 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001542 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001543 {
1544 *data = mUniformBuffers[index].id();
1545 }
1546 break;
1547 default:
1548 return false;
1549 }
1550
1551 return true;
1552}
1553
1554bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1555{
1556 switch (target)
1557 {
1558 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001559 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001560 {
Geoff Lang045536b2015-03-27 15:17:18 -04001561 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001562 }
1563 break;
1564 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001565 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001566 {
Geoff Lang045536b2015-03-27 15:17:18 -04001567 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001568 }
1569 break;
1570 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001571 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001572 {
1573 *data = mUniformBuffers[index].getOffset();
1574 }
1575 break;
1576 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001577 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001578 {
1579 *data = mUniformBuffers[index].getSize();
1580 }
1581 break;
1582 default:
1583 return false;
1584 }
1585
1586 return true;
1587}
1588
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001589bool State::hasMappedBuffer(GLenum target) const
1590{
1591 if (target == GL_ARRAY_BUFFER)
1592 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001593 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001594 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001595 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001596 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001597 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001598 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001599 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1600 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1601 {
1602 return true;
1603 }
1604 }
1605
1606 return false;
1607 }
1608 else
1609 {
1610 Buffer *buffer = getTargetBuffer(target);
1611 return (buffer && buffer->isMapped());
1612 }
1613}
1614
Shannon Woods53a94a82014-06-24 15:20:36 -04001615}