blob: 1e26f2b25dab6c09742108338a1f14fbc25826ec [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);
Geoff Lang242468f2015-09-24 14:15:41 -040031
Jamie Madill1b94d432015-08-07 13:23:23 -040032 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
33 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Geoff Lang242468f2015-09-24 14:15:41 -040034
Jamie Madill1b94d432015-08-07 13:23:23 -040035 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
36 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
37 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
38 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
39 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
40 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
41 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
42 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
43 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
44 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
45 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang242468f2015-09-24 14:15:41 -040046
47 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
48 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR);
Geoff Lang76b10c92014-09-05 16:28:14 -040049}
50
51State::~State()
52{
53 reset();
54}
55
Jamie Madillc185cb82015-04-28 12:39:08 -040056void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040057{
Shannon Woods2df6a602014-09-26 16:12:07 -040058 mMaxDrawBuffers = caps.maxDrawBuffers;
59 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040060
Jamie Madillf75ab352015-03-16 10:46:52 -040061 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040062
63 mDepthClearValue = 1.0f;
64 mStencilClearValue = 0;
65
66 mRasterizer.rasterizerDiscard = false;
67 mRasterizer.cullFace = false;
68 mRasterizer.cullMode = GL_BACK;
69 mRasterizer.frontFace = GL_CCW;
70 mRasterizer.polygonOffsetFill = false;
71 mRasterizer.polygonOffsetFactor = 0.0f;
72 mRasterizer.polygonOffsetUnits = 0.0f;
73 mRasterizer.pointDrawMode = false;
74 mRasterizer.multiSample = false;
75 mScissorTest = false;
76 mScissor.x = 0;
77 mScissor.y = 0;
78 mScissor.width = 0;
79 mScissor.height = 0;
80
81 mBlend.blend = false;
82 mBlend.sourceBlendRGB = GL_ONE;
83 mBlend.sourceBlendAlpha = GL_ONE;
84 mBlend.destBlendRGB = GL_ZERO;
85 mBlend.destBlendAlpha = GL_ZERO;
86 mBlend.blendEquationRGB = GL_FUNC_ADD;
87 mBlend.blendEquationAlpha = GL_FUNC_ADD;
88 mBlend.sampleAlphaToCoverage = false;
89 mBlend.dither = true;
90
91 mBlendColor.red = 0;
92 mBlendColor.green = 0;
93 mBlendColor.blue = 0;
94 mBlendColor.alpha = 0;
95
96 mDepthStencil.depthTest = false;
97 mDepthStencil.depthFunc = GL_LESS;
98 mDepthStencil.depthMask = true;
99 mDepthStencil.stencilTest = false;
100 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700101 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
102 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400103 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700104 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
105 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400106 mDepthStencil.stencilFail = GL_KEEP;
107 mDepthStencil.stencilPassDepthFail = GL_KEEP;
108 mDepthStencil.stencilPassDepthPass = GL_KEEP;
109 mDepthStencil.stencilBackFail = GL_KEEP;
110 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
111 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
112
113 mStencilRef = 0;
114 mStencilBackRef = 0;
115
116 mSampleCoverage = false;
117 mSampleCoverageValue = 1.0f;
118 mSampleCoverageInvert = false;
119 mGenerateMipmapHint = GL_DONT_CARE;
120 mFragmentShaderDerivativeHint = GL_DONT_CARE;
121
122 mLineWidth = 1.0f;
123
124 mViewport.x = 0;
125 mViewport.y = 0;
126 mViewport.width = 0;
127 mViewport.height = 0;
128 mNearZ = 0.0f;
129 mFarZ = 1.0f;
130
131 mBlend.colorMaskRed = true;
132 mBlend.colorMaskGreen = true;
133 mBlend.colorMaskBlue = true;
134 mBlend.colorMaskAlpha = true;
135
Geoff Lang76b10c92014-09-05 16:28:14 -0400136 mActiveSampler = 0;
137
Shannon Woods23e05002014-09-22 19:07:27 -0400138 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400139
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400140 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
141
Geoff Lang76b10c92014-09-05 16:28:14 -0400142 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
143 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
144 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400145 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400146 // TODO: These could also be enabled via extension
147 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
148 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400149 }
150
Geoff Lang76b10c92014-09-05 16:28:14 -0400151 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400152
153 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
154 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
155 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
156
Geoff Lang7dd2e102014-11-10 15:19:26 -0500157 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400158
159 mReadFramebuffer = NULL;
160 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500161
162 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400163}
164
Geoff Lang76b10c92014-09-05 16:28:14 -0400165void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400166{
Geoff Lang76b10c92014-09-05 16:28:14 -0400167 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400168 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400169 TextureBindingVector &textureVector = bindingVec->second;
170 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400171 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400172 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400173 }
174 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400175 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
176 {
177 mSamplers[samplerIdx].set(NULL);
178 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400179
Shannon Woods53a94a82014-06-24 15:20:36 -0400180 mArrayBuffer.set(NULL);
181 mRenderbuffer.set(NULL);
182
Geoff Lang7dd2e102014-11-10 15:19:26 -0500183 if (mProgram)
184 {
185 mProgram->release();
186 }
187 mProgram = NULL;
188
Shannon Woods53a94a82014-06-24 15:20:36 -0400189 mTransformFeedback.set(NULL);
190
191 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
192 {
193 i->second.set(NULL);
194 }
195
196 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400197 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400198 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400199 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400200 }
201
Shannon Woods53a94a82014-06-24 15:20:36 -0400202 mCopyReadBuffer.set(NULL);
203 mCopyWriteBuffer.set(NULL);
204
205 mPack.pixelBuffer.set(NULL);
206 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500207
208 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400209
210 // TODO(jmadill): Is this necessary?
211 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400212}
213
214const RasterizerState &State::getRasterizerState() const
215{
216 return mRasterizer;
217}
218
219const BlendState &State::getBlendState() const
220{
221 return mBlend;
222}
223
224const DepthStencilState &State::getDepthStencilState() const
225{
226 return mDepthStencil;
227}
228
Jamie Madillf75ab352015-03-16 10:46:52 -0400229void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400230{
231 mColorClearValue.red = red;
232 mColorClearValue.green = green;
233 mColorClearValue.blue = blue;
234 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400235 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400236}
237
Jamie Madillf75ab352015-03-16 10:46:52 -0400238void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400239{
240 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400241 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400242}
243
Jamie Madillf75ab352015-03-16 10:46:52 -0400244void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400245{
246 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400247 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400248}
249
Shannon Woods53a94a82014-06-24 15:20:36 -0400250void State::setColorMask(bool red, bool green, bool blue, bool alpha)
251{
252 mBlend.colorMaskRed = red;
253 mBlend.colorMaskGreen = green;
254 mBlend.colorMaskBlue = blue;
255 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400256 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400257}
258
259void State::setDepthMask(bool mask)
260{
261 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400262 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400263}
264
265bool State::isRasterizerDiscardEnabled() const
266{
267 return mRasterizer.rasterizerDiscard;
268}
269
270void State::setRasterizerDiscard(bool enabled)
271{
272 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400273 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400274}
275
276bool State::isCullFaceEnabled() const
277{
278 return mRasterizer.cullFace;
279}
280
281void State::setCullFace(bool enabled)
282{
283 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400284 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400285}
286
287void State::setCullMode(GLenum mode)
288{
289 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400290 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400291}
292
293void State::setFrontFace(GLenum front)
294{
295 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400296 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400297}
298
299bool State::isDepthTestEnabled() const
300{
301 return mDepthStencil.depthTest;
302}
303
304void State::setDepthTest(bool enabled)
305{
306 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400307 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400308}
309
310void State::setDepthFunc(GLenum depthFunc)
311{
312 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400313 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400314}
315
316void State::setDepthRange(float zNear, float zFar)
317{
318 mNearZ = zNear;
319 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400320 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400321}
322
Geoff Langd42f5b82015-04-16 14:03:29 -0400323float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400324{
Geoff Langd42f5b82015-04-16 14:03:29 -0400325 return mNearZ;
326}
327
328float State::getFarPlane() const
329{
330 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400331}
332
333bool State::isBlendEnabled() const
334{
335 return mBlend.blend;
336}
337
338void State::setBlend(bool enabled)
339{
340 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400341 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400342}
343
344void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
345{
346 mBlend.sourceBlendRGB = sourceRGB;
347 mBlend.destBlendRGB = destRGB;
348 mBlend.sourceBlendAlpha = sourceAlpha;
349 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400350 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400351}
352
353void State::setBlendColor(float red, float green, float blue, float alpha)
354{
355 mBlendColor.red = red;
356 mBlendColor.green = green;
357 mBlendColor.blue = blue;
358 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400359 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400360}
361
362void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
363{
364 mBlend.blendEquationRGB = rgbEquation;
365 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400366 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400367}
368
369const ColorF &State::getBlendColor() const
370{
371 return mBlendColor;
372}
373
374bool State::isStencilTestEnabled() const
375{
376 return mDepthStencil.stencilTest;
377}
378
379void State::setStencilTest(bool enabled)
380{
381 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400382 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400383}
384
385void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
386{
387 mDepthStencil.stencilFunc = stencilFunc;
388 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
389 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400390 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400391}
392
393void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
394{
395 mDepthStencil.stencilBackFunc = stencilBackFunc;
396 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
397 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400398 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400399}
400
401void State::setStencilWritemask(GLuint stencilWritemask)
402{
403 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400404 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400405}
406
407void State::setStencilBackWritemask(GLuint stencilBackWritemask)
408{
409 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400410 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400411}
412
413void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
414{
415 mDepthStencil.stencilFail = stencilFail;
416 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
417 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400418 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400419}
420
421void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
422{
423 mDepthStencil.stencilBackFail = stencilBackFail;
424 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
425 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400426 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400427}
428
429GLint State::getStencilRef() const
430{
431 return mStencilRef;
432}
433
434GLint State::getStencilBackRef() const
435{
436 return mStencilBackRef;
437}
438
439bool State::isPolygonOffsetFillEnabled() const
440{
441 return mRasterizer.polygonOffsetFill;
442}
443
444void State::setPolygonOffsetFill(bool enabled)
445{
Jamie Madill1b94d432015-08-07 13:23:23 -0400446 mRasterizer.polygonOffsetFill = enabled;
447 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400448}
449
450void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
451{
452 // An application can pass NaN values here, so handle this gracefully
453 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
454 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400455 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400456}
457
458bool State::isSampleAlphaToCoverageEnabled() const
459{
460 return mBlend.sampleAlphaToCoverage;
461}
462
463void State::setSampleAlphaToCoverage(bool enabled)
464{
465 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400466 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400467}
468
469bool State::isSampleCoverageEnabled() const
470{
471 return mSampleCoverage;
472}
473
474void State::setSampleCoverage(bool enabled)
475{
476 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400477 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400478}
479
480void State::setSampleCoverageParams(GLclampf value, bool invert)
481{
482 mSampleCoverageValue = value;
483 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400484 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400485}
486
Geoff Lang0fbb6002015-04-16 11:11:53 -0400487GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400488{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400489 return mSampleCoverageValue;
490}
Shannon Woods53a94a82014-06-24 15:20:36 -0400491
Geoff Lang0fbb6002015-04-16 11:11:53 -0400492bool State::getSampleCoverageInvert() const
493{
494 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400495}
496
497bool State::isScissorTestEnabled() const
498{
499 return mScissorTest;
500}
501
502void State::setScissorTest(bool enabled)
503{
504 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400505 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400506}
507
508void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
509{
510 mScissor.x = x;
511 mScissor.y = y;
512 mScissor.width = width;
513 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400514 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400515}
516
517const Rectangle &State::getScissor() const
518{
519 return mScissor;
520}
521
522bool State::isDitherEnabled() const
523{
524 return mBlend.dither;
525}
526
527void State::setDither(bool enabled)
528{
529 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400530 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400531}
532
Jamie Madillb4b53c52015-02-03 15:22:48 -0500533bool State::isPrimitiveRestartEnabled() const
534{
535 return mPrimitiveRestart;
536}
537
538void State::setPrimitiveRestart(bool enabled)
539{
540 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400541 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500542}
543
Shannon Woods53a94a82014-06-24 15:20:36 -0400544void State::setEnableFeature(GLenum feature, bool enabled)
545{
546 switch (feature)
547 {
548 case GL_CULL_FACE: setCullFace(enabled); break;
549 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
550 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
551 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
552 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
553 case GL_STENCIL_TEST: setStencilTest(enabled); break;
554 case GL_DEPTH_TEST: setDepthTest(enabled); break;
555 case GL_BLEND: setBlend(enabled); break;
556 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500557 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400558 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
559 default: UNREACHABLE();
560 }
561}
562
563bool State::getEnableFeature(GLenum feature)
564{
565 switch (feature)
566 {
567 case GL_CULL_FACE: return isCullFaceEnabled();
568 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
569 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
570 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
571 case GL_SCISSOR_TEST: return isScissorTestEnabled();
572 case GL_STENCIL_TEST: return isStencilTestEnabled();
573 case GL_DEPTH_TEST: return isDepthTestEnabled();
574 case GL_BLEND: return isBlendEnabled();
575 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500576 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400577 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
578 default: UNREACHABLE(); return false;
579 }
580}
581
582void State::setLineWidth(GLfloat width)
583{
584 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400585 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400586}
587
Geoff Lang4b3f4162015-04-16 13:22:05 -0400588float State::getLineWidth() const
589{
590 return mLineWidth;
591}
592
Shannon Woods53a94a82014-06-24 15:20:36 -0400593void State::setGenerateMipmapHint(GLenum hint)
594{
595 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400596 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400597}
598
599void State::setFragmentShaderDerivativeHint(GLenum hint)
600{
601 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400602 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400603 // TODO: Propagate the hint to shader translator so we can write
604 // ddx, ddx_coarse, or ddx_fine depending on the hint.
605 // Ignore for now. It is valid for implementations to ignore hint.
606}
607
608void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
609{
610 mViewport.x = x;
611 mViewport.y = y;
612 mViewport.width = width;
613 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400614 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400615}
616
617const Rectangle &State::getViewport() const
618{
619 return mViewport;
620}
621
622void State::setActiveSampler(unsigned int active)
623{
624 mActiveSampler = active;
625}
626
627unsigned int State::getActiveSampler() const
628{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700629 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400630}
631
Geoff Lang76b10c92014-09-05 16:28:14 -0400632void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400633{
Geoff Lang76b10c92014-09-05 16:28:14 -0400634 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400635}
636
Geoff Lang76b10c92014-09-05 16:28:14 -0400637Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400638{
Jamie Madill5864ac22015-01-12 14:43:07 -0500639 const auto it = mSamplerTextures.find(type);
640 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400641 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500642 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400643}
644
Geoff Lang76b10c92014-09-05 16:28:14 -0400645GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400646{
Jamie Madill5864ac22015-01-12 14:43:07 -0500647 const auto it = mSamplerTextures.find(type);
648 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400649 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500650 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400651}
652
Jamie Madille6382c32014-11-07 15:05:26 -0500653void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400654{
655 // Textures have a detach method on State rather than a simple
656 // removeBinding, because the zero/null texture objects are managed
657 // separately, and don't have to go through the Context's maps or
658 // the ResourceManager.
659
660 // [OpenGL ES 2.0.24] section 3.8 page 84:
661 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
662 // rebound to texture object zero
663
Geoff Lang76b10c92014-09-05 16:28:14 -0400664 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400665 {
Jamie Madille6382c32014-11-07 15:05:26 -0500666 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400667 TextureBindingVector &textureVector = bindingVec->second;
668 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400669 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400670 BindingPointer<Texture> &binding = textureVector[textureIdx];
671 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400672 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500673 auto it = zeroTextures.find(textureType);
674 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500675 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500676 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400677 }
678 }
679 }
680
681 // [OpenGL ES 2.0.24] section 4.4 page 112:
682 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
683 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
684 // image was attached in the currently bound framebuffer.
685
686 if (mReadFramebuffer)
687 {
688 mReadFramebuffer->detachTexture(texture);
689 }
690
691 if (mDrawFramebuffer)
692 {
693 mDrawFramebuffer->detachTexture(texture);
694 }
695}
696
Jamie Madille6382c32014-11-07 15:05:26 -0500697void State::initializeZeroTextures(const TextureMap &zeroTextures)
698{
699 for (const auto &zeroTexture : zeroTextures)
700 {
701 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
702
703 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
704 {
705 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
706 }
707 }
708}
709
Shannon Woods53a94a82014-06-24 15:20:36 -0400710void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
711{
712 mSamplers[textureUnit].set(sampler);
713}
714
715GLuint State::getSamplerId(GLuint textureUnit) const
716{
Geoff Lang76b10c92014-09-05 16:28:14 -0400717 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400718 return mSamplers[textureUnit].id();
719}
720
721Sampler *State::getSampler(GLuint textureUnit) const
722{
723 return mSamplers[textureUnit].get();
724}
725
726void State::detachSampler(GLuint sampler)
727{
728 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
729 // If a sampler object that is currently bound to one or more texture units is
730 // deleted, it is as though BindSampler is called once for each texture unit to
731 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400732 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400733 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400734 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
735 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400736 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400737 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400738 }
739 }
740}
741
742void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
743{
744 mRenderbuffer.set(renderbuffer);
745}
746
747GLuint State::getRenderbufferId() const
748{
749 return mRenderbuffer.id();
750}
751
752Renderbuffer *State::getCurrentRenderbuffer()
753{
754 return mRenderbuffer.get();
755}
756
757void State::detachRenderbuffer(GLuint renderbuffer)
758{
759 // [OpenGL ES 2.0.24] section 4.4 page 109:
760 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
761 // had been executed with the target RENDERBUFFER and name of zero.
762
763 if (mRenderbuffer.id() == renderbuffer)
764 {
765 mRenderbuffer.set(NULL);
766 }
767
768 // [OpenGL ES 2.0.24] section 4.4 page 111:
769 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
770 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
771 // point to which this image was attached in the currently bound framebuffer.
772
773 Framebuffer *readFramebuffer = mReadFramebuffer;
774 Framebuffer *drawFramebuffer = mDrawFramebuffer;
775
776 if (readFramebuffer)
777 {
778 readFramebuffer->detachRenderbuffer(renderbuffer);
779 }
780
781 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
782 {
783 drawFramebuffer->detachRenderbuffer(renderbuffer);
784 }
785
786}
787
788void State::setReadFramebufferBinding(Framebuffer *framebuffer)
789{
790 mReadFramebuffer = framebuffer;
791}
792
793void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
794{
795 mDrawFramebuffer = framebuffer;
796}
797
798Framebuffer *State::getTargetFramebuffer(GLenum target) const
799{
800 switch (target)
801 {
802 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
803 case GL_DRAW_FRAMEBUFFER_ANGLE:
804 case GL_FRAMEBUFFER: return mDrawFramebuffer;
805 default: UNREACHABLE(); return NULL;
806 }
807}
808
809Framebuffer *State::getReadFramebuffer()
810{
811 return mReadFramebuffer;
812}
813
814Framebuffer *State::getDrawFramebuffer()
815{
816 return mDrawFramebuffer;
817}
818
819const Framebuffer *State::getReadFramebuffer() const
820{
821 return mReadFramebuffer;
822}
823
824const Framebuffer *State::getDrawFramebuffer() const
825{
826 return mDrawFramebuffer;
827}
828
829bool State::removeReadFramebufferBinding(GLuint framebuffer)
830{
Jamie Madill77a72f62015-04-14 11:18:32 -0400831 if (mReadFramebuffer != nullptr &&
832 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400833 {
834 mReadFramebuffer = NULL;
835 return true;
836 }
837
838 return false;
839}
840
841bool State::removeDrawFramebufferBinding(GLuint framebuffer)
842{
Jamie Madill77a72f62015-04-14 11:18:32 -0400843 if (mReadFramebuffer != nullptr &&
844 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400845 {
846 mDrawFramebuffer = NULL;
847 return true;
848 }
849
850 return false;
851}
852
853void State::setVertexArrayBinding(VertexArray *vertexArray)
854{
855 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000856 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
857 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400858}
859
860GLuint State::getVertexArrayId() const
861{
862 ASSERT(mVertexArray != NULL);
863 return mVertexArray->id();
864}
865
866VertexArray *State::getVertexArray() const
867{
868 ASSERT(mVertexArray != NULL);
869 return mVertexArray;
870}
871
872bool State::removeVertexArrayBinding(GLuint vertexArray)
873{
874 if (mVertexArray->id() == vertexArray)
875 {
876 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000877 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
878 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400879 return true;
880 }
881
882 return false;
883}
884
Geoff Lang7dd2e102014-11-10 15:19:26 -0500885void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400886{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500887 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400888 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500889 if (mProgram)
890 {
891 mProgram->release();
892 }
893
894 mProgram = newProgram;
895
896 if (mProgram)
897 {
898 newProgram->addRef();
899 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400900 }
901}
902
Geoff Lang7dd2e102014-11-10 15:19:26 -0500903Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400904{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500905 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400906}
907
908void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
909{
910 mTransformFeedback.set(transformFeedback);
911}
912
913TransformFeedback *State::getCurrentTransformFeedback() const
914{
915 return mTransformFeedback.get();
916}
917
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000918bool State::isTransformFeedbackActiveUnpaused() const
919{
920 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400921 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000922}
923
Shannon Woods53a94a82014-06-24 15:20:36 -0400924void State::detachTransformFeedback(GLuint transformFeedback)
925{
926 if (mTransformFeedback.id() == transformFeedback)
927 {
928 mTransformFeedback.set(NULL);
929 }
930}
931
932bool State::isQueryActive() const
933{
934 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
935 i != mActiveQueries.end(); i++)
936 {
937 if (i->second.get() != NULL)
938 {
939 return true;
940 }
941 }
942
943 return false;
944}
945
946void State::setActiveQuery(GLenum target, Query *query)
947{
948 mActiveQueries[target].set(query);
949}
950
951GLuint State::getActiveQueryId(GLenum target) const
952{
953 const Query *query = getActiveQuery(target);
954 return (query ? query->id() : 0u);
955}
956
957Query *State::getActiveQuery(GLenum target) const
958{
Jamie Madill5864ac22015-01-12 14:43:07 -0500959 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400960
Jamie Madill5864ac22015-01-12 14:43:07 -0500961 // All query types should already exist in the activeQueries map
962 ASSERT(it != mActiveQueries.end());
963
964 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400965}
966
967void State::setArrayBufferBinding(Buffer *buffer)
968{
969 mArrayBuffer.set(buffer);
970}
971
972GLuint State::getArrayBufferId() const
973{
974 return mArrayBuffer.id();
975}
976
977bool State::removeArrayBufferBinding(GLuint buffer)
978{
979 if (mArrayBuffer.id() == buffer)
980 {
981 mArrayBuffer.set(NULL);
982 return true;
983 }
984
985 return false;
986}
987
988void State::setGenericUniformBufferBinding(Buffer *buffer)
989{
990 mGenericUniformBuffer.set(buffer);
991}
992
993void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
994{
995 mUniformBuffers[index].set(buffer, offset, size);
996}
997
998GLuint State::getIndexedUniformBufferId(GLuint index) const
999{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001000 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001001
1002 return mUniformBuffers[index].id();
1003}
1004
1005Buffer *State::getIndexedUniformBuffer(GLuint index) const
1006{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001007 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001008
1009 return mUniformBuffers[index].get();
1010}
1011
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001012GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
1013{
1014 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1015
1016 return mUniformBuffers[index].getOffset();
1017}
1018
1019GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
1020{
1021 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1022
1023 return mUniformBuffers[index].getSize();
1024}
1025
Shannon Woods53a94a82014-06-24 15:20:36 -04001026void State::setCopyReadBufferBinding(Buffer *buffer)
1027{
1028 mCopyReadBuffer.set(buffer);
1029}
1030
1031void State::setCopyWriteBufferBinding(Buffer *buffer)
1032{
1033 mCopyWriteBuffer.set(buffer);
1034}
1035
1036void State::setPixelPackBufferBinding(Buffer *buffer)
1037{
1038 mPack.pixelBuffer.set(buffer);
1039}
1040
1041void State::setPixelUnpackBufferBinding(Buffer *buffer)
1042{
1043 mUnpack.pixelBuffer.set(buffer);
1044}
1045
1046Buffer *State::getTargetBuffer(GLenum target) const
1047{
1048 switch (target)
1049 {
1050 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1051 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1052 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001053 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001054 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1055 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001056 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001057 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1058 default: UNREACHABLE(); return NULL;
1059 }
1060}
1061
1062void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1063{
1064 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001065 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001066}
1067
1068void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1069{
Shannon Woods23e05002014-09-22 19:07:27 -04001070 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001071 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001072 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001073}
1074
1075void State::setVertexAttribu(GLuint index, const GLuint values[4])
1076{
Shannon Woods23e05002014-09-22 19:07:27 -04001077 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001078 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001079 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001080}
1081
1082void State::setVertexAttribi(GLuint index, const GLint values[4])
1083{
Shannon Woods23e05002014-09-22 19:07:27 -04001084 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001085 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001086 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001087}
1088
Jamie Madill0b9e9032015-08-17 11:51:52 +00001089void State::setVertexAttribState(unsigned int attribNum,
1090 Buffer *boundBuffer,
1091 GLint size,
1092 GLenum type,
1093 bool normalized,
1094 bool pureInteger,
1095 GLsizei stride,
1096 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001097{
1098 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001099 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
1100}
1101
1102void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1103{
1104 getVertexArray()->setVertexAttribDivisor(index, divisor);
1105 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001106}
1107
Shannon Woods53a94a82014-06-24 15:20:36 -04001108const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1109{
Shannon Woods23e05002014-09-22 19:07:27 -04001110 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001111 return mVertexAttribCurrentValues[attribNum];
1112}
1113
Shannon Woods53a94a82014-06-24 15:20:36 -04001114const void *State::getVertexAttribPointer(unsigned int attribNum) const
1115{
1116 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1117}
1118
1119void State::setPackAlignment(GLint alignment)
1120{
1121 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001122 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001123}
1124
1125GLint State::getPackAlignment() const
1126{
1127 return mPack.alignment;
1128}
1129
1130void State::setPackReverseRowOrder(bool reverseRowOrder)
1131{
1132 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001133 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001134}
1135
1136bool State::getPackReverseRowOrder() const
1137{
1138 return mPack.reverseRowOrder;
1139}
1140
1141const PixelPackState &State::getPackState() const
1142{
1143 return mPack;
1144}
1145
Jamie Madill87de3622015-03-16 10:41:44 -04001146PixelPackState &State::getPackState()
1147{
1148 return mPack;
1149}
1150
Shannon Woods53a94a82014-06-24 15:20:36 -04001151void State::setUnpackAlignment(GLint alignment)
1152{
1153 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001154 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001155}
1156
1157GLint State::getUnpackAlignment() const
1158{
1159 return mUnpack.alignment;
1160}
1161
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001162void State::setUnpackRowLength(GLint rowLength)
1163{
1164 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001165 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001166}
1167
1168GLint State::getUnpackRowLength() const
1169{
1170 return mUnpack.rowLength;
1171}
1172
Shannon Woods53a94a82014-06-24 15:20:36 -04001173const PixelUnpackState &State::getUnpackState() const
1174{
1175 return mUnpack;
1176}
1177
Jamie Madill67102f02015-03-16 10:41:42 -04001178PixelUnpackState &State::getUnpackState()
1179{
1180 return mUnpack;
1181}
1182
Shannon Woods53a94a82014-06-24 15:20:36 -04001183void State::getBooleanv(GLenum pname, GLboolean *params)
1184{
1185 switch (pname)
1186 {
1187 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1188 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1189 case GL_COLOR_WRITEMASK:
1190 params[0] = mBlend.colorMaskRed;
1191 params[1] = mBlend.colorMaskGreen;
1192 params[2] = mBlend.colorMaskBlue;
1193 params[3] = mBlend.colorMaskAlpha;
1194 break;
1195 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1196 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1197 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1198 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1199 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1200 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1201 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1202 case GL_BLEND: *params = mBlend.blend; break;
1203 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001204 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1205 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001206 default:
1207 UNREACHABLE();
1208 break;
1209 }
1210}
1211
1212void State::getFloatv(GLenum pname, GLfloat *params)
1213{
1214 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1215 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1216 // GetIntegerv as its native query function. As it would require conversion in any
1217 // case, this should make no difference to the calling application.
1218 switch (pname)
1219 {
1220 case GL_LINE_WIDTH: *params = mLineWidth; break;
1221 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1222 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1223 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1224 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1225 case GL_DEPTH_RANGE:
1226 params[0] = mNearZ;
1227 params[1] = mFarZ;
1228 break;
1229 case GL_COLOR_CLEAR_VALUE:
1230 params[0] = mColorClearValue.red;
1231 params[1] = mColorClearValue.green;
1232 params[2] = mColorClearValue.blue;
1233 params[3] = mColorClearValue.alpha;
1234 break;
1235 case GL_BLEND_COLOR:
1236 params[0] = mBlendColor.red;
1237 params[1] = mBlendColor.green;
1238 params[2] = mBlendColor.blue;
1239 params[3] = mBlendColor.alpha;
1240 break;
1241 default:
1242 UNREACHABLE();
1243 break;
1244 }
1245}
1246
Jamie Madill48faf802014-11-06 15:27:22 -05001247void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001248{
1249 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1250 {
1251 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001252 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001253 Framebuffer *framebuffer = mDrawFramebuffer;
1254 *params = framebuffer->getDrawBufferState(colorAttachment);
1255 return;
1256 }
1257
1258 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1259 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1260 // GetIntegerv as its native query function. As it would require conversion in any
1261 // case, this should make no difference to the calling application. You may find it in
1262 // State::getFloatv.
1263 switch (pname)
1264 {
1265 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001266 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001267 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1268 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1269 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1270 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1271 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001272 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001273 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1274 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1275 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001276 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001277 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1278 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001279 case GL_ACTIVE_TEXTURE:
1280 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1281 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001282 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1283 case GL_STENCIL_REF: *params = mStencilRef; break;
1284 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1285 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1286 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1287 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1288 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1289 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1290 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1291 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1292 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1293 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1294 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1295 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1296 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1297 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1298 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1299 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1300 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1301 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1302 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1303 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001304 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1305 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001306 case GL_SAMPLE_BUFFERS:
1307 case GL_SAMPLES:
1308 {
1309 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001310 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001311 {
1312 switch (pname)
1313 {
1314 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001315 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001316 {
1317 *params = 1;
1318 }
1319 else
1320 {
1321 *params = 0;
1322 }
1323 break;
1324 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001325 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001326 break;
1327 }
1328 }
1329 else
1330 {
1331 *params = 0;
1332 }
1333 }
1334 break;
1335 case GL_VIEWPORT:
1336 params[0] = mViewport.x;
1337 params[1] = mViewport.y;
1338 params[2] = mViewport.width;
1339 params[3] = mViewport.height;
1340 break;
1341 case GL_SCISSOR_BOX:
1342 params[0] = mScissor.x;
1343 params[1] = mScissor.y;
1344 params[2] = mScissor.width;
1345 params[3] = mScissor.height;
1346 break;
1347 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1348 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1349 case GL_RED_BITS:
1350 case GL_GREEN_BITS:
1351 case GL_BLUE_BITS:
1352 case GL_ALPHA_BITS:
1353 {
1354 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001355 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001356
1357 if (colorbuffer)
1358 {
1359 switch (pname)
1360 {
1361 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1362 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1363 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1364 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1365 }
1366 }
1367 else
1368 {
1369 *params = 0;
1370 }
1371 }
1372 break;
1373 case GL_DEPTH_BITS:
1374 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001375 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1376 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001377
1378 if (depthbuffer)
1379 {
1380 *params = depthbuffer->getDepthSize();
1381 }
1382 else
1383 {
1384 *params = 0;
1385 }
1386 }
1387 break;
1388 case GL_STENCIL_BITS:
1389 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001390 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1391 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001392
1393 if (stencilbuffer)
1394 {
1395 *params = stencilbuffer->getStencilSize();
1396 }
1397 else
1398 {
1399 *params = 0;
1400 }
1401 }
1402 break;
1403 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001404 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001405 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001406 break;
1407 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001408 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001409 *params =
1410 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001411 break;
1412 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001413 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001414 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 break;
1416 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001417 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001418 *params =
1419 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001420 break;
1421 case GL_UNIFORM_BUFFER_BINDING:
1422 *params = mGenericUniformBuffer.id();
1423 break;
1424 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001425 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001426 break;
1427 case GL_COPY_READ_BUFFER_BINDING:
1428 *params = mCopyReadBuffer.id();
1429 break;
1430 case GL_COPY_WRITE_BUFFER_BINDING:
1431 *params = mCopyWriteBuffer.id();
1432 break;
1433 case GL_PIXEL_PACK_BUFFER_BINDING:
1434 *params = mPack.pixelBuffer.id();
1435 break;
1436 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1437 *params = mUnpack.pixelBuffer.id();
1438 break;
1439 default:
1440 UNREACHABLE();
1441 break;
1442 }
1443}
1444
1445bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1446{
1447 switch (target)
1448 {
1449 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001450 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001451 {
Geoff Lang045536b2015-03-27 15:17:18 -04001452 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001453 }
1454 break;
1455 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001456 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001457 {
1458 *data = mUniformBuffers[index].id();
1459 }
1460 break;
1461 default:
1462 return false;
1463 }
1464
1465 return true;
1466}
1467
1468bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1469{
1470 switch (target)
1471 {
1472 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001473 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001474 {
Geoff Lang045536b2015-03-27 15:17:18 -04001475 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001476 }
1477 break;
1478 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001479 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001480 {
Geoff Lang045536b2015-03-27 15:17:18 -04001481 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001482 }
1483 break;
1484 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001485 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001486 {
1487 *data = mUniformBuffers[index].getOffset();
1488 }
1489 break;
1490 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001491 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001492 {
1493 *data = mUniformBuffers[index].getSize();
1494 }
1495 break;
1496 default:
1497 return false;
1498 }
1499
1500 return true;
1501}
1502
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001503bool State::hasMappedBuffer(GLenum target) const
1504{
1505 if (target == GL_ARRAY_BUFFER)
1506 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001507 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001508 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001509 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001510 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001511 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001512 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001513 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1514 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1515 {
1516 return true;
1517 }
1518 }
1519
1520 return false;
1521 }
1522 else
1523 {
1524 Buffer *buffer = getTargetBuffer(target);
1525 return (buffer && buffer->isMapped());
1526 }
1527}
1528
Shannon Woods53a94a82014-06-24 15:20:36 -04001529}