blob: 875738c0b4434edb2ac51489629dd2c55f65ff14 [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
9#include "libGLESv2/State.h"
10
11#include "libGLESv2/Context.h"
Geoff Lang76b10c92014-09-05 16:28:14 -040012#include "libGLESv2/Caps.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040013#include "libGLESv2/VertexArray.h"
14#include "libGLESv2/Query.h"
15#include "libGLESv2/Framebuffer.h"
16#include "libGLESv2/FramebufferAttachment.h"
17#include "libGLESv2/renderer/RenderTarget.h"
18#include "libGLESv2/formatutils.h"
19
20namespace gl
21{
Geoff Lang76b10c92014-09-05 16:28:14 -040022
Shannon Woods53a94a82014-06-24 15:20:36 -040023State::State()
24{
Shannon Woods2df6a602014-09-26 16:12:07 -040025 mMaxDrawBuffers = 0;
26 mMaxCombinedTextureImageUnits = 0;
Geoff Lang76b10c92014-09-05 16:28:14 -040027}
28
29State::~State()
30{
31 reset();
32}
33
34void State::initialize(const Caps& caps, GLuint clientVersion)
35{
Shannon Woods2df6a602014-09-26 16:12:07 -040036 mMaxDrawBuffers = caps.maxDrawBuffers;
37 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040038
39 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
40
41 mDepthClearValue = 1.0f;
42 mStencilClearValue = 0;
43
44 mRasterizer.rasterizerDiscard = false;
45 mRasterizer.cullFace = false;
46 mRasterizer.cullMode = GL_BACK;
47 mRasterizer.frontFace = GL_CCW;
48 mRasterizer.polygonOffsetFill = false;
49 mRasterizer.polygonOffsetFactor = 0.0f;
50 mRasterizer.polygonOffsetUnits = 0.0f;
51 mRasterizer.pointDrawMode = false;
52 mRasterizer.multiSample = false;
53 mScissorTest = false;
54 mScissor.x = 0;
55 mScissor.y = 0;
56 mScissor.width = 0;
57 mScissor.height = 0;
58
59 mBlend.blend = false;
60 mBlend.sourceBlendRGB = GL_ONE;
61 mBlend.sourceBlendAlpha = GL_ONE;
62 mBlend.destBlendRGB = GL_ZERO;
63 mBlend.destBlendAlpha = GL_ZERO;
64 mBlend.blendEquationRGB = GL_FUNC_ADD;
65 mBlend.blendEquationAlpha = GL_FUNC_ADD;
66 mBlend.sampleAlphaToCoverage = false;
67 mBlend.dither = true;
68
69 mBlendColor.red = 0;
70 mBlendColor.green = 0;
71 mBlendColor.blue = 0;
72 mBlendColor.alpha = 0;
73
74 mDepthStencil.depthTest = false;
75 mDepthStencil.depthFunc = GL_LESS;
76 mDepthStencil.depthMask = true;
77 mDepthStencil.stencilTest = false;
78 mDepthStencil.stencilFunc = GL_ALWAYS;
79 mDepthStencil.stencilMask = -1;
80 mDepthStencil.stencilWritemask = -1;
81 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Geoff Lang76b10c92014-09-05 16:28:14 -040082 mDepthStencil.stencilBackMask = -1;
Shannon Woods53a94a82014-06-24 15:20:36 -040083 mDepthStencil.stencilBackWritemask = -1;
84 mDepthStencil.stencilFail = GL_KEEP;
85 mDepthStencil.stencilPassDepthFail = GL_KEEP;
86 mDepthStencil.stencilPassDepthPass = GL_KEEP;
87 mDepthStencil.stencilBackFail = GL_KEEP;
88 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
89 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
90
91 mStencilRef = 0;
92 mStencilBackRef = 0;
93
94 mSampleCoverage = false;
95 mSampleCoverageValue = 1.0f;
96 mSampleCoverageInvert = false;
97 mGenerateMipmapHint = GL_DONT_CARE;
98 mFragmentShaderDerivativeHint = GL_DONT_CARE;
99
100 mLineWidth = 1.0f;
101
102 mViewport.x = 0;
103 mViewport.y = 0;
104 mViewport.width = 0;
105 mViewport.height = 0;
106 mNearZ = 0.0f;
107 mFarZ = 1.0f;
108
109 mBlend.colorMaskRed = true;
110 mBlend.colorMaskGreen = true;
111 mBlend.colorMaskBlue = true;
112 mBlend.colorMaskAlpha = true;
113
Geoff Lang76b10c92014-09-05 16:28:14 -0400114 mActiveSampler = 0;
115
Shannon Woods53a94a82014-06-24 15:20:36 -0400116 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
Shannon Woods23e05002014-09-22 19:07:27 -0400117 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
118 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
Shannon Woods53a94a82014-06-24 15:20:36 -0400119 {
120 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
121 }
122
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400123 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
124
Geoff Lang76b10c92014-09-05 16:28:14 -0400125 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
126 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
127 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400128 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400129 // TODO: These could also be enabled via extension
130 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
131 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400132 }
133
Geoff Lang76b10c92014-09-05 16:28:14 -0400134 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400135
136 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
137 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
138 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
139
140 mCurrentProgramId = 0;
141 mCurrentProgramBinary.set(NULL);
142
143 mReadFramebuffer = NULL;
144 mDrawFramebuffer = NULL;
145}
146
Geoff Lang76b10c92014-09-05 16:28:14 -0400147void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400148{
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400150 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400151 TextureBindingVector &textureVector = bindingVec->second;
152 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400153 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400154 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 }
156 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400157 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
158 {
159 mSamplers[samplerIdx].set(NULL);
160 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400161
Shannon Woods53a94a82014-06-24 15:20:36 -0400162 mArrayBuffer.set(NULL);
163 mRenderbuffer.set(NULL);
164
165 mTransformFeedback.set(NULL);
166
167 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
168 {
169 i->second.set(NULL);
170 }
171
172 mGenericUniformBuffer.set(NULL);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400173 mGenericTransformFeedbackBuffer.set(NULL);
174 for (UniformBufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400176 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400177 }
178
Shannon Woods53a94a82014-06-24 15:20:36 -0400179 for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
180 {
181 mTransformFeedbackBuffers[i].set(NULL);
182 }
183
184 mCopyReadBuffer.set(NULL);
185 mCopyWriteBuffer.set(NULL);
186
187 mPack.pixelBuffer.set(NULL);
188 mUnpack.pixelBuffer.set(NULL);
189}
190
191const RasterizerState &State::getRasterizerState() const
192{
193 return mRasterizer;
194}
195
196const BlendState &State::getBlendState() const
197{
198 return mBlend;
199}
200
201const DepthStencilState &State::getDepthStencilState() const
202{
203 return mDepthStencil;
204}
205
206void State::setClearColor(float red, float green, float blue, float alpha)
207{
208 mColorClearValue.red = red;
209 mColorClearValue.green = green;
210 mColorClearValue.blue = blue;
211 mColorClearValue.alpha = alpha;
212}
213
214void State::setClearDepth(float depth)
215{
216 mDepthClearValue = depth;
217}
218
219void State::setClearStencil(int stencil)
220{
221 mStencilClearValue = stencil;
222}
223
224ClearParameters State::getClearParameters(GLbitfield mask) const
225{
226 ClearParameters clearParams = { 0 };
227 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
228 {
229 clearParams.clearColor[i] = false;
230 }
231 clearParams.colorFClearValue = mColorClearValue;
232 clearParams.colorClearType = GL_FLOAT;
233 clearParams.colorMaskRed = mBlend.colorMaskRed;
234 clearParams.colorMaskGreen = mBlend.colorMaskGreen;
235 clearParams.colorMaskBlue = mBlend.colorMaskBlue;
236 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
237 clearParams.clearDepth = false;
238 clearParams.depthClearValue = mDepthClearValue;
239 clearParams.clearStencil = false;
240 clearParams.stencilClearValue = mStencilClearValue;
241 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
242 clearParams.scissorEnabled = mScissorTest;
243 clearParams.scissor = mScissor;
244
245 const Framebuffer *framebufferObject = getDrawFramebuffer();
246 if (mask & GL_COLOR_BUFFER_BIT)
247 {
248 if (framebufferObject->hasEnabledColorAttachment())
249 {
250 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
251 {
252 clearParams.clearColor[i] = true;
253 }
254 }
255 }
256
257 if (mask & GL_DEPTH_BUFFER_BIT)
258 {
259 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
260 {
261 clearParams.clearDepth = true;
262 }
263 }
264
265 if (mask & GL_STENCIL_BUFFER_BIT)
266 {
267 if (framebufferObject->getStencilbuffer() != NULL)
268 {
Jamie Madilldd8488d2014-09-03 15:07:21 -0400269 GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
270 if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
Shannon Woods53a94a82014-06-24 15:20:36 -0400271 {
272 clearParams.clearStencil = true;
273 }
274 }
275 }
276
277 return clearParams;
278}
279
280void State::setColorMask(bool red, bool green, bool blue, bool alpha)
281{
282 mBlend.colorMaskRed = red;
283 mBlend.colorMaskGreen = green;
284 mBlend.colorMaskBlue = blue;
285 mBlend.colorMaskAlpha = alpha;
286}
287
288void State::setDepthMask(bool mask)
289{
290 mDepthStencil.depthMask = mask;
291}
292
293bool State::isRasterizerDiscardEnabled() const
294{
295 return mRasterizer.rasterizerDiscard;
296}
297
298void State::setRasterizerDiscard(bool enabled)
299{
300 mRasterizer.rasterizerDiscard = enabled;
301}
302
303bool State::isCullFaceEnabled() const
304{
305 return mRasterizer.cullFace;
306}
307
308void State::setCullFace(bool enabled)
309{
310 mRasterizer.cullFace = enabled;
311}
312
313void State::setCullMode(GLenum mode)
314{
315 mRasterizer.cullMode = mode;
316}
317
318void State::setFrontFace(GLenum front)
319{
320 mRasterizer.frontFace = front;
321}
322
323bool State::isDepthTestEnabled() const
324{
325 return mDepthStencil.depthTest;
326}
327
328void State::setDepthTest(bool enabled)
329{
330 mDepthStencil.depthTest = enabled;
331}
332
333void State::setDepthFunc(GLenum depthFunc)
334{
335 mDepthStencil.depthFunc = depthFunc;
336}
337
338void State::setDepthRange(float zNear, float zFar)
339{
340 mNearZ = zNear;
341 mFarZ = zFar;
342}
343
344void State::getDepthRange(float *zNear, float *zFar) const
345{
346 *zNear = mNearZ;
347 *zFar = mFarZ;
348}
349
350bool State::isBlendEnabled() const
351{
352 return mBlend.blend;
353}
354
355void State::setBlend(bool enabled)
356{
357 mBlend.blend = enabled;
358}
359
360void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
361{
362 mBlend.sourceBlendRGB = sourceRGB;
363 mBlend.destBlendRGB = destRGB;
364 mBlend.sourceBlendAlpha = sourceAlpha;
365 mBlend.destBlendAlpha = destAlpha;
366}
367
368void State::setBlendColor(float red, float green, float blue, float alpha)
369{
370 mBlendColor.red = red;
371 mBlendColor.green = green;
372 mBlendColor.blue = blue;
373 mBlendColor.alpha = alpha;
374}
375
376void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
377{
378 mBlend.blendEquationRGB = rgbEquation;
379 mBlend.blendEquationAlpha = alphaEquation;
380}
381
382const ColorF &State::getBlendColor() const
383{
384 return mBlendColor;
385}
386
387bool State::isStencilTestEnabled() const
388{
389 return mDepthStencil.stencilTest;
390}
391
392void State::setStencilTest(bool enabled)
393{
394 mDepthStencil.stencilTest = enabled;
395}
396
397void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
398{
399 mDepthStencil.stencilFunc = stencilFunc;
400 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
401 mDepthStencil.stencilMask = stencilMask;
402}
403
404void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
405{
406 mDepthStencil.stencilBackFunc = stencilBackFunc;
407 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
408 mDepthStencil.stencilBackMask = stencilBackMask;
409}
410
411void State::setStencilWritemask(GLuint stencilWritemask)
412{
413 mDepthStencil.stencilWritemask = stencilWritemask;
414}
415
416void State::setStencilBackWritemask(GLuint stencilBackWritemask)
417{
418 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
419}
420
421void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
422{
423 mDepthStencil.stencilFail = stencilFail;
424 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
425 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
426}
427
428void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
429{
430 mDepthStencil.stencilBackFail = stencilBackFail;
431 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
432 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
433}
434
435GLint State::getStencilRef() const
436{
437 return mStencilRef;
438}
439
440GLint State::getStencilBackRef() const
441{
442 return mStencilBackRef;
443}
444
445bool State::isPolygonOffsetFillEnabled() const
446{
447 return mRasterizer.polygonOffsetFill;
448}
449
450void State::setPolygonOffsetFill(bool enabled)
451{
452 mRasterizer.polygonOffsetFill = enabled;
453}
454
455void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
456{
457 // An application can pass NaN values here, so handle this gracefully
458 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
459 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
460}
461
462bool State::isSampleAlphaToCoverageEnabled() const
463{
464 return mBlend.sampleAlphaToCoverage;
465}
466
467void State::setSampleAlphaToCoverage(bool enabled)
468{
469 mBlend.sampleAlphaToCoverage = enabled;
470}
471
472bool State::isSampleCoverageEnabled() const
473{
474 return mSampleCoverage;
475}
476
477void State::setSampleCoverage(bool enabled)
478{
479 mSampleCoverage = enabled;
480}
481
482void State::setSampleCoverageParams(GLclampf value, bool invert)
483{
484 mSampleCoverageValue = value;
485 mSampleCoverageInvert = invert;
486}
487
488void State::getSampleCoverageParams(GLclampf *value, bool *invert)
489{
490 ASSERT(value != NULL && invert != NULL);
491
492 *value = mSampleCoverageValue;
493 *invert = mSampleCoverageInvert;
494}
495
496bool State::isScissorTestEnabled() const
497{
498 return mScissorTest;
499}
500
501void State::setScissorTest(bool enabled)
502{
503 mScissorTest = enabled;
504}
505
506void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
507{
508 mScissor.x = x;
509 mScissor.y = y;
510 mScissor.width = width;
511 mScissor.height = height;
512}
513
514const Rectangle &State::getScissor() const
515{
516 return mScissor;
517}
518
519bool State::isDitherEnabled() const
520{
521 return mBlend.dither;
522}
523
524void State::setDither(bool enabled)
525{
526 mBlend.dither = enabled;
527}
528
529void State::setEnableFeature(GLenum feature, bool enabled)
530{
531 switch (feature)
532 {
533 case GL_CULL_FACE: setCullFace(enabled); break;
534 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
535 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
536 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
537 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
538 case GL_STENCIL_TEST: setStencilTest(enabled); break;
539 case GL_DEPTH_TEST: setDepthTest(enabled); break;
540 case GL_BLEND: setBlend(enabled); break;
541 case GL_DITHER: setDither(enabled); break;
542 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
543 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
544 default: UNREACHABLE();
545 }
546}
547
548bool State::getEnableFeature(GLenum feature)
549{
550 switch (feature)
551 {
552 case GL_CULL_FACE: return isCullFaceEnabled();
553 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
554 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
555 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
556 case GL_SCISSOR_TEST: return isScissorTestEnabled();
557 case GL_STENCIL_TEST: return isStencilTestEnabled();
558 case GL_DEPTH_TEST: return isDepthTestEnabled();
559 case GL_BLEND: return isBlendEnabled();
560 case GL_DITHER: return isDitherEnabled();
561 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
562 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
563 default: UNREACHABLE(); return false;
564 }
565}
566
567void State::setLineWidth(GLfloat width)
568{
569 mLineWidth = width;
570}
571
572void State::setGenerateMipmapHint(GLenum hint)
573{
574 mGenerateMipmapHint = hint;
575}
576
577void State::setFragmentShaderDerivativeHint(GLenum hint)
578{
579 mFragmentShaderDerivativeHint = hint;
580 // TODO: Propagate the hint to shader translator so we can write
581 // ddx, ddx_coarse, or ddx_fine depending on the hint.
582 // Ignore for now. It is valid for implementations to ignore hint.
583}
584
585void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
586{
587 mViewport.x = x;
588 mViewport.y = y;
589 mViewport.width = width;
590 mViewport.height = height;
591}
592
593const Rectangle &State::getViewport() const
594{
595 return mViewport;
596}
597
598void State::setActiveSampler(unsigned int active)
599{
600 mActiveSampler = active;
601}
602
603unsigned int State::getActiveSampler() const
604{
605 return mActiveSampler;
606}
607
Geoff Lang76b10c92014-09-05 16:28:14 -0400608void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400609{
Geoff Lang76b10c92014-09-05 16:28:14 -0400610 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400611}
612
Geoff Lang76b10c92014-09-05 16:28:14 -0400613Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400614{
Geoff Lang76b10c92014-09-05 16:28:14 -0400615 const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
Shannon Woods53a94a82014-06-24 15:20:36 -0400616
Geoff Lang76b10c92014-09-05 16:28:14 -0400617 if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
Shannon Woods53a94a82014-06-24 15:20:36 -0400618 {
619 return NULL;
620 }
621
Geoff Lang76b10c92014-09-05 16:28:14 -0400622 return binding.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400623}
624
Geoff Lang76b10c92014-09-05 16:28:14 -0400625GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400626{
Geoff Lang76b10c92014-09-05 16:28:14 -0400627 return mSamplerTextures.at(type)[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400628}
629
630void State::detachTexture(GLuint texture)
631{
632 // Textures have a detach method on State rather than a simple
633 // removeBinding, because the zero/null texture objects are managed
634 // separately, and don't have to go through the Context's maps or
635 // the ResourceManager.
636
637 // [OpenGL ES 2.0.24] section 3.8 page 84:
638 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
639 // rebound to texture object zero
640
Geoff Lang76b10c92014-09-05 16:28:14 -0400641 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400642 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400643 TextureBindingVector &textureVector = bindingVec->second;
644 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400645 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400646 BindingPointer<Texture> &binding = textureVector[textureIdx];
647 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400648 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400649 binding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400650 }
651 }
652 }
653
654 // [OpenGL ES 2.0.24] section 4.4 page 112:
655 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
656 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
657 // image was attached in the currently bound framebuffer.
658
659 if (mReadFramebuffer)
660 {
661 mReadFramebuffer->detachTexture(texture);
662 }
663
664 if (mDrawFramebuffer)
665 {
666 mDrawFramebuffer->detachTexture(texture);
667 }
668}
669
670void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
671{
672 mSamplers[textureUnit].set(sampler);
673}
674
675GLuint State::getSamplerId(GLuint textureUnit) const
676{
Geoff Lang76b10c92014-09-05 16:28:14 -0400677 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400678 return mSamplers[textureUnit].id();
679}
680
681Sampler *State::getSampler(GLuint textureUnit) const
682{
683 return mSamplers[textureUnit].get();
684}
685
686void State::detachSampler(GLuint sampler)
687{
688 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
689 // If a sampler object that is currently bound to one or more texture units is
690 // deleted, it is as though BindSampler is called once for each texture unit to
691 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400692 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400693 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400694 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
695 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400696 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400697 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400698 }
699 }
700}
701
702void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
703{
704 mRenderbuffer.set(renderbuffer);
705}
706
707GLuint State::getRenderbufferId() const
708{
709 return mRenderbuffer.id();
710}
711
712Renderbuffer *State::getCurrentRenderbuffer()
713{
714 return mRenderbuffer.get();
715}
716
717void State::detachRenderbuffer(GLuint renderbuffer)
718{
719 // [OpenGL ES 2.0.24] section 4.4 page 109:
720 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
721 // had been executed with the target RENDERBUFFER and name of zero.
722
723 if (mRenderbuffer.id() == renderbuffer)
724 {
725 mRenderbuffer.set(NULL);
726 }
727
728 // [OpenGL ES 2.0.24] section 4.4 page 111:
729 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
730 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
731 // point to which this image was attached in the currently bound framebuffer.
732
733 Framebuffer *readFramebuffer = mReadFramebuffer;
734 Framebuffer *drawFramebuffer = mDrawFramebuffer;
735
736 if (readFramebuffer)
737 {
738 readFramebuffer->detachRenderbuffer(renderbuffer);
739 }
740
741 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
742 {
743 drawFramebuffer->detachRenderbuffer(renderbuffer);
744 }
745
746}
747
748void State::setReadFramebufferBinding(Framebuffer *framebuffer)
749{
750 mReadFramebuffer = framebuffer;
751}
752
753void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
754{
755 mDrawFramebuffer = framebuffer;
756}
757
758Framebuffer *State::getTargetFramebuffer(GLenum target) const
759{
760 switch (target)
761 {
762 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
763 case GL_DRAW_FRAMEBUFFER_ANGLE:
764 case GL_FRAMEBUFFER: return mDrawFramebuffer;
765 default: UNREACHABLE(); return NULL;
766 }
767}
768
769Framebuffer *State::getReadFramebuffer()
770{
771 return mReadFramebuffer;
772}
773
774Framebuffer *State::getDrawFramebuffer()
775{
776 return mDrawFramebuffer;
777}
778
779const Framebuffer *State::getReadFramebuffer() const
780{
781 return mReadFramebuffer;
782}
783
784const Framebuffer *State::getDrawFramebuffer() const
785{
786 return mDrawFramebuffer;
787}
788
789bool State::removeReadFramebufferBinding(GLuint framebuffer)
790{
791 if (mReadFramebuffer->id() == framebuffer)
792 {
793 mReadFramebuffer = NULL;
794 return true;
795 }
796
797 return false;
798}
799
800bool State::removeDrawFramebufferBinding(GLuint framebuffer)
801{
802 if (mDrawFramebuffer->id() == framebuffer)
803 {
804 mDrawFramebuffer = NULL;
805 return true;
806 }
807
808 return false;
809}
810
811void State::setVertexArrayBinding(VertexArray *vertexArray)
812{
813 mVertexArray = vertexArray;
814}
815
816GLuint State::getVertexArrayId() const
817{
818 ASSERT(mVertexArray != NULL);
819 return mVertexArray->id();
820}
821
822VertexArray *State::getVertexArray() const
823{
824 ASSERT(mVertexArray != NULL);
825 return mVertexArray;
826}
827
828bool State::removeVertexArrayBinding(GLuint vertexArray)
829{
830 if (mVertexArray->id() == vertexArray)
831 {
832 mVertexArray = NULL;
833 return true;
834 }
835
836 return false;
837}
838
839void State::setCurrentProgram(GLuint programId, Program *newProgram)
840{
841 mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
842 mCurrentProgramBinary.set(NULL);
843
844 if (newProgram)
845 {
846 newProgram->addRef();
847 mCurrentProgramBinary.set(newProgram->getProgramBinary());
848 }
849}
850
851void State::setCurrentProgramBinary(ProgramBinary *binary)
852{
853 mCurrentProgramBinary.set(binary);
854}
855
856GLuint State::getCurrentProgramId() const
857{
858 return mCurrentProgramId;
859}
860
861ProgramBinary *State::getCurrentProgramBinary() const
862{
863 return mCurrentProgramBinary.get();
864}
865
866void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
867{
868 mTransformFeedback.set(transformFeedback);
869}
870
871TransformFeedback *State::getCurrentTransformFeedback() const
872{
873 return mTransformFeedback.get();
874}
875
876void State::detachTransformFeedback(GLuint transformFeedback)
877{
878 if (mTransformFeedback.id() == transformFeedback)
879 {
880 mTransformFeedback.set(NULL);
881 }
882}
883
884bool State::isQueryActive() const
885{
886 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
887 i != mActiveQueries.end(); i++)
888 {
889 if (i->second.get() != NULL)
890 {
891 return true;
892 }
893 }
894
895 return false;
896}
897
898void State::setActiveQuery(GLenum target, Query *query)
899{
900 mActiveQueries[target].set(query);
901}
902
903GLuint State::getActiveQueryId(GLenum target) const
904{
905 const Query *query = getActiveQuery(target);
906 return (query ? query->id() : 0u);
907}
908
909Query *State::getActiveQuery(GLenum target) const
910{
911 // All query types should already exist in the activeQueries map
912 ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
913
914 return mActiveQueries.at(target).get();
915}
916
917void State::setArrayBufferBinding(Buffer *buffer)
918{
919 mArrayBuffer.set(buffer);
920}
921
922GLuint State::getArrayBufferId() const
923{
924 return mArrayBuffer.id();
925}
926
927bool State::removeArrayBufferBinding(GLuint buffer)
928{
929 if (mArrayBuffer.id() == buffer)
930 {
931 mArrayBuffer.set(NULL);
932 return true;
933 }
934
935 return false;
936}
937
938void State::setGenericUniformBufferBinding(Buffer *buffer)
939{
940 mGenericUniformBuffer.set(buffer);
941}
942
943void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
944{
945 mUniformBuffers[index].set(buffer, offset, size);
946}
947
948GLuint State::getIndexedUniformBufferId(GLuint index) const
949{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400950 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400951
952 return mUniformBuffers[index].id();
953}
954
955Buffer *State::getIndexedUniformBuffer(GLuint index) const
956{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400957 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400958
959 return mUniformBuffers[index].get();
960}
961
962void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
963{
964 mGenericTransformFeedbackBuffer.set(buffer);
965}
966
967void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
968{
969 mTransformFeedbackBuffers[index].set(buffer, offset, size);
970}
971
972GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
973{
974 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
975
976 return mTransformFeedbackBuffers[index].id();
977}
978
979Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
980{
981 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
982
983 return mTransformFeedbackBuffers[index].get();
984}
985
986GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
987{
988 ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
989
990 return mTransformFeedbackBuffers[index].getOffset();
991}
992
993void State::setCopyReadBufferBinding(Buffer *buffer)
994{
995 mCopyReadBuffer.set(buffer);
996}
997
998void State::setCopyWriteBufferBinding(Buffer *buffer)
999{
1000 mCopyWriteBuffer.set(buffer);
1001}
1002
1003void State::setPixelPackBufferBinding(Buffer *buffer)
1004{
1005 mPack.pixelBuffer.set(buffer);
1006}
1007
1008void State::setPixelUnpackBufferBinding(Buffer *buffer)
1009{
1010 mUnpack.pixelBuffer.set(buffer);
1011}
1012
1013Buffer *State::getTargetBuffer(GLenum target) const
1014{
1015 switch (target)
1016 {
1017 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1018 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1019 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1020 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1021 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1022 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1023 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1024 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1025 default: UNREACHABLE(); return NULL;
1026 }
1027}
1028
1029void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1030{
1031 getVertexArray()->enableAttribute(attribNum, enabled);
1032}
1033
1034void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1035{
Shannon Woods23e05002014-09-22 19:07:27 -04001036 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001037 mVertexAttribCurrentValues[index].setFloatValues(values);
1038}
1039
1040void State::setVertexAttribu(GLuint index, const GLuint values[4])
1041{
Shannon Woods23e05002014-09-22 19:07:27 -04001042 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001043 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1044}
1045
1046void State::setVertexAttribi(GLuint index, const GLint values[4])
1047{
Shannon Woods23e05002014-09-22 19:07:27 -04001048 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001049 mVertexAttribCurrentValues[index].setIntValues(values);
1050}
1051
1052void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1053 bool pureInteger, GLsizei stride, const void *pointer)
1054{
1055 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1056}
1057
1058const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1059{
1060 return getVertexArray()->getVertexAttribute(attribNum);
1061}
1062
1063const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1064{
Shannon Woods23e05002014-09-22 19:07:27 -04001065 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001066 return mVertexAttribCurrentValues[attribNum];
1067}
1068
Shannon Woods53a94a82014-06-24 15:20:36 -04001069const void *State::getVertexAttribPointer(unsigned int attribNum) const
1070{
1071 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1072}
1073
1074void State::setPackAlignment(GLint alignment)
1075{
1076 mPack.alignment = alignment;
1077}
1078
1079GLint State::getPackAlignment() const
1080{
1081 return mPack.alignment;
1082}
1083
1084void State::setPackReverseRowOrder(bool reverseRowOrder)
1085{
1086 mPack.reverseRowOrder = reverseRowOrder;
1087}
1088
1089bool State::getPackReverseRowOrder() const
1090{
1091 return mPack.reverseRowOrder;
1092}
1093
1094const PixelPackState &State::getPackState() const
1095{
1096 return mPack;
1097}
1098
1099void State::setUnpackAlignment(GLint alignment)
1100{
1101 mUnpack.alignment = alignment;
1102}
1103
1104GLint State::getUnpackAlignment() const
1105{
1106 return mUnpack.alignment;
1107}
1108
1109const PixelUnpackState &State::getUnpackState() const
1110{
1111 return mUnpack;
1112}
1113
1114void State::getBooleanv(GLenum pname, GLboolean *params)
1115{
1116 switch (pname)
1117 {
1118 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1119 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1120 case GL_COLOR_WRITEMASK:
1121 params[0] = mBlend.colorMaskRed;
1122 params[1] = mBlend.colorMaskGreen;
1123 params[2] = mBlend.colorMaskBlue;
1124 params[3] = mBlend.colorMaskAlpha;
1125 break;
1126 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1127 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1128 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1129 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1130 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1131 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1132 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1133 case GL_BLEND: *params = mBlend.blend; break;
1134 case GL_DITHER: *params = mBlend.dither; break;
1135 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1136 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1137 default:
1138 UNREACHABLE();
1139 break;
1140 }
1141}
1142
1143void State::getFloatv(GLenum pname, GLfloat *params)
1144{
1145 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1146 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1147 // GetIntegerv as its native query function. As it would require conversion in any
1148 // case, this should make no difference to the calling application.
1149 switch (pname)
1150 {
1151 case GL_LINE_WIDTH: *params = mLineWidth; break;
1152 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1153 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1154 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1155 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1156 case GL_DEPTH_RANGE:
1157 params[0] = mNearZ;
1158 params[1] = mFarZ;
1159 break;
1160 case GL_COLOR_CLEAR_VALUE:
1161 params[0] = mColorClearValue.red;
1162 params[1] = mColorClearValue.green;
1163 params[2] = mColorClearValue.blue;
1164 params[3] = mColorClearValue.alpha;
1165 break;
1166 case GL_BLEND_COLOR:
1167 params[0] = mBlendColor.red;
1168 params[1] = mBlendColor.green;
1169 params[2] = mBlendColor.blue;
1170 params[3] = mBlendColor.alpha;
1171 break;
1172 default:
1173 UNREACHABLE();
1174 break;
1175 }
1176}
1177
1178void State::getIntegerv(GLenum pname, GLint *params)
1179{
1180 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1181 {
1182 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001183 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001184 Framebuffer *framebuffer = mDrawFramebuffer;
1185 *params = framebuffer->getDrawBufferState(colorAttachment);
1186 return;
1187 }
1188
1189 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1190 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1191 // GetIntegerv as its native query function. As it would require conversion in any
1192 // case, this should make no difference to the calling application. You may find it in
1193 // State::getFloatv.
1194 switch (pname)
1195 {
1196 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1197 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1198 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1199 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1200 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1201 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1202 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
1203 case GL_CURRENT_PROGRAM: *params = mCurrentProgramId; break;
1204 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1205 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1206 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
1207 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1208 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1209 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1210 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1211 case GL_STENCIL_REF: *params = mStencilRef; break;
1212 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1213 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1214 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1215 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1216 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1217 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1218 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1219 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1220 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1221 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1222 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1223 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1224 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1225 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1226 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1227 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1228 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1229 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1230 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1231 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
1232 case GL_SAMPLE_BUFFERS:
1233 case GL_SAMPLES:
1234 {
1235 gl::Framebuffer *framebuffer = mDrawFramebuffer;
1236 if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1237 {
1238 switch (pname)
1239 {
1240 case GL_SAMPLE_BUFFERS:
1241 if (framebuffer->getSamples() != 0)
1242 {
1243 *params = 1;
1244 }
1245 else
1246 {
1247 *params = 0;
1248 }
1249 break;
1250 case GL_SAMPLES:
1251 *params = framebuffer->getSamples();
1252 break;
1253 }
1254 }
1255 else
1256 {
1257 *params = 0;
1258 }
1259 }
1260 break;
1261 case GL_VIEWPORT:
1262 params[0] = mViewport.x;
1263 params[1] = mViewport.y;
1264 params[2] = mViewport.width;
1265 params[3] = mViewport.height;
1266 break;
1267 case GL_SCISSOR_BOX:
1268 params[0] = mScissor.x;
1269 params[1] = mScissor.y;
1270 params[2] = mScissor.width;
1271 params[3] = mScissor.height;
1272 break;
1273 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1274 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1275 case GL_RED_BITS:
1276 case GL_GREEN_BITS:
1277 case GL_BLUE_BITS:
1278 case GL_ALPHA_BITS:
1279 {
1280 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1281 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1282
1283 if (colorbuffer)
1284 {
1285 switch (pname)
1286 {
1287 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1288 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1289 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1290 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1291 }
1292 }
1293 else
1294 {
1295 *params = 0;
1296 }
1297 }
1298 break;
1299 case GL_DEPTH_BITS:
1300 {
1301 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1302 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1303
1304 if (depthbuffer)
1305 {
1306 *params = depthbuffer->getDepthSize();
1307 }
1308 else
1309 {
1310 *params = 0;
1311 }
1312 }
1313 break;
1314 case GL_STENCIL_BITS:
1315 {
1316 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1317 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1318
1319 if (stencilbuffer)
1320 {
1321 *params = stencilbuffer->getStencilSize();
1322 }
1323 else
1324 {
1325 *params = 0;
1326 }
1327 }
1328 break;
1329 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001330 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001331 *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001332 break;
1333 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001334 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001335 *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001336 break;
1337 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001338 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001339 *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001340 break;
1341 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001342 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001343 *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001344 break;
1345 case GL_UNIFORM_BUFFER_BINDING:
1346 *params = mGenericUniformBuffer.id();
1347 break;
1348 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1349 *params = mGenericTransformFeedbackBuffer.id();
1350 break;
1351 case GL_COPY_READ_BUFFER_BINDING:
1352 *params = mCopyReadBuffer.id();
1353 break;
1354 case GL_COPY_WRITE_BUFFER_BINDING:
1355 *params = mCopyWriteBuffer.id();
1356 break;
1357 case GL_PIXEL_PACK_BUFFER_BINDING:
1358 *params = mPack.pixelBuffer.id();
1359 break;
1360 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1361 *params = mUnpack.pixelBuffer.id();
1362 break;
1363 default:
1364 UNREACHABLE();
1365 break;
1366 }
1367}
1368
1369bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1370{
1371 switch (target)
1372 {
1373 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1374 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1375 {
1376 *data = mTransformFeedbackBuffers[index].id();
1377 }
1378 break;
1379 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001380 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001381 {
1382 *data = mUniformBuffers[index].id();
1383 }
1384 break;
1385 default:
1386 return false;
1387 }
1388
1389 return true;
1390}
1391
1392bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1393{
1394 switch (target)
1395 {
1396 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1397 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1398 {
1399 *data = mTransformFeedbackBuffers[index].getOffset();
1400 }
1401 break;
1402 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1403 if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1404 {
1405 *data = mTransformFeedbackBuffers[index].getSize();
1406 }
1407 break;
1408 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001409 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001410 {
1411 *data = mUniformBuffers[index].getOffset();
1412 }
1413 break;
1414 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001415 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001416 {
1417 *data = mUniformBuffers[index].getSize();
1418 }
1419 break;
1420 default:
1421 return false;
1422 }
1423
1424 return true;
1425}
1426
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001427bool State::hasMappedBuffer(GLenum target) const
1428{
1429 if (target == GL_ARRAY_BUFFER)
1430 {
Shannon Woods23e05002014-09-22 19:07:27 -04001431 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001432 {
Shannon Woods23e05002014-09-22 19:07:27 -04001433 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001434 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1435 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1436 {
1437 return true;
1438 }
1439 }
1440
1441 return false;
1442 }
1443 else
1444 {
1445 Buffer *buffer = getTargetBuffer(target);
1446 return (buffer && buffer->isMapped());
1447 }
1448}
1449
Shannon Woods53a94a82014-06-24 15:20:36 -04001450}