blob: d51015a2b76961505eefa67cd781b21441d58519 [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);
31 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
32 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
33 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
34 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
35 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
36 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
37 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
38 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
39 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
40 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
41 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
42 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
43 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang76b10c92014-09-05 16:28:14 -040044}
45
46State::~State()
47{
48 reset();
49}
50
Jamie Madillc185cb82015-04-28 12:39:08 -040051void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040052{
Shannon Woods2df6a602014-09-26 16:12:07 -040053 mMaxDrawBuffers = caps.maxDrawBuffers;
54 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040055
Jamie Madillf75ab352015-03-16 10:46:52 -040056 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040057
58 mDepthClearValue = 1.0f;
59 mStencilClearValue = 0;
60
61 mRasterizer.rasterizerDiscard = false;
62 mRasterizer.cullFace = false;
63 mRasterizer.cullMode = GL_BACK;
64 mRasterizer.frontFace = GL_CCW;
65 mRasterizer.polygonOffsetFill = false;
66 mRasterizer.polygonOffsetFactor = 0.0f;
67 mRasterizer.polygonOffsetUnits = 0.0f;
68 mRasterizer.pointDrawMode = false;
69 mRasterizer.multiSample = false;
70 mScissorTest = false;
71 mScissor.x = 0;
72 mScissor.y = 0;
73 mScissor.width = 0;
74 mScissor.height = 0;
75
76 mBlend.blend = false;
77 mBlend.sourceBlendRGB = GL_ONE;
78 mBlend.sourceBlendAlpha = GL_ONE;
79 mBlend.destBlendRGB = GL_ZERO;
80 mBlend.destBlendAlpha = GL_ZERO;
81 mBlend.blendEquationRGB = GL_FUNC_ADD;
82 mBlend.blendEquationAlpha = GL_FUNC_ADD;
83 mBlend.sampleAlphaToCoverage = false;
84 mBlend.dither = true;
85
86 mBlendColor.red = 0;
87 mBlendColor.green = 0;
88 mBlendColor.blue = 0;
89 mBlendColor.alpha = 0;
90
91 mDepthStencil.depthTest = false;
92 mDepthStencil.depthFunc = GL_LESS;
93 mDepthStencil.depthMask = true;
94 mDepthStencil.stencilTest = false;
95 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070096 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
97 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040098 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070099 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
100 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400101 mDepthStencil.stencilFail = GL_KEEP;
102 mDepthStencil.stencilPassDepthFail = GL_KEEP;
103 mDepthStencil.stencilPassDepthPass = GL_KEEP;
104 mDepthStencil.stencilBackFail = GL_KEEP;
105 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
106 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
107
108 mStencilRef = 0;
109 mStencilBackRef = 0;
110
111 mSampleCoverage = false;
112 mSampleCoverageValue = 1.0f;
113 mSampleCoverageInvert = false;
114 mGenerateMipmapHint = GL_DONT_CARE;
115 mFragmentShaderDerivativeHint = GL_DONT_CARE;
116
117 mLineWidth = 1.0f;
118
119 mViewport.x = 0;
120 mViewport.y = 0;
121 mViewport.width = 0;
122 mViewport.height = 0;
123 mNearZ = 0.0f;
124 mFarZ = 1.0f;
125
126 mBlend.colorMaskRed = true;
127 mBlend.colorMaskGreen = true;
128 mBlend.colorMaskBlue = true;
129 mBlend.colorMaskAlpha = true;
130
Geoff Lang76b10c92014-09-05 16:28:14 -0400131 mActiveSampler = 0;
132
Shannon Woods23e05002014-09-22 19:07:27 -0400133 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400134
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400135 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
136
Geoff Lang76b10c92014-09-05 16:28:14 -0400137 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
138 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
139 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400140 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400141 // TODO: These could also be enabled via extension
142 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
143 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400144 }
145
Geoff Lang76b10c92014-09-05 16:28:14 -0400146 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400147
148 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
149 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
150 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
151
Geoff Lang7dd2e102014-11-10 15:19:26 -0500152 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400153
154 mReadFramebuffer = NULL;
155 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500156
157 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400158}
159
Geoff Lang76b10c92014-09-05 16:28:14 -0400160void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400161{
Geoff Lang76b10c92014-09-05 16:28:14 -0400162 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400163 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400164 TextureBindingVector &textureVector = bindingVec->second;
165 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400166 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400167 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400168 }
169 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400170 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
171 {
172 mSamplers[samplerIdx].set(NULL);
173 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400174
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 mArrayBuffer.set(NULL);
176 mRenderbuffer.set(NULL);
177
Geoff Lang7dd2e102014-11-10 15:19:26 -0500178 if (mProgram)
179 {
180 mProgram->release();
181 }
182 mProgram = NULL;
183
Shannon Woods53a94a82014-06-24 15:20:36 -0400184 mTransformFeedback.set(NULL);
185
186 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
187 {
188 i->second.set(NULL);
189 }
190
191 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400192 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400193 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400194 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400195 }
196
Shannon Woods53a94a82014-06-24 15:20:36 -0400197 mCopyReadBuffer.set(NULL);
198 mCopyWriteBuffer.set(NULL);
199
200 mPack.pixelBuffer.set(NULL);
201 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500202
203 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400204
205 // TODO(jmadill): Is this necessary?
206 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400207}
208
209const RasterizerState &State::getRasterizerState() const
210{
211 return mRasterizer;
212}
213
214const BlendState &State::getBlendState() const
215{
216 return mBlend;
217}
218
219const DepthStencilState &State::getDepthStencilState() const
220{
221 return mDepthStencil;
222}
223
Jamie Madillf75ab352015-03-16 10:46:52 -0400224void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400225{
226 mColorClearValue.red = red;
227 mColorClearValue.green = green;
228 mColorClearValue.blue = blue;
229 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400230 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400231}
232
Jamie Madillf75ab352015-03-16 10:46:52 -0400233void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400234{
235 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400236 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400237}
238
Jamie Madillf75ab352015-03-16 10:46:52 -0400239void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400240{
241 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400242 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400243}
244
Shannon Woods53a94a82014-06-24 15:20:36 -0400245void State::setColorMask(bool red, bool green, bool blue, bool alpha)
246{
247 mBlend.colorMaskRed = red;
248 mBlend.colorMaskGreen = green;
249 mBlend.colorMaskBlue = blue;
250 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400251 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400252}
253
254void State::setDepthMask(bool mask)
255{
256 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400257 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400258}
259
260bool State::isRasterizerDiscardEnabled() const
261{
262 return mRasterizer.rasterizerDiscard;
263}
264
265void State::setRasterizerDiscard(bool enabled)
266{
267 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400268 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400269}
270
271bool State::isCullFaceEnabled() const
272{
273 return mRasterizer.cullFace;
274}
275
276void State::setCullFace(bool enabled)
277{
278 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400279 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400280}
281
282void State::setCullMode(GLenum mode)
283{
284 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400285 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400286}
287
288void State::setFrontFace(GLenum front)
289{
290 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400291 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400292}
293
294bool State::isDepthTestEnabled() const
295{
296 return mDepthStencil.depthTest;
297}
298
299void State::setDepthTest(bool enabled)
300{
301 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400302 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400303}
304
305void State::setDepthFunc(GLenum depthFunc)
306{
307 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400308 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400309}
310
311void State::setDepthRange(float zNear, float zFar)
312{
313 mNearZ = zNear;
314 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400315 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400316}
317
Geoff Langd42f5b82015-04-16 14:03:29 -0400318float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400319{
Geoff Langd42f5b82015-04-16 14:03:29 -0400320 return mNearZ;
321}
322
323float State::getFarPlane() const
324{
325 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400326}
327
328bool State::isBlendEnabled() const
329{
330 return mBlend.blend;
331}
332
333void State::setBlend(bool enabled)
334{
335 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400336 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400337}
338
339void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
340{
341 mBlend.sourceBlendRGB = sourceRGB;
342 mBlend.destBlendRGB = destRGB;
343 mBlend.sourceBlendAlpha = sourceAlpha;
344 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400345 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400346}
347
348void State::setBlendColor(float red, float green, float blue, float alpha)
349{
350 mBlendColor.red = red;
351 mBlendColor.green = green;
352 mBlendColor.blue = blue;
353 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400354 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400355}
356
357void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
358{
359 mBlend.blendEquationRGB = rgbEquation;
360 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400361 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400362}
363
364const ColorF &State::getBlendColor() const
365{
366 return mBlendColor;
367}
368
369bool State::isStencilTestEnabled() const
370{
371 return mDepthStencil.stencilTest;
372}
373
374void State::setStencilTest(bool enabled)
375{
376 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400377 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400378}
379
380void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
381{
382 mDepthStencil.stencilFunc = stencilFunc;
383 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
384 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400385 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400386}
387
388void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
389{
390 mDepthStencil.stencilBackFunc = stencilBackFunc;
391 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
392 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400393 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400394}
395
396void State::setStencilWritemask(GLuint stencilWritemask)
397{
398 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400399 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400400}
401
402void State::setStencilBackWritemask(GLuint stencilBackWritemask)
403{
404 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400405 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400406}
407
408void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
409{
410 mDepthStencil.stencilFail = stencilFail;
411 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
412 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400413 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400414}
415
416void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
417{
418 mDepthStencil.stencilBackFail = stencilBackFail;
419 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
420 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400421 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400422}
423
424GLint State::getStencilRef() const
425{
426 return mStencilRef;
427}
428
429GLint State::getStencilBackRef() const
430{
431 return mStencilBackRef;
432}
433
434bool State::isPolygonOffsetFillEnabled() const
435{
436 return mRasterizer.polygonOffsetFill;
437}
438
439void State::setPolygonOffsetFill(bool enabled)
440{
Jamie Madill1b94d432015-08-07 13:23:23 -0400441 mRasterizer.polygonOffsetFill = enabled;
442 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400443}
444
445void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
446{
447 // An application can pass NaN values here, so handle this gracefully
448 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
449 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400450 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400451}
452
453bool State::isSampleAlphaToCoverageEnabled() const
454{
455 return mBlend.sampleAlphaToCoverage;
456}
457
458void State::setSampleAlphaToCoverage(bool enabled)
459{
460 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400461 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400462}
463
464bool State::isSampleCoverageEnabled() const
465{
466 return mSampleCoverage;
467}
468
469void State::setSampleCoverage(bool enabled)
470{
471 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400472 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400473}
474
475void State::setSampleCoverageParams(GLclampf value, bool invert)
476{
477 mSampleCoverageValue = value;
478 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400479 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400480}
481
Geoff Lang0fbb6002015-04-16 11:11:53 -0400482GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400483{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400484 return mSampleCoverageValue;
485}
Shannon Woods53a94a82014-06-24 15:20:36 -0400486
Geoff Lang0fbb6002015-04-16 11:11:53 -0400487bool State::getSampleCoverageInvert() const
488{
489 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400490}
491
492bool State::isScissorTestEnabled() const
493{
494 return mScissorTest;
495}
496
497void State::setScissorTest(bool enabled)
498{
499 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400500 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400501}
502
503void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
504{
505 mScissor.x = x;
506 mScissor.y = y;
507 mScissor.width = width;
508 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400509 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400510}
511
512const Rectangle &State::getScissor() const
513{
514 return mScissor;
515}
516
517bool State::isDitherEnabled() const
518{
519 return mBlend.dither;
520}
521
522void State::setDither(bool enabled)
523{
524 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400525 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400526}
527
Jamie Madillb4b53c52015-02-03 15:22:48 -0500528bool State::isPrimitiveRestartEnabled() const
529{
530 return mPrimitiveRestart;
531}
532
533void State::setPrimitiveRestart(bool enabled)
534{
535 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400536 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500537}
538
Shannon Woods53a94a82014-06-24 15:20:36 -0400539void State::setEnableFeature(GLenum feature, bool enabled)
540{
541 switch (feature)
542 {
543 case GL_CULL_FACE: setCullFace(enabled); break;
544 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
545 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
546 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
547 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
548 case GL_STENCIL_TEST: setStencilTest(enabled); break;
549 case GL_DEPTH_TEST: setDepthTest(enabled); break;
550 case GL_BLEND: setBlend(enabled); break;
551 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500552 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400553 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
554 default: UNREACHABLE();
555 }
556}
557
558bool State::getEnableFeature(GLenum feature)
559{
560 switch (feature)
561 {
562 case GL_CULL_FACE: return isCullFaceEnabled();
563 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
564 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
565 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
566 case GL_SCISSOR_TEST: return isScissorTestEnabled();
567 case GL_STENCIL_TEST: return isStencilTestEnabled();
568 case GL_DEPTH_TEST: return isDepthTestEnabled();
569 case GL_BLEND: return isBlendEnabled();
570 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500571 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400572 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
573 default: UNREACHABLE(); return false;
574 }
575}
576
577void State::setLineWidth(GLfloat width)
578{
579 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400580 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400581}
582
Geoff Lang4b3f4162015-04-16 13:22:05 -0400583float State::getLineWidth() const
584{
585 return mLineWidth;
586}
587
Shannon Woods53a94a82014-06-24 15:20:36 -0400588void State::setGenerateMipmapHint(GLenum hint)
589{
590 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400591 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400592}
593
594void State::setFragmentShaderDerivativeHint(GLenum hint)
595{
596 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400597 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400598 // TODO: Propagate the hint to shader translator so we can write
599 // ddx, ddx_coarse, or ddx_fine depending on the hint.
600 // Ignore for now. It is valid for implementations to ignore hint.
601}
602
603void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
604{
605 mViewport.x = x;
606 mViewport.y = y;
607 mViewport.width = width;
608 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400609 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400610}
611
612const Rectangle &State::getViewport() const
613{
614 return mViewport;
615}
616
617void State::setActiveSampler(unsigned int active)
618{
619 mActiveSampler = active;
620}
621
622unsigned int State::getActiveSampler() const
623{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700624 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400625}
626
Geoff Lang76b10c92014-09-05 16:28:14 -0400627void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400628{
Geoff Lang76b10c92014-09-05 16:28:14 -0400629 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400630}
631
Geoff Lang76b10c92014-09-05 16:28:14 -0400632Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400633{
Jamie Madill5864ac22015-01-12 14:43:07 -0500634 const auto it = mSamplerTextures.find(type);
635 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400636 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500637 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400638}
639
Geoff Lang76b10c92014-09-05 16:28:14 -0400640GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400641{
Jamie Madill5864ac22015-01-12 14:43:07 -0500642 const auto it = mSamplerTextures.find(type);
643 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400644 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500645 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400646}
647
Jamie Madille6382c32014-11-07 15:05:26 -0500648void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400649{
650 // Textures have a detach method on State rather than a simple
651 // removeBinding, because the zero/null texture objects are managed
652 // separately, and don't have to go through the Context's maps or
653 // the ResourceManager.
654
655 // [OpenGL ES 2.0.24] section 3.8 page 84:
656 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
657 // rebound to texture object zero
658
Geoff Lang76b10c92014-09-05 16:28:14 -0400659 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400660 {
Jamie Madille6382c32014-11-07 15:05:26 -0500661 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400662 TextureBindingVector &textureVector = bindingVec->second;
663 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400664 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400665 BindingPointer<Texture> &binding = textureVector[textureIdx];
666 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400667 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500668 auto it = zeroTextures.find(textureType);
669 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500670 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500671 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400672 }
673 }
674 }
675
676 // [OpenGL ES 2.0.24] section 4.4 page 112:
677 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
678 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
679 // image was attached in the currently bound framebuffer.
680
681 if (mReadFramebuffer)
682 {
683 mReadFramebuffer->detachTexture(texture);
684 }
685
686 if (mDrawFramebuffer)
687 {
688 mDrawFramebuffer->detachTexture(texture);
689 }
690}
691
Jamie Madille6382c32014-11-07 15:05:26 -0500692void State::initializeZeroTextures(const TextureMap &zeroTextures)
693{
694 for (const auto &zeroTexture : zeroTextures)
695 {
696 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
697
698 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
699 {
700 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
701 }
702 }
703}
704
Shannon Woods53a94a82014-06-24 15:20:36 -0400705void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
706{
707 mSamplers[textureUnit].set(sampler);
708}
709
710GLuint State::getSamplerId(GLuint textureUnit) const
711{
Geoff Lang76b10c92014-09-05 16:28:14 -0400712 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400713 return mSamplers[textureUnit].id();
714}
715
716Sampler *State::getSampler(GLuint textureUnit) const
717{
718 return mSamplers[textureUnit].get();
719}
720
721void State::detachSampler(GLuint sampler)
722{
723 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
724 // If a sampler object that is currently bound to one or more texture units is
725 // deleted, it is as though BindSampler is called once for each texture unit to
726 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400727 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400728 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400729 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
730 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400731 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400732 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400733 }
734 }
735}
736
737void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
738{
739 mRenderbuffer.set(renderbuffer);
740}
741
742GLuint State::getRenderbufferId() const
743{
744 return mRenderbuffer.id();
745}
746
747Renderbuffer *State::getCurrentRenderbuffer()
748{
749 return mRenderbuffer.get();
750}
751
752void State::detachRenderbuffer(GLuint renderbuffer)
753{
754 // [OpenGL ES 2.0.24] section 4.4 page 109:
755 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
756 // had been executed with the target RENDERBUFFER and name of zero.
757
758 if (mRenderbuffer.id() == renderbuffer)
759 {
760 mRenderbuffer.set(NULL);
761 }
762
763 // [OpenGL ES 2.0.24] section 4.4 page 111:
764 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
765 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
766 // point to which this image was attached in the currently bound framebuffer.
767
768 Framebuffer *readFramebuffer = mReadFramebuffer;
769 Framebuffer *drawFramebuffer = mDrawFramebuffer;
770
771 if (readFramebuffer)
772 {
773 readFramebuffer->detachRenderbuffer(renderbuffer);
774 }
775
776 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
777 {
778 drawFramebuffer->detachRenderbuffer(renderbuffer);
779 }
780
781}
782
783void State::setReadFramebufferBinding(Framebuffer *framebuffer)
784{
785 mReadFramebuffer = framebuffer;
786}
787
788void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
789{
790 mDrawFramebuffer = framebuffer;
791}
792
793Framebuffer *State::getTargetFramebuffer(GLenum target) const
794{
795 switch (target)
796 {
797 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
798 case GL_DRAW_FRAMEBUFFER_ANGLE:
799 case GL_FRAMEBUFFER: return mDrawFramebuffer;
800 default: UNREACHABLE(); return NULL;
801 }
802}
803
804Framebuffer *State::getReadFramebuffer()
805{
806 return mReadFramebuffer;
807}
808
809Framebuffer *State::getDrawFramebuffer()
810{
811 return mDrawFramebuffer;
812}
813
814const Framebuffer *State::getReadFramebuffer() const
815{
816 return mReadFramebuffer;
817}
818
819const Framebuffer *State::getDrawFramebuffer() const
820{
821 return mDrawFramebuffer;
822}
823
824bool State::removeReadFramebufferBinding(GLuint framebuffer)
825{
Jamie Madill77a72f62015-04-14 11:18:32 -0400826 if (mReadFramebuffer != nullptr &&
827 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400828 {
829 mReadFramebuffer = NULL;
830 return true;
831 }
832
833 return false;
834}
835
836bool State::removeDrawFramebufferBinding(GLuint framebuffer)
837{
Jamie Madill77a72f62015-04-14 11:18:32 -0400838 if (mReadFramebuffer != nullptr &&
839 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400840 {
841 mDrawFramebuffer = NULL;
842 return true;
843 }
844
845 return false;
846}
847
848void State::setVertexArrayBinding(VertexArray *vertexArray)
849{
850 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000851 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
852 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400853}
854
855GLuint State::getVertexArrayId() const
856{
857 ASSERT(mVertexArray != NULL);
858 return mVertexArray->id();
859}
860
861VertexArray *State::getVertexArray() const
862{
863 ASSERT(mVertexArray != NULL);
864 return mVertexArray;
865}
866
867bool State::removeVertexArrayBinding(GLuint vertexArray)
868{
869 if (mVertexArray->id() == vertexArray)
870 {
871 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000872 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
873 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400874 return true;
875 }
876
877 return false;
878}
879
Geoff Lang7dd2e102014-11-10 15:19:26 -0500880void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400881{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500882 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400883 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500884 if (mProgram)
885 {
886 mProgram->release();
887 }
888
889 mProgram = newProgram;
890
891 if (mProgram)
892 {
893 newProgram->addRef();
894 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400895 }
896}
897
Geoff Lang7dd2e102014-11-10 15:19:26 -0500898Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400899{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500900 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400901}
902
903void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
904{
905 mTransformFeedback.set(transformFeedback);
906}
907
908TransformFeedback *State::getCurrentTransformFeedback() const
909{
910 return mTransformFeedback.get();
911}
912
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000913bool State::isTransformFeedbackActiveUnpaused() const
914{
915 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400916 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000917}
918
Shannon Woods53a94a82014-06-24 15:20:36 -0400919void State::detachTransformFeedback(GLuint transformFeedback)
920{
921 if (mTransformFeedback.id() == transformFeedback)
922 {
923 mTransformFeedback.set(NULL);
924 }
925}
926
927bool State::isQueryActive() const
928{
929 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
930 i != mActiveQueries.end(); i++)
931 {
932 if (i->second.get() != NULL)
933 {
934 return true;
935 }
936 }
937
938 return false;
939}
940
941void State::setActiveQuery(GLenum target, Query *query)
942{
943 mActiveQueries[target].set(query);
944}
945
946GLuint State::getActiveQueryId(GLenum target) const
947{
948 const Query *query = getActiveQuery(target);
949 return (query ? query->id() : 0u);
950}
951
952Query *State::getActiveQuery(GLenum target) const
953{
Jamie Madill5864ac22015-01-12 14:43:07 -0500954 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400955
Jamie Madill5864ac22015-01-12 14:43:07 -0500956 // All query types should already exist in the activeQueries map
957 ASSERT(it != mActiveQueries.end());
958
959 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400960}
961
962void State::setArrayBufferBinding(Buffer *buffer)
963{
964 mArrayBuffer.set(buffer);
965}
966
967GLuint State::getArrayBufferId() const
968{
969 return mArrayBuffer.id();
970}
971
972bool State::removeArrayBufferBinding(GLuint buffer)
973{
974 if (mArrayBuffer.id() == buffer)
975 {
976 mArrayBuffer.set(NULL);
977 return true;
978 }
979
980 return false;
981}
982
983void State::setGenericUniformBufferBinding(Buffer *buffer)
984{
985 mGenericUniformBuffer.set(buffer);
986}
987
988void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
989{
990 mUniformBuffers[index].set(buffer, offset, size);
991}
992
993GLuint State::getIndexedUniformBufferId(GLuint index) const
994{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400995 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400996
997 return mUniformBuffers[index].id();
998}
999
1000Buffer *State::getIndexedUniformBuffer(GLuint index) const
1001{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001002 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001003
1004 return mUniformBuffers[index].get();
1005}
1006
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001007GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
1008{
1009 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1010
1011 return mUniformBuffers[index].getOffset();
1012}
1013
1014GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
1015{
1016 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1017
1018 return mUniformBuffers[index].getSize();
1019}
1020
Shannon Woods53a94a82014-06-24 15:20:36 -04001021void State::setCopyReadBufferBinding(Buffer *buffer)
1022{
1023 mCopyReadBuffer.set(buffer);
1024}
1025
1026void State::setCopyWriteBufferBinding(Buffer *buffer)
1027{
1028 mCopyWriteBuffer.set(buffer);
1029}
1030
1031void State::setPixelPackBufferBinding(Buffer *buffer)
1032{
1033 mPack.pixelBuffer.set(buffer);
1034}
1035
1036void State::setPixelUnpackBufferBinding(Buffer *buffer)
1037{
1038 mUnpack.pixelBuffer.set(buffer);
1039}
1040
1041Buffer *State::getTargetBuffer(GLenum target) const
1042{
1043 switch (target)
1044 {
1045 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1046 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1047 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001048 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001049 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1050 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001051 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001052 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1053 default: UNREACHABLE(); return NULL;
1054 }
1055}
1056
1057void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1058{
1059 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001060 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001061}
1062
1063void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1064{
Shannon Woods23e05002014-09-22 19:07:27 -04001065 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001066 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001067 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001068}
1069
1070void State::setVertexAttribu(GLuint index, const GLuint values[4])
1071{
Shannon Woods23e05002014-09-22 19:07:27 -04001072 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001073 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001074 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001075}
1076
1077void State::setVertexAttribi(GLuint index, const GLint values[4])
1078{
Shannon Woods23e05002014-09-22 19:07:27 -04001079 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001080 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001081 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001082}
1083
Jamie Madill0b9e9032015-08-17 11:51:52 +00001084void State::setVertexAttribState(unsigned int attribNum,
1085 Buffer *boundBuffer,
1086 GLint size,
1087 GLenum type,
1088 bool normalized,
1089 bool pureInteger,
1090 GLsizei stride,
1091 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001092{
1093 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001094 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
1095}
1096
1097void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1098{
1099 getVertexArray()->setVertexAttribDivisor(index, divisor);
1100 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001101}
1102
Shannon Woods53a94a82014-06-24 15:20:36 -04001103const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1104{
Shannon Woods23e05002014-09-22 19:07:27 -04001105 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001106 return mVertexAttribCurrentValues[attribNum];
1107}
1108
Shannon Woods53a94a82014-06-24 15:20:36 -04001109const void *State::getVertexAttribPointer(unsigned int attribNum) const
1110{
1111 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1112}
1113
1114void State::setPackAlignment(GLint alignment)
1115{
1116 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001117 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001118}
1119
1120GLint State::getPackAlignment() const
1121{
1122 return mPack.alignment;
1123}
1124
1125void State::setPackReverseRowOrder(bool reverseRowOrder)
1126{
1127 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001128 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001129}
1130
1131bool State::getPackReverseRowOrder() const
1132{
1133 return mPack.reverseRowOrder;
1134}
1135
1136const PixelPackState &State::getPackState() const
1137{
1138 return mPack;
1139}
1140
Jamie Madill87de3622015-03-16 10:41:44 -04001141PixelPackState &State::getPackState()
1142{
1143 return mPack;
1144}
1145
Shannon Woods53a94a82014-06-24 15:20:36 -04001146void State::setUnpackAlignment(GLint alignment)
1147{
1148 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001149 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001150}
1151
1152GLint State::getUnpackAlignment() const
1153{
1154 return mUnpack.alignment;
1155}
1156
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001157void State::setUnpackRowLength(GLint rowLength)
1158{
1159 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001160 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001161}
1162
1163GLint State::getUnpackRowLength() const
1164{
1165 return mUnpack.rowLength;
1166}
1167
Shannon Woods53a94a82014-06-24 15:20:36 -04001168const PixelUnpackState &State::getUnpackState() const
1169{
1170 return mUnpack;
1171}
1172
Jamie Madill67102f02015-03-16 10:41:42 -04001173PixelUnpackState &State::getUnpackState()
1174{
1175 return mUnpack;
1176}
1177
Shannon Woods53a94a82014-06-24 15:20:36 -04001178void State::getBooleanv(GLenum pname, GLboolean *params)
1179{
1180 switch (pname)
1181 {
1182 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1183 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1184 case GL_COLOR_WRITEMASK:
1185 params[0] = mBlend.colorMaskRed;
1186 params[1] = mBlend.colorMaskGreen;
1187 params[2] = mBlend.colorMaskBlue;
1188 params[3] = mBlend.colorMaskAlpha;
1189 break;
1190 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1191 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1192 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1193 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1194 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1195 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1196 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1197 case GL_BLEND: *params = mBlend.blend; break;
1198 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001199 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1200 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001201 default:
1202 UNREACHABLE();
1203 break;
1204 }
1205}
1206
1207void State::getFloatv(GLenum pname, GLfloat *params)
1208{
1209 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1210 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1211 // GetIntegerv as its native query function. As it would require conversion in any
1212 // case, this should make no difference to the calling application.
1213 switch (pname)
1214 {
1215 case GL_LINE_WIDTH: *params = mLineWidth; break;
1216 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1217 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1218 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1219 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1220 case GL_DEPTH_RANGE:
1221 params[0] = mNearZ;
1222 params[1] = mFarZ;
1223 break;
1224 case GL_COLOR_CLEAR_VALUE:
1225 params[0] = mColorClearValue.red;
1226 params[1] = mColorClearValue.green;
1227 params[2] = mColorClearValue.blue;
1228 params[3] = mColorClearValue.alpha;
1229 break;
1230 case GL_BLEND_COLOR:
1231 params[0] = mBlendColor.red;
1232 params[1] = mBlendColor.green;
1233 params[2] = mBlendColor.blue;
1234 params[3] = mBlendColor.alpha;
1235 break;
1236 default:
1237 UNREACHABLE();
1238 break;
1239 }
1240}
1241
Jamie Madill48faf802014-11-06 15:27:22 -05001242void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001243{
1244 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1245 {
1246 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001247 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001248 Framebuffer *framebuffer = mDrawFramebuffer;
1249 *params = framebuffer->getDrawBufferState(colorAttachment);
1250 return;
1251 }
1252
1253 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1254 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1255 // GetIntegerv as its native query function. As it would require conversion in any
1256 // case, this should make no difference to the calling application. You may find it in
1257 // State::getFloatv.
1258 switch (pname)
1259 {
1260 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001261 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001262 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1263 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1264 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1265 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1266 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001267 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001268 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1269 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1270 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001271 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001272 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1273 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001274 case GL_ACTIVE_TEXTURE:
1275 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1276 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001277 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1278 case GL_STENCIL_REF: *params = mStencilRef; break;
1279 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1280 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1281 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1282 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1283 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1284 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1285 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1286 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1287 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1288 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1289 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1290 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1291 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1292 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1293 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1294 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1295 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1296 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1297 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1298 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001299 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1300 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001301 case GL_SAMPLE_BUFFERS:
1302 case GL_SAMPLES:
1303 {
1304 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001305 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001306 {
1307 switch (pname)
1308 {
1309 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001310 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001311 {
1312 *params = 1;
1313 }
1314 else
1315 {
1316 *params = 0;
1317 }
1318 break;
1319 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001320 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001321 break;
1322 }
1323 }
1324 else
1325 {
1326 *params = 0;
1327 }
1328 }
1329 break;
1330 case GL_VIEWPORT:
1331 params[0] = mViewport.x;
1332 params[1] = mViewport.y;
1333 params[2] = mViewport.width;
1334 params[3] = mViewport.height;
1335 break;
1336 case GL_SCISSOR_BOX:
1337 params[0] = mScissor.x;
1338 params[1] = mScissor.y;
1339 params[2] = mScissor.width;
1340 params[3] = mScissor.height;
1341 break;
1342 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1343 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1344 case GL_RED_BITS:
1345 case GL_GREEN_BITS:
1346 case GL_BLUE_BITS:
1347 case GL_ALPHA_BITS:
1348 {
1349 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001350 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001351
1352 if (colorbuffer)
1353 {
1354 switch (pname)
1355 {
1356 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1357 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1358 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1359 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1360 }
1361 }
1362 else
1363 {
1364 *params = 0;
1365 }
1366 }
1367 break;
1368 case GL_DEPTH_BITS:
1369 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001370 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1371 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001372
1373 if (depthbuffer)
1374 {
1375 *params = depthbuffer->getDepthSize();
1376 }
1377 else
1378 {
1379 *params = 0;
1380 }
1381 }
1382 break;
1383 case GL_STENCIL_BITS:
1384 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001385 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1386 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001387
1388 if (stencilbuffer)
1389 {
1390 *params = stencilbuffer->getStencilSize();
1391 }
1392 else
1393 {
1394 *params = 0;
1395 }
1396 }
1397 break;
1398 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001399 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001400 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001401 break;
1402 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001403 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001404 *params =
1405 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001406 break;
1407 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001408 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001409 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001410 break;
1411 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001412 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001413 *params =
1414 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 break;
1416 case GL_UNIFORM_BUFFER_BINDING:
1417 *params = mGenericUniformBuffer.id();
1418 break;
1419 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001420 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001421 break;
1422 case GL_COPY_READ_BUFFER_BINDING:
1423 *params = mCopyReadBuffer.id();
1424 break;
1425 case GL_COPY_WRITE_BUFFER_BINDING:
1426 *params = mCopyWriteBuffer.id();
1427 break;
1428 case GL_PIXEL_PACK_BUFFER_BINDING:
1429 *params = mPack.pixelBuffer.id();
1430 break;
1431 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1432 *params = mUnpack.pixelBuffer.id();
1433 break;
1434 default:
1435 UNREACHABLE();
1436 break;
1437 }
1438}
1439
1440bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1441{
1442 switch (target)
1443 {
1444 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001445 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001446 {
Geoff Lang045536b2015-03-27 15:17:18 -04001447 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001448 }
1449 break;
1450 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001451 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001452 {
1453 *data = mUniformBuffers[index].id();
1454 }
1455 break;
1456 default:
1457 return false;
1458 }
1459
1460 return true;
1461}
1462
1463bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1464{
1465 switch (target)
1466 {
1467 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001468 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001469 {
Geoff Lang045536b2015-03-27 15:17:18 -04001470 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001471 }
1472 break;
1473 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001474 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001475 {
Geoff Lang045536b2015-03-27 15:17:18 -04001476 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001477 }
1478 break;
1479 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001480 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001481 {
1482 *data = mUniformBuffers[index].getOffset();
1483 }
1484 break;
1485 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001486 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001487 {
1488 *data = mUniformBuffers[index].getSize();
1489 }
1490 break;
1491 default:
1492 return false;
1493 }
1494
1495 return true;
1496}
1497
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001498bool State::hasMappedBuffer(GLenum target) const
1499{
1500 if (target == GL_ARRAY_BUFFER)
1501 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001502 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001503 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001504 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001505 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001506 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001507 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001508 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1509 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1510 {
1511 return true;
1512 }
1513 }
1514
1515 return false;
1516 }
1517 else
1518 {
1519 Buffer *buffer = getTargetBuffer(target);
1520 return (buffer && buffer->isMapped());
1521 }
1522}
1523
Shannon Woods53a94a82014-06-24 15:20:36 -04001524}