1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Context.cpp: Implements the es2::Context class, managing all GL state and performing
16 // rendering operations. It is the GLES2 specific implementation of EGLContext.
17
18 #include "Context.h"
19
20 #include "main.h"
21 #include "mathutil.h"
22 #include "utilities.h"
23 #include "ResourceManager.h"
24 #include "Buffer.h"
25 #include "Fence.h"
26 #include "Framebuffer.h"
27 #include "Program.h"
28 #include "Query.h"
29 #include "Renderbuffer.h"
30 #include "Sampler.h"
31 #include "Shader.h"
32 #include "Texture.h"
33 #include "TransformFeedback.h"
34 #include "VertexArray.h"
35 #include "VertexDataManager.h"
36 #include "IndexDataManager.h"
37 #include "libEGL/Display.h"
38 #include "common/Surface.hpp"
39 #include "Common/Half.hpp"
40
41 #include <EGL/eglext.h>
42
43 #include <algorithm>
44 #include <string>
45
46 namespace es2
47 {
Context(egl::Display * display,const Context * shareContext,const egl::Config * config)48 Context::Context(egl::Display *display, const Context *shareContext, const egl::Config *config)
49 : egl::Context(display), config(config)
50 {
51 sw::Context *context = new sw::Context();
52 device = new es2::Device(context);
53
54 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
55
56 mState.depthClearValue = 1.0f;
57 mState.stencilClearValue = 0;
58
59 mState.cullFaceEnabled = false;
60 mState.cullMode = GL_BACK;
61 mState.frontFace = GL_CCW;
62 mState.depthTestEnabled = false;
63 mState.depthFunc = GL_LESS;
64 mState.blendEnabled = false;
65 mState.sourceBlendRGB = GL_ONE;
66 mState.sourceBlendAlpha = GL_ONE;
67 mState.destBlendRGB = GL_ZERO;
68 mState.destBlendAlpha = GL_ZERO;
69 mState.blendEquationRGB = GL_FUNC_ADD;
70 mState.blendEquationAlpha = GL_FUNC_ADD;
71 mState.blendColor.red = 0;
72 mState.blendColor.green = 0;
73 mState.blendColor.blue = 0;
74 mState.blendColor.alpha = 0;
75 mState.stencilTestEnabled = false;
76 mState.stencilFunc = GL_ALWAYS;
77 mState.stencilRef = 0;
78 mState.stencilMask = 0xFFFFFFFFu;
79 mState.stencilWritemask = 0xFFFFFFFFu;
80 mState.stencilBackFunc = GL_ALWAYS;
81 mState.stencilBackRef = 0;
82 mState.stencilBackMask = 0xFFFFFFFFu;
83 mState.stencilBackWritemask = 0xFFFFFFFFu;
84 mState.stencilFail = GL_KEEP;
85 mState.stencilPassDepthFail = GL_KEEP;
86 mState.stencilPassDepthPass = GL_KEEP;
87 mState.stencilBackFail = GL_KEEP;
88 mState.stencilBackPassDepthFail = GL_KEEP;
89 mState.stencilBackPassDepthPass = GL_KEEP;
90 mState.polygonOffsetFillEnabled = false;
91 mState.polygonOffsetFactor = 0.0f;
92 mState.polygonOffsetUnits = 0.0f;
93 mState.sampleAlphaToCoverageEnabled = false;
94 mState.sampleCoverageEnabled = false;
95 mState.sampleCoverageValue = 1.0f;
96 mState.sampleCoverageInvert = false;
97 mState.scissorTestEnabled = false;
98 mState.ditherEnabled = true;
99 mState.primitiveRestartFixedIndexEnabled = false;
100 mState.rasterizerDiscardEnabled = false;
101 mState.generateMipmapHint = GL_DONT_CARE;
102 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
103 mState.textureFilteringHint = GL_DONT_CARE;
104
105 mState.lineWidth = 1.0f;
106
107 mState.viewportX = 0;
108 mState.viewportY = 0;
109 mState.viewportWidth = 0;
110 mState.viewportHeight = 0;
111 mState.zNear = 0.0f;
112 mState.zFar = 1.0f;
113
114 mState.scissorX = 0;
115 mState.scissorY = 0;
116 mState.scissorWidth = 0;
117 mState.scissorHeight = 0;
118
119 mState.colorMaskRed = true;
120 mState.colorMaskGreen = true;
121 mState.colorMaskBlue = true;
122 mState.colorMaskAlpha = true;
123 mState.depthMask = true;
124
125 if(shareContext)
126 {
127 mResourceManager = shareContext->mResourceManager;
128 mResourceManager->addRef();
129 }
130 else
131 {
132 mResourceManager = new ResourceManager();
133 }
134
135 // [OpenGL ES 2.0.24] section 3.7 page 83:
136 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
137 // and cube map texture state vectors respectively associated with them.
138 // In order that access to these initial textures not be lost, they are treated as texture
139 // objects all of whose names are 0.
140
141 mTexture2DZero = new Texture2D(0);
142 mTexture3DZero = new Texture3D(0);
143 mTexture2DArrayZero = new Texture2DArray(0);
144 mTextureCubeMapZero = new TextureCubeMap(0);
145 mTexture2DRectZero = new Texture2DRect(0);
146 mTextureExternalZero = new TextureExternal(0);
147
148 mState.activeSampler = 0;
149
150 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
151 {
152 bindTexture((TextureType)type, 0);
153 }
154
155 bindVertexArray(0);
156 bindArrayBuffer(0);
157 bindElementArrayBuffer(0);
158 bindReadFramebuffer(0);
159 bindDrawFramebuffer(0);
160 bindRenderbuffer(0);
161 bindGenericUniformBuffer(0);
162 bindTransformFeedback(0);
163
164 mState.currentProgram = 0;
165
166 mVertexDataManager = nullptr;
167 mIndexDataManager = nullptr;
168
169 mInvalidEnum = false;
170 mInvalidValue = false;
171 mInvalidOperation = false;
172 mOutOfMemory = false;
173 mInvalidFramebufferOperation = false;
174
175 mHasBeenCurrent = false;
176
177 markAllStateDirty();
178 }
179
~Context()180 Context::~Context()
181 {
182 if(mState.currentProgram != 0)
183 {
184 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
185 if(programObject)
186 {
187 programObject->release();
188 }
189 mState.currentProgram = 0;
190 }
191
192 while(!mFramebufferNameSpace.empty())
193 {
194 deleteFramebuffer(mFramebufferNameSpace.firstName());
195 }
196
197 while(!mFenceNameSpace.empty())
198 {
199 deleteFence(mFenceNameSpace.firstName());
200 }
201
202 while(!mQueryNameSpace.empty())
203 {
204 deleteQuery(mQueryNameSpace.firstName());
205 }
206
207 while(!mVertexArrayNameSpace.empty())
208 {
209 deleteVertexArray(mVertexArrayNameSpace.lastName());
210 }
211
212 while(!mTransformFeedbackNameSpace.empty())
213 {
214 deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
215 }
216
217 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
218 {
219 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
220 {
221 mState.samplerTexture[type][sampler] = nullptr;
222 }
223 }
224
225 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
226 {
227 mState.vertexAttribute[i].mBoundBuffer = nullptr;
228 }
229
230 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
231 {
232 mState.activeQuery[i] = nullptr;
233 }
234
235 mState.arrayBuffer = nullptr;
236 mState.copyReadBuffer = nullptr;
237 mState.copyWriteBuffer = nullptr;
238 mState.pixelPackBuffer = nullptr;
239 mState.pixelUnpackBuffer = nullptr;
240 mState.genericUniformBuffer = nullptr;
241
242 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; i++) {
243 mState.uniformBuffers[i].set(nullptr, 0, 0);
244 }
245
246 mState.renderbuffer = nullptr;
247
248 for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
249 {
250 mState.sampler[i] = nullptr;
251 }
252
253 mTexture2DZero = nullptr;
254 mTexture3DZero = nullptr;
255 mTexture2DArrayZero = nullptr;
256 mTextureCubeMapZero = nullptr;
257 mTexture2DRectZero = nullptr;
258 mTextureExternalZero = nullptr;
259
260 delete mVertexDataManager;
261 delete mIndexDataManager;
262
263 mResourceManager->release();
264 delete device;
265 }
266
makeCurrent(gl::Surface * surface)267 void Context::makeCurrent(gl::Surface *surface)
268 {
269 if(!mHasBeenCurrent)
270 {
271 mVertexDataManager = new VertexDataManager(this);
272 mIndexDataManager = new IndexDataManager();
273
274 mState.viewportX = 0;
275 mState.viewportY = 0;
276 mState.viewportWidth = surface ? surface->getWidth() : 0;
277 mState.viewportHeight = surface ? surface->getHeight() : 0;
278
279 mState.scissorX = 0;
280 mState.scissorY = 0;
281 mState.scissorWidth = surface ? surface->getWidth() : 0;
282 mState.scissorHeight = surface ? surface->getHeight() : 0;
283
284 mHasBeenCurrent = true;
285 }
286
287 if(surface)
288 {
289 // Wrap the existing resources into GL objects and assign them to the '0' names
290 egl::Image *defaultRenderTarget = surface->getRenderTarget();
291 egl::Image *depthStencil = surface->getDepthStencil();
292
293 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
294 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
295 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
296
297 setFramebufferZero(framebufferZero);
298
299 if(defaultRenderTarget)
300 {
301 defaultRenderTarget->release();
302 }
303
304 if(depthStencil)
305 {
306 depthStencil->release();
307 }
308 }
309 else
310 {
311 setFramebufferZero(nullptr);
312 }
313
314 markAllStateDirty();
315 }
316
getClientVersion() const317 EGLint Context::getClientVersion() const
318 {
319 return 3;
320 }
321
getConfigID() const322 EGLint Context::getConfigID() const
323 {
324 return config->mConfigID;
325 }
326
327 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()328 void Context::markAllStateDirty()
329 {
330 mAppliedProgramSerial = 0;
331
332 mDepthStateDirty = true;
333 mMaskStateDirty = true;
334 mBlendStateDirty = true;
335 mStencilStateDirty = true;
336 mPolygonOffsetStateDirty = true;
337 mSampleStateDirty = true;
338 mDitherStateDirty = true;
339 mFrontFaceDirty = true;
340 }
341
setClearColor(float red,float green,float blue,float alpha)342 void Context::setClearColor(float red, float green, float blue, float alpha)
343 {
344 mState.colorClearValue.red = red;
345 mState.colorClearValue.green = green;
346 mState.colorClearValue.blue = blue;
347 mState.colorClearValue.alpha = alpha;
348 }
349
setClearDepth(float depth)350 void Context::setClearDepth(float depth)
351 {
352 mState.depthClearValue = depth;
353 }
354
setClearStencil(int stencil)355 void Context::setClearStencil(int stencil)
356 {
357 mState.stencilClearValue = stencil;
358 }
359
setCullFaceEnabled(bool enabled)360 void Context::setCullFaceEnabled(bool enabled)
361 {
362 mState.cullFaceEnabled = enabled;
363 }
364
isCullFaceEnabled() const365 bool Context::isCullFaceEnabled() const
366 {
367 return mState.cullFaceEnabled;
368 }
369
setCullMode(GLenum mode)370 void Context::setCullMode(GLenum mode)
371 {
372 mState.cullMode = mode;
373 }
374
setFrontFace(GLenum front)375 void Context::setFrontFace(GLenum front)
376 {
377 if(mState.frontFace != front)
378 {
379 mState.frontFace = front;
380 mFrontFaceDirty = true;
381 }
382 }
383
setDepthTestEnabled(bool enabled)384 void Context::setDepthTestEnabled(bool enabled)
385 {
386 if(mState.depthTestEnabled != enabled)
387 {
388 mState.depthTestEnabled = enabled;
389 mDepthStateDirty = true;
390 }
391 }
392
isDepthTestEnabled() const393 bool Context::isDepthTestEnabled() const
394 {
395 return mState.depthTestEnabled;
396 }
397
setDepthFunc(GLenum depthFunc)398 void Context::setDepthFunc(GLenum depthFunc)
399 {
400 if(mState.depthFunc != depthFunc)
401 {
402 mState.depthFunc = depthFunc;
403 mDepthStateDirty = true;
404 }
405 }
406
setDepthRange(float zNear,float zFar)407 void Context::setDepthRange(float zNear, float zFar)
408 {
409 mState.zNear = zNear;
410 mState.zFar = zFar;
411 }
412
setBlendEnabled(bool enabled)413 void Context::setBlendEnabled(bool enabled)
414 {
415 if(mState.blendEnabled != enabled)
416 {
417 mState.blendEnabled = enabled;
418 mBlendStateDirty = true;
419 }
420 }
421
isBlendEnabled() const422 bool Context::isBlendEnabled() const
423 {
424 return mState.blendEnabled;
425 }
426
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)427 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
428 {
429 if(mState.sourceBlendRGB != sourceRGB ||
430 mState.sourceBlendAlpha != sourceAlpha ||
431 mState.destBlendRGB != destRGB ||
432 mState.destBlendAlpha != destAlpha)
433 {
434 mState.sourceBlendRGB = sourceRGB;
435 mState.destBlendRGB = destRGB;
436 mState.sourceBlendAlpha = sourceAlpha;
437 mState.destBlendAlpha = destAlpha;
438 mBlendStateDirty = true;
439 }
440 }
441
setBlendColor(float red,float green,float blue,float alpha)442 void Context::setBlendColor(float red, float green, float blue, float alpha)
443 {
444 if(mState.blendColor.red != red ||
445 mState.blendColor.green != green ||
446 mState.blendColor.blue != blue ||
447 mState.blendColor.alpha != alpha)
448 {
449 mState.blendColor.red = red;
450 mState.blendColor.green = green;
451 mState.blendColor.blue = blue;
452 mState.blendColor.alpha = alpha;
453 mBlendStateDirty = true;
454 }
455 }
456
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)457 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
458 {
459 if(mState.blendEquationRGB != rgbEquation ||
460 mState.blendEquationAlpha != alphaEquation)
461 {
462 mState.blendEquationRGB = rgbEquation;
463 mState.blendEquationAlpha = alphaEquation;
464 mBlendStateDirty = true;
465 }
466 }
467
setStencilTestEnabled(bool enabled)468 void Context::setStencilTestEnabled(bool enabled)
469 {
470 if(mState.stencilTestEnabled != enabled)
471 {
472 mState.stencilTestEnabled = enabled;
473 mStencilStateDirty = true;
474 }
475 }
476
isStencilTestEnabled() const477 bool Context::isStencilTestEnabled() const
478 {
479 return mState.stencilTestEnabled;
480 }
481
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)482 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
483 {
484 if(mState.stencilFunc != stencilFunc ||
485 mState.stencilRef != stencilRef ||
486 mState.stencilMask != stencilMask)
487 {
488 mState.stencilFunc = stencilFunc;
489 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
490 mState.stencilMask = stencilMask;
491 mStencilStateDirty = true;
492 }
493 }
494
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)495 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
496 {
497 if(mState.stencilBackFunc != stencilBackFunc ||
498 mState.stencilBackRef != stencilBackRef ||
499 mState.stencilBackMask != stencilBackMask)
500 {
501 mState.stencilBackFunc = stencilBackFunc;
502 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
503 mState.stencilBackMask = stencilBackMask;
504 mStencilStateDirty = true;
505 }
506 }
507
setStencilWritemask(GLuint stencilWritemask)508 void Context::setStencilWritemask(GLuint stencilWritemask)
509 {
510 if(mState.stencilWritemask != stencilWritemask)
511 {
512 mState.stencilWritemask = stencilWritemask;
513 mStencilStateDirty = true;
514 }
515 }
516
setStencilBackWritemask(GLuint stencilBackWritemask)517 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
518 {
519 if(mState.stencilBackWritemask != stencilBackWritemask)
520 {
521 mState.stencilBackWritemask = stencilBackWritemask;
522 mStencilStateDirty = true;
523 }
524 }
525
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)526 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
527 {
528 if(mState.stencilFail != stencilFail ||
529 mState.stencilPassDepthFail != stencilPassDepthFail ||
530 mState.stencilPassDepthPass != stencilPassDepthPass)
531 {
532 mState.stencilFail = stencilFail;
533 mState.stencilPassDepthFail = stencilPassDepthFail;
534 mState.stencilPassDepthPass = stencilPassDepthPass;
535 mStencilStateDirty = true;
536 }
537 }
538
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)539 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
540 {
541 if(mState.stencilBackFail != stencilBackFail ||
542 mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
543 mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
544 {
545 mState.stencilBackFail = stencilBackFail;
546 mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
547 mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
548 mStencilStateDirty = true;
549 }
550 }
551
setPolygonOffsetFillEnabled(bool enabled)552 void Context::setPolygonOffsetFillEnabled(bool enabled)
553 {
554 if(mState.polygonOffsetFillEnabled != enabled)
555 {
556 mState.polygonOffsetFillEnabled = enabled;
557 mPolygonOffsetStateDirty = true;
558 }
559 }
560
isPolygonOffsetFillEnabled() const561 bool Context::isPolygonOffsetFillEnabled() const
562 {
563 return mState.polygonOffsetFillEnabled;
564 }
565
setPolygonOffsetParams(GLfloat factor,GLfloat units)566 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
567 {
568 if(mState.polygonOffsetFactor != factor ||
569 mState.polygonOffsetUnits != units)
570 {
571 mState.polygonOffsetFactor = factor;
572 mState.polygonOffsetUnits = units;
573 mPolygonOffsetStateDirty = true;
574 }
575 }
576
setSampleAlphaToCoverageEnabled(bool enabled)577 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
578 {
579 if(mState.sampleAlphaToCoverageEnabled != enabled)
580 {
581 mState.sampleAlphaToCoverageEnabled = enabled;
582 mSampleStateDirty = true;
583 }
584 }
585
isSampleAlphaToCoverageEnabled() const586 bool Context::isSampleAlphaToCoverageEnabled() const
587 {
588 return mState.sampleAlphaToCoverageEnabled;
589 }
590
setSampleCoverageEnabled(bool enabled)591 void Context::setSampleCoverageEnabled(bool enabled)
592 {
593 if(mState.sampleCoverageEnabled != enabled)
594 {
595 mState.sampleCoverageEnabled = enabled;
596 mSampleStateDirty = true;
597 }
598 }
599
isSampleCoverageEnabled() const600 bool Context::isSampleCoverageEnabled() const
601 {
602 return mState.sampleCoverageEnabled;
603 }
604
setSampleCoverageParams(GLclampf value,bool invert)605 void Context::setSampleCoverageParams(GLclampf value, bool invert)
606 {
607 if(mState.sampleCoverageValue != value ||
608 mState.sampleCoverageInvert != invert)
609 {
610 mState.sampleCoverageValue = value;
611 mState.sampleCoverageInvert = invert;
612 mSampleStateDirty = true;
613 }
614 }
615
setScissorTestEnabled(bool enabled)616 void Context::setScissorTestEnabled(bool enabled)
617 {
618 mState.scissorTestEnabled = enabled;
619 }
620
isScissorTestEnabled() const621 bool Context::isScissorTestEnabled() const
622 {
623 return mState.scissorTestEnabled;
624 }
625
setDitherEnabled(bool enabled)626 void Context::setDitherEnabled(bool enabled)
627 {
628 if(mState.ditherEnabled != enabled)
629 {
630 mState.ditherEnabled = enabled;
631 mDitherStateDirty = true;
632 }
633 }
634
isDitherEnabled() const635 bool Context::isDitherEnabled() const
636 {
637 return mState.ditherEnabled;
638 }
639
setPrimitiveRestartFixedIndexEnabled(bool enabled)640 void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
641 {
642 mState.primitiveRestartFixedIndexEnabled = enabled;
643 }
644
isPrimitiveRestartFixedIndexEnabled() const645 bool Context::isPrimitiveRestartFixedIndexEnabled() const
646 {
647 return mState.primitiveRestartFixedIndexEnabled;
648 }
649
setRasterizerDiscardEnabled(bool enabled)650 void Context::setRasterizerDiscardEnabled(bool enabled)
651 {
652 mState.rasterizerDiscardEnabled = enabled;
653 }
654
isRasterizerDiscardEnabled() const655 bool Context::isRasterizerDiscardEnabled() const
656 {
657 return mState.rasterizerDiscardEnabled;
658 }
659
setLineWidth(GLfloat width)660 void Context::setLineWidth(GLfloat width)
661 {
662 mState.lineWidth = width;
663 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
664 }
665
setGenerateMipmapHint(GLenum hint)666 void Context::setGenerateMipmapHint(GLenum hint)
667 {
668 mState.generateMipmapHint = hint;
669 }
670
setFragmentShaderDerivativeHint(GLenum hint)671 void Context::setFragmentShaderDerivativeHint(GLenum hint)
672 {
673 mState.fragmentShaderDerivativeHint = hint;
674 // TODO: Propagate the hint to shader translator so we can write
675 // ddx, ddx_coarse, or ddx_fine depending on the hint.
676 // Ignore for now. It is valid for implementations to ignore hint.
677 }
678
setTextureFilteringHint(GLenum hint)679 void Context::setTextureFilteringHint(GLenum hint)
680 {
681 mState.textureFilteringHint = hint;
682 }
683
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)684 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
685 {
686 mState.viewportX = x;
687 mState.viewportY = y;
688 mState.viewportWidth = std::min<GLsizei>(width, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[0]
689 mState.viewportHeight = std::min<GLsizei>(height, IMPLEMENTATION_MAX_RENDERBUFFER_SIZE); // GL_MAX_VIEWPORT_DIMS[1]
690 }
691
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)692 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
693 {
694 mState.scissorX = x;
695 mState.scissorY = y;
696 mState.scissorWidth = width;
697 mState.scissorHeight = height;
698 }
699
setColorMask(bool red,bool green,bool blue,bool alpha)700 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
701 {
702 if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
703 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
704 {
705 mState.colorMaskRed = red;
706 mState.colorMaskGreen = green;
707 mState.colorMaskBlue = blue;
708 mState.colorMaskAlpha = alpha;
709 mMaskStateDirty = true;
710 }
711 }
712
getColorMask() const713 unsigned int Context::getColorMask() const
714 {
715 return (mState.colorMaskRed ? 0x1 : 0) |
716 (mState.colorMaskGreen ? 0x2 : 0) |
717 (mState.colorMaskBlue ? 0x4 : 0) |
718 (mState.colorMaskAlpha ? 0x8 : 0);
719 }
720
setDepthMask(bool mask)721 void Context::setDepthMask(bool mask)
722 {
723 if(mState.depthMask != mask)
724 {
725 mState.depthMask = mask;
726 mMaskStateDirty = true;
727 }
728 }
729
setActiveSampler(unsigned int active)730 void Context::setActiveSampler(unsigned int active)
731 {
732 mState.activeSampler = active;
733 }
734
getReadFramebufferName() const735 GLuint Context::getReadFramebufferName() const
736 {
737 return mState.readFramebuffer;
738 }
739
getDrawFramebufferName() const740 GLuint Context::getDrawFramebufferName() const
741 {
742 return mState.drawFramebuffer;
743 }
744
getRenderbufferName() const745 GLuint Context::getRenderbufferName() const
746 {
747 return mState.renderbuffer.name();
748 }
749
setFramebufferReadBuffer(GLuint buf)750 void Context::setFramebufferReadBuffer(GLuint buf)
751 {
752 Framebuffer *framebuffer = getReadFramebuffer();
753
754 if(framebuffer)
755 {
756 framebuffer->setReadBuffer(buf);
757 }
758 else
759 {
760 return error(GL_INVALID_OPERATION);
761 }
762 }
763
setFramebufferDrawBuffers(GLsizei n,const GLenum * bufs)764 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
765 {
766 Framebuffer *drawFramebuffer = getDrawFramebuffer();
767
768 if(drawFramebuffer)
769 {
770 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
771 {
772 drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
773 }
774 }
775 else
776 {
777 return error(GL_INVALID_OPERATION);
778 }
779 }
780
getArrayBufferName() const781 GLuint Context::getArrayBufferName() const
782 {
783 return mState.arrayBuffer.name();
784 }
785
getElementArrayBufferName() const786 GLuint Context::getElementArrayBufferName() const
787 {
788 Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
789 return elementArrayBuffer ? elementArrayBuffer->name : 0;
790 }
791
getActiveQuery(GLenum target) const792 GLuint Context::getActiveQuery(GLenum target) const
793 {
794 Query *queryObject = nullptr;
795
796 switch(target)
797 {
798 case GL_ANY_SAMPLES_PASSED_EXT:
799 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
800 break;
801 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
802 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
803 break;
804 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
805 queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
806 break;
807 default:
808 ASSERT(false);
809 }
810
811 if(queryObject)
812 {
813 return queryObject->name;
814 }
815
816 return 0;
817 }
818
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)819 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
820 {
821 getCurrentVertexArray()->enableAttribute(attribNum, enabled);
822 }
823
setVertexAttribDivisor(unsigned int attribNum,GLuint divisor)824 void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
825 {
826 getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
827 }
828
getVertexAttribState(unsigned int attribNum) const829 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
830 {
831 return getCurrentVertexArray()->getVertexAttribute(attribNum);
832 }
833
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,bool pureInteger,GLsizei stride,const void * pointer)834 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
835 bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
836 {
837 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
838 }
839
getVertexAttribPointer(unsigned int attribNum) const840 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
841 {
842 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
843 }
844
getVertexArrayAttributes()845 const VertexAttributeArray &Context::getVertexArrayAttributes()
846 {
847 return getCurrentVertexArray()->getVertexAttributes();
848 }
849
getCurrentVertexAttributes()850 const VertexAttributeArray &Context::getCurrentVertexAttributes()
851 {
852 return mState.vertexAttribute;
853 }
854
setPackAlignment(GLint alignment)855 void Context::setPackAlignment(GLint alignment)
856 {
857 mState.packParameters.alignment = alignment;
858 }
859
setUnpackAlignment(GLint alignment)860 void Context::setUnpackAlignment(GLint alignment)
861 {
862 mState.unpackParameters.alignment = alignment;
863 }
864
getUnpackParameters() const865 const gl::PixelStorageModes &Context::getUnpackParameters() const
866 {
867 return mState.unpackParameters;
868 }
869
setPackRowLength(GLint rowLength)870 void Context::setPackRowLength(GLint rowLength)
871 {
872 mState.packParameters.rowLength = rowLength;
873 }
874
setPackSkipPixels(GLint skipPixels)875 void Context::setPackSkipPixels(GLint skipPixels)
876 {
877 mState.packParameters.skipPixels = skipPixels;
878 }
879
setPackSkipRows(GLint skipRows)880 void Context::setPackSkipRows(GLint skipRows)
881 {
882 mState.packParameters.skipRows = skipRows;
883 }
884
setUnpackRowLength(GLint rowLength)885 void Context::setUnpackRowLength(GLint rowLength)
886 {
887 mState.unpackParameters.rowLength = rowLength;
888 }
889
setUnpackImageHeight(GLint imageHeight)890 void Context::setUnpackImageHeight(GLint imageHeight)
891 {
892 mState.unpackParameters.imageHeight = imageHeight;
893 }
894
setUnpackSkipPixels(GLint skipPixels)895 void Context::setUnpackSkipPixels(GLint skipPixels)
896 {
897 mState.unpackParameters.skipPixels = skipPixels;
898 }
899
setUnpackSkipRows(GLint skipRows)900 void Context::setUnpackSkipRows(GLint skipRows)
901 {
902 mState.unpackParameters.skipRows = skipRows;
903 }
904
setUnpackSkipImages(GLint skipImages)905 void Context::setUnpackSkipImages(GLint skipImages)
906 {
907 mState.unpackParameters.skipImages = skipImages;
908 }
909
createBuffer()910 GLuint Context::createBuffer()
911 {
912 return mResourceManager->createBuffer();
913 }
914
createProgram()915 GLuint Context::createProgram()
916 {
917 return mResourceManager->createProgram();
918 }
919
createShader(GLenum type)920 GLuint Context::createShader(GLenum type)
921 {
922 return mResourceManager->createShader(type);
923 }
924
createTexture()925 GLuint Context::createTexture()
926 {
927 return mResourceManager->createTexture();
928 }
929
createRenderbuffer()930 GLuint Context::createRenderbuffer()
931 {
932 return mResourceManager->createRenderbuffer();
933 }
934
935 // Returns an unused framebuffer name
createFramebuffer()936 GLuint Context::createFramebuffer()
937 {
938 return mFramebufferNameSpace.allocate();
939 }
940
createFence()941 GLuint Context::createFence()
942 {
943 return mFenceNameSpace.allocate(new Fence());
944 }
945
946 // Returns an unused query name
createQuery()947 GLuint Context::createQuery()
948 {
949 return mQueryNameSpace.allocate();
950 }
951
952 // Returns an unused vertex array name
createVertexArray()953 GLuint Context::createVertexArray()
954 {
955 return mVertexArrayNameSpace.allocate();
956 }
957
createFenceSync(GLenum condition,GLbitfield flags)958 GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
959 {
960 GLuint handle = mResourceManager->createFenceSync(condition, flags);
961
962 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
963 }
964
965 // Returns an unused transform feedback name
createTransformFeedback()966 GLuint Context::createTransformFeedback()
967 {
968 return mTransformFeedbackNameSpace.allocate();
969 }
970
971 // Returns an unused sampler name
createSampler()972 GLuint Context::createSampler()
973 {
974 return mResourceManager->createSampler();
975 }
976
deleteBuffer(GLuint buffer)977 void Context::deleteBuffer(GLuint buffer)
978 {
979 detachBuffer(buffer);
980
981 mResourceManager->deleteBuffer(buffer);
982 }
983
deleteShader(GLuint shader)984 void Context::deleteShader(GLuint shader)
985 {
986 mResourceManager->deleteShader(shader);
987 }
988
deleteProgram(GLuint program)989 void Context::deleteProgram(GLuint program)
990 {
991 mResourceManager->deleteProgram(program);
992 }
993
deleteTexture(GLuint texture)994 void Context::deleteTexture(GLuint texture)
995 {
996 detachTexture(texture);
997
998 mResourceManager->deleteTexture(texture);
999 }
1000
deleteRenderbuffer(GLuint renderbuffer)1001 void Context::deleteRenderbuffer(GLuint renderbuffer)
1002 {
1003 if(mResourceManager->getRenderbuffer(renderbuffer))
1004 {
1005 detachRenderbuffer(renderbuffer);
1006 }
1007
1008 mResourceManager->deleteRenderbuffer(renderbuffer);
1009 }
1010
deleteFramebuffer(GLuint framebuffer)1011 void Context::deleteFramebuffer(GLuint framebuffer)
1012 {
1013 detachFramebuffer(framebuffer);
1014
1015 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
1016
1017 if(framebufferObject)
1018 {
1019 delete framebufferObject;
1020 }
1021 }
1022
deleteFence(GLuint fence)1023 void Context::deleteFence(GLuint fence)
1024 {
1025 Fence *fenceObject = mFenceNameSpace.remove(fence);
1026
1027 if(fenceObject)
1028 {
1029 delete fenceObject;
1030 }
1031 }
1032
deleteQuery(GLuint query)1033 void Context::deleteQuery(GLuint query)
1034 {
1035 Query *queryObject = mQueryNameSpace.remove(query);
1036
1037 if(queryObject)
1038 {
1039 queryObject->release();
1040 }
1041 }
1042
deleteVertexArray(GLuint vertexArray)1043 void Context::deleteVertexArray(GLuint vertexArray)
1044 {
1045 // [OpenGL ES 3.0.2] section 2.10 page 43:
1046 // If a vertex array object that is currently bound is deleted, the binding
1047 // for that object reverts to zero and the default vertex array becomes current.
1048 if(getCurrentVertexArray()->name == vertexArray)
1049 {
1050 bindVertexArray(0);
1051 }
1052
1053 VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
1054
1055 if(vertexArrayObject)
1056 {
1057 delete vertexArrayObject;
1058 }
1059 }
1060
deleteFenceSync(GLsync fenceSync)1061 void Context::deleteFenceSync(GLsync fenceSync)
1062 {
1063 // The spec specifies the underlying Fence object is not deleted until all current
1064 // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1065 // and since our API is currently designed for being called from a single thread, we can delete
1066 // the fence immediately.
1067 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
1068 }
1069
deleteTransformFeedback(GLuint transformFeedback)1070 void Context::deleteTransformFeedback(GLuint transformFeedback)
1071 {
1072 TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
1073
1074 // Detach if currently bound.
1075 if(mState.transformFeedback == transformFeedback)
1076 {
1077 mState.transformFeedback = 0;
1078 }
1079
1080 if(transformFeedbackObject)
1081 {
1082 delete transformFeedbackObject;
1083 }
1084 }
1085
deleteSampler(GLuint sampler)1086 void Context::deleteSampler(GLuint sampler)
1087 {
1088 detachSampler(sampler);
1089
1090 mResourceManager->deleteSampler(sampler);
1091 }
1092
getBuffer(GLuint handle) const1093 Buffer *Context::getBuffer(GLuint handle) const
1094 {
1095 return mResourceManager->getBuffer(handle);
1096 }
1097
getShader(GLuint handle) const1098 Shader *Context::getShader(GLuint handle) const
1099 {
1100 return mResourceManager->getShader(handle);
1101 }
1102
getProgram(GLuint handle) const1103 Program *Context::getProgram(GLuint handle) const
1104 {
1105 return mResourceManager->getProgram(handle);
1106 }
1107
getTexture(GLuint handle) const1108 Texture *Context::getTexture(GLuint handle) const
1109 {
1110 return mResourceManager->getTexture(handle);
1111 }
1112
getRenderbuffer(GLuint handle) const1113 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1114 {
1115 return mResourceManager->getRenderbuffer(handle);
1116 }
1117
getReadFramebuffer() const1118 Framebuffer *Context::getReadFramebuffer() const
1119 {
1120 return getFramebuffer(mState.readFramebuffer);
1121 }
1122
getDrawFramebuffer() const1123 Framebuffer *Context::getDrawFramebuffer() const
1124 {
1125 return getFramebuffer(mState.drawFramebuffer);
1126 }
1127
bindArrayBuffer(unsigned int buffer)1128 void Context::bindArrayBuffer(unsigned int buffer)
1129 {
1130 mResourceManager->checkBufferAllocation(buffer);
1131
1132 mState.arrayBuffer = getBuffer(buffer);
1133 }
1134
bindElementArrayBuffer(unsigned int buffer)1135 void Context::bindElementArrayBuffer(unsigned int buffer)
1136 {
1137 mResourceManager->checkBufferAllocation(buffer);
1138
1139 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1140 }
1141
bindCopyReadBuffer(GLuint buffer)1142 void Context::bindCopyReadBuffer(GLuint buffer)
1143 {
1144 mResourceManager->checkBufferAllocation(buffer);
1145
1146 mState.copyReadBuffer = getBuffer(buffer);
1147 }
1148
bindCopyWriteBuffer(GLuint buffer)1149 void Context::bindCopyWriteBuffer(GLuint buffer)
1150 {
1151 mResourceManager->checkBufferAllocation(buffer);
1152
1153 mState.copyWriteBuffer = getBuffer(buffer);
1154 }
1155
bindPixelPackBuffer(GLuint buffer)1156 void Context::bindPixelPackBuffer(GLuint buffer)
1157 {
1158 mResourceManager->checkBufferAllocation(buffer);
1159
1160 mState.pixelPackBuffer = getBuffer(buffer);
1161 }
1162
bindPixelUnpackBuffer(GLuint buffer)1163 void Context::bindPixelUnpackBuffer(GLuint buffer)
1164 {
1165 mResourceManager->checkBufferAllocation(buffer);
1166
1167 mState.pixelUnpackBuffer = getBuffer(buffer);
1168 }
1169
bindTransformFeedbackBuffer(GLuint buffer)1170 void Context::bindTransformFeedbackBuffer(GLuint buffer)
1171 {
1172 mResourceManager->checkBufferAllocation(buffer);
1173
1174 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1175
1176 if(transformFeedback)
1177 {
1178 transformFeedback->setGenericBuffer(getBuffer(buffer));
1179 }
1180 }
1181
bindTexture(TextureType type,GLuint texture)1182 void Context::bindTexture(TextureType type, GLuint texture)
1183 {
1184 mResourceManager->checkTextureAllocation(texture, type);
1185
1186 mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
1187 }
1188
bindReadFramebuffer(GLuint framebuffer)1189 void Context::bindReadFramebuffer(GLuint framebuffer)
1190 {
1191 if(!getFramebuffer(framebuffer))
1192 {
1193 if(framebuffer == 0)
1194 {
1195 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1196 }
1197 else
1198 {
1199 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1200 }
1201 }
1202
1203 mState.readFramebuffer = framebuffer;
1204 }
1205
bindDrawFramebuffer(GLuint framebuffer)1206 void Context::bindDrawFramebuffer(GLuint framebuffer)
1207 {
1208 if(!getFramebuffer(framebuffer))
1209 {
1210 if(framebuffer == 0)
1211 {
1212 mFramebufferNameSpace.insert(framebuffer, new DefaultFramebuffer());
1213 }
1214 else
1215 {
1216 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1217 }
1218 }
1219
1220 mState.drawFramebuffer = framebuffer;
1221 }
1222
bindRenderbuffer(GLuint renderbuffer)1223 void Context::bindRenderbuffer(GLuint renderbuffer)
1224 {
1225 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1226
1227 mState.renderbuffer = getRenderbuffer(renderbuffer);
1228 }
1229
bindVertexArray(GLuint array)1230 void Context::bindVertexArray(GLuint array)
1231 {
1232 VertexArray *vertexArray = getVertexArray(array);
1233
1234 if(!vertexArray)
1235 {
1236 vertexArray = new VertexArray(array);
1237 mVertexArrayNameSpace.insert(array, vertexArray);
1238 }
1239
1240 mState.vertexArray = array;
1241 }
1242
bindGenericUniformBuffer(GLuint buffer)1243 void Context::bindGenericUniformBuffer(GLuint buffer)
1244 {
1245 mResourceManager->checkBufferAllocation(buffer);
1246
1247 mState.genericUniformBuffer = getBuffer(buffer);
1248 }
1249
bindIndexedUniformBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1250 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1251 {
1252 mResourceManager->checkBufferAllocation(buffer);
1253
1254 Buffer* bufferObject = getBuffer(buffer);
1255 mState.uniformBuffers[index].set(bufferObject, static_cast<int>(offset), static_cast<int>(size));
1256 }
1257
bindGenericTransformFeedbackBuffer(GLuint buffer)1258 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1259 {
1260 mResourceManager->checkBufferAllocation(buffer);
1261
1262 getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
1263 }
1264
bindIndexedTransformFeedbackBuffer(GLuint buffer,GLuint index,GLintptr offset,GLsizeiptr size)1265 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1266 {
1267 mResourceManager->checkBufferAllocation(buffer);
1268
1269 Buffer* bufferObject = getBuffer(buffer);
1270 getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1271 }
1272
bindTransformFeedback(GLuint id)1273 void Context::bindTransformFeedback(GLuint id)
1274 {
1275 if(!getTransformFeedback(id))
1276 {
1277 mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
1278 }
1279
1280 mState.transformFeedback = id;
1281 }
1282
bindSampler(GLuint unit,GLuint sampler)1283 bool Context::bindSampler(GLuint unit, GLuint sampler)
1284 {
1285 mResourceManager->checkSamplerAllocation(sampler);
1286
1287 Sampler* samplerObject = getSampler(sampler);
1288
1289 mState.sampler[unit] = samplerObject;
1290
1291 return !!samplerObject;
1292 }
1293
useProgram(GLuint program)1294 void Context::useProgram(GLuint program)
1295 {
1296 GLuint priorProgram = mState.currentProgram;
1297 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
1298
1299 if(priorProgram != program)
1300 {
1301 Program *newProgram = mResourceManager->getProgram(program);
1302 Program *oldProgram = mResourceManager->getProgram(priorProgram);
1303
1304 if(newProgram)
1305 {
1306 newProgram->addRef();
1307 }
1308
1309 if(oldProgram)
1310 {
1311 oldProgram->release();
1312 }
1313 }
1314 }
1315
beginQuery(GLenum target,GLuint query)1316 void Context::beginQuery(GLenum target, GLuint query)
1317 {
1318 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1319 // of zero, if the active query object name for <target> is non-zero (for the
1320 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1321 // the active query for either target is non-zero), if <id> is the name of an
1322 // existing query object whose type does not match <target>, or if <id> is the
1323 // active query object name for any query type, the error INVALID_OPERATION is
1324 // generated.
1325
1326 // Ensure no other queries are active
1327 // NOTE: If other queries than occlusion are supported, we will need to check
1328 // separately that:
1329 // a) The query ID passed is not the current active query for any target/type
1330 // b) There are no active queries for the requested target (and in the case
1331 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1332 // no query may be active for either if glBeginQuery targets either.
1333 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1334 {
1335 if(mState.activeQuery[i])
1336 {
1337 switch(mState.activeQuery[i]->getType())
1338 {
1339 case GL_ANY_SAMPLES_PASSED_EXT:
1340 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1341 if((target == GL_ANY_SAMPLES_PASSED_EXT) ||
1342 (target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT))
1343 {
1344 return error(GL_INVALID_OPERATION);
1345 }
1346 break;
1347 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1348 if(target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
1349 {
1350 return error(GL_INVALID_OPERATION);
1351 }
1352 break;
1353 default:
1354 break;
1355 }
1356 }
1357 }
1358
1359 QueryType qType;
1360 switch(target)
1361 {
1362 case GL_ANY_SAMPLES_PASSED_EXT:
1363 qType = QUERY_ANY_SAMPLES_PASSED;
1364 break;
1365 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1366 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1367 break;
1368 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1369 qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1370 break;
1371 default:
1372 UNREACHABLE(target);
1373 return error(GL_INVALID_ENUM);
1374 }
1375
1376 Query *queryObject = createQuery(query, target);
1377
1378 // Check that name was obtained with glGenQueries
1379 if(!queryObject)
1380 {
1381 return error(GL_INVALID_OPERATION);
1382 }
1383
1384 // Check for type mismatch
1385 if(queryObject->getType() != target)
1386 {
1387 return error(GL_INVALID_OPERATION);
1388 }
1389
1390 // Set query as active for specified target
1391 mState.activeQuery[qType] = queryObject;
1392
1393 // Begin query
1394 queryObject->begin();
1395 }
1396
endQuery(GLenum target)1397 void Context::endQuery(GLenum target)
1398 {
1399 QueryType qType;
1400
1401 switch(target)
1402 {
1403 case GL_ANY_SAMPLES_PASSED_EXT: qType = QUERY_ANY_SAMPLES_PASSED; break;
1404 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; break;
1405 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1406 default: UNREACHABLE(target); return;
1407 }
1408
1409 Query *queryObject = mState.activeQuery[qType];
1410
1411 if(!queryObject)
1412 {
1413 return error(GL_INVALID_OPERATION);
1414 }
1415
1416 queryObject->end();
1417
1418 mState.activeQuery[qType] = nullptr;
1419 }
1420
setFramebufferZero(Framebuffer * buffer)1421 void Context::setFramebufferZero(Framebuffer *buffer)
1422 {
1423 delete mFramebufferNameSpace.remove(0);
1424 mFramebufferNameSpace.insert(0, buffer);
1425 }
1426
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1427 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1428 {
1429 Renderbuffer *renderbufferObject = mState.renderbuffer;
1430 renderbufferObject->setStorage(renderbuffer);
1431 }
1432
getFramebuffer(unsigned int handle) const1433 Framebuffer *Context::getFramebuffer(unsigned int handle) const
1434 {
1435 return mFramebufferNameSpace.find(handle);
1436 }
1437
getFence(unsigned int handle) const1438 Fence *Context::getFence(unsigned int handle) const
1439 {
1440 return mFenceNameSpace.find(handle);
1441 }
1442
getFenceSync(GLsync handle) const1443 FenceSync *Context::getFenceSync(GLsync handle) const
1444 {
1445 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1446 }
1447
getQuery(unsigned int handle) const1448 Query *Context::getQuery(unsigned int handle) const
1449 {
1450 return mQueryNameSpace.find(handle);
1451 }
1452
createQuery(unsigned int handle,GLenum type)1453 Query *Context::createQuery(unsigned int handle, GLenum type)
1454 {
1455 if(!mQueryNameSpace.isReserved(handle))
1456 {
1457 return nullptr;
1458 }
1459 else
1460 {
1461 Query *query = mQueryNameSpace.find(handle);
1462 if(!query)
1463 {
1464 query = new Query(handle, type);
1465 query->addRef();
1466 mQueryNameSpace.insert(handle, query);
1467 }
1468
1469 return query;
1470 }
1471 }
1472
getVertexArray(GLuint array) const1473 VertexArray *Context::getVertexArray(GLuint array) const
1474 {
1475 return mVertexArrayNameSpace.find(array);
1476 }
1477
getCurrentVertexArray() const1478 VertexArray *Context::getCurrentVertexArray() const
1479 {
1480 return getVertexArray(mState.vertexArray);
1481 }
1482
isVertexArray(GLuint array) const1483 bool Context::isVertexArray(GLuint array) const
1484 {
1485 return mVertexArrayNameSpace.isReserved(array);
1486 }
1487
hasZeroDivisor() const1488 bool Context::hasZeroDivisor() const
1489 {
1490 // Verify there is at least one active attribute with a divisor of zero
1491 es2::Program *programObject = getCurrentProgram();
1492 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1493 {
1494 bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1495 if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1496 {
1497 return true;
1498 }
1499 }
1500
1501 return false;
1502 }
1503
getTransformFeedback(GLuint transformFeedback) const1504 TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1505 {
1506 return mTransformFeedbackNameSpace.find(transformFeedback);
1507 }
1508
isTransformFeedback(GLuint array) const1509 bool Context::isTransformFeedback(GLuint array) const
1510 {
1511 return mTransformFeedbackNameSpace.isReserved(array);
1512 }
1513
getSampler(GLuint sampler) const1514 Sampler *Context::getSampler(GLuint sampler) const
1515 {
1516 return mResourceManager->getSampler(sampler);
1517 }
1518
isSampler(GLuint sampler) const1519 bool Context::isSampler(GLuint sampler) const
1520 {
1521 return mResourceManager->isSampler(sampler);
1522 }
1523
getArrayBuffer() const1524 Buffer *Context::getArrayBuffer() const
1525 {
1526 return mState.arrayBuffer;
1527 }
1528
getElementArrayBuffer() const1529 Buffer *Context::getElementArrayBuffer() const
1530 {
1531 return getCurrentVertexArray()->getElementArrayBuffer();
1532 }
1533
getCopyReadBuffer() const1534 Buffer *Context::getCopyReadBuffer() const
1535 {
1536 return mState.copyReadBuffer;
1537 }
1538
getCopyWriteBuffer() const1539 Buffer *Context::getCopyWriteBuffer() const
1540 {
1541 return mState.copyWriteBuffer;
1542 }
1543
getPixelPackBuffer() const1544 Buffer *Context::getPixelPackBuffer() const
1545 {
1546 return mState.pixelPackBuffer;
1547 }
1548
getPixelUnpackBuffer() const1549 Buffer *Context::getPixelUnpackBuffer() const
1550 {
1551 return mState.pixelUnpackBuffer;
1552 }
1553
getGenericUniformBuffer() const1554 Buffer *Context::getGenericUniformBuffer() const
1555 {
1556 return mState.genericUniformBuffer;
1557 }
1558
getRequiredBufferSize(GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type) const1559 GLsizei Context::getRequiredBufferSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type) const
1560 {
1561 GLsizei inputWidth = (mState.unpackParameters.rowLength == 0) ? width : mState.unpackParameters.rowLength;
1562 GLsizei inputPitch = gl::ComputePitch(inputWidth, format, type, mState.unpackParameters.alignment);
1563 GLsizei inputHeight = (mState.unpackParameters.imageHeight == 0) ? height : mState.unpackParameters.imageHeight;
1564 return inputPitch * inputHeight * depth;
1565 }
1566
getPixels(const GLvoid ** pixels,GLenum type,GLsizei imageSize) const1567 GLenum Context::getPixels(const GLvoid **pixels, GLenum type, GLsizei imageSize) const
1568 {
1569 if(mState.pixelUnpackBuffer)
1570 {
1571 ASSERT(mState.pixelUnpackBuffer->name != 0);
1572
1573 if(mState.pixelUnpackBuffer->isMapped())
1574 {
1575 return GL_INVALID_OPERATION;
1576 }
1577
1578 size_t offset = static_cast<size_t>((ptrdiff_t)(*pixels));
1579
1580 if(offset % GetTypeSize(type) != 0)
1581 {
1582 return GL_INVALID_OPERATION;
1583 }
1584
1585 if(offset > mState.pixelUnpackBuffer->size())
1586 {
1587 return GL_INVALID_OPERATION;
1588 }
1589
1590 if(mState.pixelUnpackBuffer->size() - offset < static_cast<size_t>(imageSize))
1591 {
1592 return GL_INVALID_OPERATION;
1593 }
1594
1595 *pixels = static_cast<const unsigned char*>(mState.pixelUnpackBuffer->data()) + offset;
1596 }
1597
1598 return GL_NO_ERROR;
1599 }
1600
getBuffer(GLenum target,es2::Buffer ** buffer) const1601 bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1602 {
1603 switch(target)
1604 {
1605 case GL_ARRAY_BUFFER:
1606 *buffer = getArrayBuffer();
1607 break;
1608 case GL_ELEMENT_ARRAY_BUFFER:
1609 *buffer = getElementArrayBuffer();
1610 break;
1611 case GL_COPY_READ_BUFFER:
1612 *buffer = getCopyReadBuffer();
1613 break;
1614 case GL_COPY_WRITE_BUFFER:
1615 *buffer = getCopyWriteBuffer();
1616 break;
1617 case GL_PIXEL_PACK_BUFFER:
1618 *buffer = getPixelPackBuffer();
1619 break;
1620 case GL_PIXEL_UNPACK_BUFFER:
1621 *buffer = getPixelUnpackBuffer();
1622 break;
1623 case GL_TRANSFORM_FEEDBACK_BUFFER:
1624 {
1625 TransformFeedback* transformFeedback = getTransformFeedback();
1626 *buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
1627 }
1628 break;
1629 case GL_UNIFORM_BUFFER:
1630 *buffer = getGenericUniformBuffer();
1631 break;
1632 default:
1633 return false;
1634 }
1635 return true;
1636 }
1637
getTransformFeedback() const1638 TransformFeedback *Context::getTransformFeedback() const
1639 {
1640 return getTransformFeedback(mState.transformFeedback);
1641 }
1642
getCurrentProgram() const1643 Program *Context::getCurrentProgram() const
1644 {
1645 return mResourceManager->getProgram(mState.currentProgram);
1646 }
1647
getTexture2D() const1648 Texture2D *Context::getTexture2D() const
1649 {
1650 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1651 }
1652
getTexture2D(GLenum target) const1653 Texture2D *Context::getTexture2D(GLenum target) const
1654 {
1655 switch(target)
1656 {
1657 case GL_TEXTURE_2D: return getTexture2D();
1658 case GL_TEXTURE_RECTANGLE_ARB: return getTexture2DRect();
1659 case GL_TEXTURE_EXTERNAL_OES: return getTextureExternal();
1660 default: UNREACHABLE(target);
1661 }
1662
1663 return nullptr;
1664 }
1665
getTexture3D() const1666 Texture3D *Context::getTexture3D() const
1667 {
1668 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1669 }
1670
getTexture2DArray() const1671 Texture2DArray *Context::getTexture2DArray() const
1672 {
1673 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1674 }
1675
getTextureCubeMap() const1676 TextureCubeMap *Context::getTextureCubeMap() const
1677 {
1678 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1679 }
1680
getTexture2DRect() const1681 Texture2DRect *Context::getTexture2DRect() const
1682 {
1683 return static_cast<Texture2DRect*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_RECT));
1684 }
1685
getTextureExternal() const1686 TextureExternal *Context::getTextureExternal() const
1687 {
1688 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1689 }
1690
getSamplerTexture(unsigned int sampler,TextureType type) const1691 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1692 {
1693 GLuint texid = mState.samplerTexture[type][sampler].name();
1694
1695 if(texid == 0) // Special case: 0 refers to different initial textures based on the target
1696 {
1697 switch(type)
1698 {
1699 case TEXTURE_2D: return mTexture2DZero;
1700 case TEXTURE_3D: return mTexture3DZero;
1701 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1702 case TEXTURE_CUBE: return mTextureCubeMapZero;
1703 case TEXTURE_2D_RECT: return mTexture2DRectZero;
1704 case TEXTURE_EXTERNAL: return mTextureExternalZero;
1705 default: UNREACHABLE(type);
1706 }
1707 }
1708
1709 return mState.samplerTexture[type][sampler];
1710 }
1711
samplerParameteri(GLuint sampler,GLenum pname,GLint param)1712 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1713 {
1714 mResourceManager->checkSamplerAllocation(sampler);
1715
1716 Sampler *samplerObject = getSampler(sampler);
1717 ASSERT(samplerObject);
1718
1719 switch(pname)
1720 {
1721 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(param)); break;
1722 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(param)); break;
1723 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(param)); break;
1724 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(param)); break;
1725 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(param)); break;
1726 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast<GLfloat>(param)); break;
1727 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast<GLfloat>(param)); break;
1728 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(param)); break;
1729 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(param)); break;
1730 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(static_cast<GLfloat>(param)); break;
1731 default: UNREACHABLE(pname); break;
1732 }
1733 }
1734
samplerParameterf(GLuint sampler,GLenum pname,GLfloat param)1735 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1736 {
1737 mResourceManager->checkSamplerAllocation(sampler);
1738
1739 Sampler *samplerObject = getSampler(sampler);
1740 ASSERT(samplerObject);
1741
1742 switch(pname)
1743 {
1744 case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast<GLenum>(roundf(param))); break;
1745 case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast<GLenum>(roundf(param))); break;
1746 case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast<GLenum>(roundf(param))); break;
1747 case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast<GLenum>(roundf(param))); break;
1748 case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast<GLenum>(roundf(param))); break;
1749 case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break;
1750 case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break;
1751 case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast<GLenum>(roundf(param))); break;
1752 case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast<GLenum>(roundf(param))); break;
1753 case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(param); break;
1754 default: UNREACHABLE(pname); break;
1755 }
1756 }
1757
getSamplerParameteri(GLuint sampler,GLenum pname)1758 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1759 {
1760 mResourceManager->checkSamplerAllocation(sampler);
1761
1762 Sampler *samplerObject = getSampler(sampler);
1763 ASSERT(samplerObject);
1764
1765 switch(pname)
1766 {
1767 case GL_TEXTURE_MIN_FILTER: return static_cast<GLint>(samplerObject->getMinFilter());
1768 case GL_TEXTURE_MAG_FILTER: return static_cast<GLint>(samplerObject->getMagFilter());
1769 case GL_TEXTURE_WRAP_S: return static_cast<GLint>(samplerObject->getWrapS());
1770 case GL_TEXTURE_WRAP_T: return static_cast<GLint>(samplerObject->getWrapT());
1771 case GL_TEXTURE_WRAP_R: return static_cast<GLint>(samplerObject->getWrapR());
1772 case GL_TEXTURE_MIN_LOD: return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1773 case GL_TEXTURE_MAX_LOD: return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1774 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLint>(samplerObject->getCompareMode());
1775 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLint>(samplerObject->getCompareFunc());
1776 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast<GLint>(samplerObject->getMaxAnisotropy());
1777 default: UNREACHABLE(pname); return 0;
1778 }
1779 }
1780
getSamplerParameterf(GLuint sampler,GLenum pname)1781 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1782 {
1783 mResourceManager->checkSamplerAllocation(sampler);
1784
1785 Sampler *samplerObject = getSampler(sampler);
1786 ASSERT(samplerObject);
1787
1788 switch(pname)
1789 {
1790 case GL_TEXTURE_MIN_FILTER: return static_cast<GLfloat>(samplerObject->getMinFilter());
1791 case GL_TEXTURE_MAG_FILTER: return static_cast<GLfloat>(samplerObject->getMagFilter());
1792 case GL_TEXTURE_WRAP_S: return static_cast<GLfloat>(samplerObject->getWrapS());
1793 case GL_TEXTURE_WRAP_T: return static_cast<GLfloat>(samplerObject->getWrapT());
1794 case GL_TEXTURE_WRAP_R: return static_cast<GLfloat>(samplerObject->getWrapR());
1795 case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod();
1796 case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod();
1797 case GL_TEXTURE_COMPARE_MODE: return static_cast<GLfloat>(samplerObject->getCompareMode());
1798 case GL_TEXTURE_COMPARE_FUNC: return static_cast<GLfloat>(samplerObject->getCompareFunc());
1799 case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy();
1800 default: UNREACHABLE(pname); return 0;
1801 }
1802 }
1803
getBooleanv(GLenum pname,GLboolean * params) const1804 bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1805 {
1806 switch(pname)
1807 {
1808 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1809 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1810 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
1811 case GL_COLOR_WRITEMASK:
1812 params[0] = mState.colorMaskRed;
1813 params[1] = mState.colorMaskGreen;
1814 params[2] = mState.colorMaskBlue;
1815 params[3] = mState.colorMaskAlpha;
1816 break;
1817 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break;
1818 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break;
1819 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1820 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break;
1821 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break;
1822 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break;
1823 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break;
1824 case GL_BLEND: *params = mState.blendEnabled; break;
1825 case GL_DITHER: *params = mState.ditherEnabled; break;
1826 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1827 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscardEnabled; break;
1828 case GL_TRANSFORM_FEEDBACK_ACTIVE:
1829 {
1830 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1831 if(transformFeedback)
1832 {
1833 *params = transformFeedback->isActive();
1834 break;
1835 }
1836 else return false;
1837 }
1838 case GL_TRANSFORM_FEEDBACK_PAUSED:
1839 {
1840 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1841 if(transformFeedback)
1842 {
1843 *params = transformFeedback->isPaused();
1844 break;
1845 }
1846 else return false;
1847 }
1848 default:
1849 return false;
1850 }
1851
1852 return true;
1853 }
1854
getFloatv(GLenum pname,GLfloat * params) const1855 bool Context::getFloatv(GLenum pname, GLfloat *params) const
1856 {
1857 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1858 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1859 // GetIntegerv as its native query function. As it would require conversion in any
1860 // case, this should make no difference to the calling application.
1861 switch(pname)
1862 {
1863 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1864 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1865 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1866 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
1867 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
1868 case GL_ALIASED_LINE_WIDTH_RANGE:
1869 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1870 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1871 break;
1872 case GL_ALIASED_POINT_SIZE_RANGE:
1873 params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1874 params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1875 break;
1876 case GL_DEPTH_RANGE:
1877 params[0] = mState.zNear;
1878 params[1] = mState.zFar;
1879 break;
1880 case GL_COLOR_CLEAR_VALUE:
1881 params[0] = mState.colorClearValue.red;
1882 params[1] = mState.colorClearValue.green;
1883 params[2] = mState.colorClearValue.blue;
1884 params[3] = mState.colorClearValue.alpha;
1885 break;
1886 case GL_BLEND_COLOR:
1887 params[0] = mState.blendColor.red;
1888 params[1] = mState.blendColor.green;
1889 params[2] = mState.blendColor.blue;
1890 params[3] = mState.blendColor.alpha;
1891 break;
1892 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1893 *params = MAX_TEXTURE_MAX_ANISOTROPY;
1894 break;
1895 default:
1896 return false;
1897 }
1898
1899 return true;
1900 }
1901
1902 template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1903 template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1904
getIntegerv(GLenum pname,T * params) const1905 template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1906 {
1907 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1908 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1909 // GetIntegerv as its native query function. As it would require conversion in any
1910 // case, this should make no difference to the calling application. You may find it in
1911 // Context::getFloatv.
1912 switch(pname)
1913 {
1914 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; return true;
1915 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; return true;
1916 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; return true;
1917 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; return true;
1918 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; return true;
1919 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; return true;
1920 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; return true;
1921 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; return true;
1922 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; return true;
1923 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ return true;
1924 case GL_ARRAY_BUFFER_BINDING: *params = getArrayBufferName(); return true;
1925 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getElementArrayBufferName(); return true;
1926 // case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1927 case GL_DRAW_FRAMEBUFFER_BINDING: *params = mState.drawFramebuffer; return true;
1928 case GL_READ_FRAMEBUFFER_BINDING: *params = mState.readFramebuffer; return true;
1929 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); return true;
1930 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; return true;
1931 case GL_PACK_ALIGNMENT: *params = mState.packParameters.alignment; return true;
1932 case GL_UNPACK_ALIGNMENT: *params = mState.unpackParameters.alignment; return true;
1933 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; return true;
1934 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; return true;
1935 case GL_TEXTURE_FILTERING_HINT_CHROMIUM: *params = mState.textureFilteringHint; return true;
1936 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); return true;
1937 case GL_STENCIL_FUNC: *params = mState.stencilFunc; return true;
1938 case GL_STENCIL_REF: *params = mState.stencilRef; return true;
1939 case GL_STENCIL_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilMask); return true;
1940 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; return true;
1941 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; return true;
1942 case GL_STENCIL_BACK_VALUE_MASK: *params = sw::clampToSignedInt(mState.stencilBackMask); return true;
1943 case GL_STENCIL_FAIL: *params = mState.stencilFail; return true;
1944 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; return true;
1945 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; return true;
1946 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; return true;
1947 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; return true;
1948 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; return true;
1949 case GL_DEPTH_FUNC: *params = mState.depthFunc; return true;
1950 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; return true;
1951 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; return true;
1952 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; return true;
1953 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; return true;
1954 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; return true;
1955 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; return true;
1956 case GL_STENCIL_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilWritemask); return true;
1957 case GL_STENCIL_BACK_WRITEMASK: *params = sw::clampToSignedInt(mState.stencilBackWritemask); return true;
1958 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; return true;
1959 case GL_SUBPIXEL_BITS: *params = 4; return true;
1960 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
1961 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; return true;
1962 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; return true;
1963 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; return true;
1964 case GL_MAX_SAMPLES: *params = IMPLEMENTATION_MAX_SAMPLES; return true;
1965 case GL_SAMPLE_BUFFERS:
1966 case GL_SAMPLES:
1967 {
1968 Framebuffer *framebuffer = getDrawFramebuffer();
1969 int width, height, samples;
1970
1971 if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE))
1972 {
1973 switch(pname)
1974 {
1975 case GL_SAMPLE_BUFFERS:
1976 if(samples > 1)
1977 {
1978 *params = 1;
1979 }
1980 else
1981 {
1982 *params = 0;
1983 }
1984 break;
1985 case GL_SAMPLES:
1986 *params = samples;
1987 break;
1988 }
1989 }
1990 else
1991 {
1992 *params = 0;
1993 }
1994 }
1995 return true;
1996 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1997 {
1998 Framebuffer *framebuffer = getReadFramebuffer();
1999 if(framebuffer)
2000 {
2001 *params = framebuffer->getImplementationColorReadType();
2002 }
2003 else
2004 {
2005 return error(GL_INVALID_OPERATION, true);
2006 }
2007 }
2008 return true;
2009 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2010 {
2011 Framebuffer *framebuffer = getReadFramebuffer();
2012 if(framebuffer)
2013 {
2014 *params = framebuffer->getImplementationColorReadFormat();
2015 }
2016 else
2017 {
2018 return error(GL_INVALID_OPERATION, true);
2019 }
2020 }
2021 return true;
2022 case GL_MAX_VIEWPORT_DIMS:
2023 {
2024 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2025 params[0] = maxDimension;
2026 params[1] = maxDimension;
2027 }
2028 return true;
2029 case GL_COMPRESSED_TEXTURE_FORMATS:
2030 {
2031 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2032 {
2033 params[i] = compressedTextureFormats[i];
2034 }
2035 }
2036 return true;
2037 case GL_VIEWPORT:
2038 params[0] = mState.viewportX;
2039 params[1] = mState.viewportY;
2040 params[2] = mState.viewportWidth;
2041 params[3] = mState.viewportHeight;
2042 return true;
2043 case GL_SCISSOR_BOX:
2044 params[0] = mState.scissorX;
2045 params[1] = mState.scissorY;
2046 params[2] = mState.scissorWidth;
2047 params[3] = mState.scissorHeight;
2048 return true;
2049 case GL_CULL_FACE_MODE: *params = mState.cullMode; return true;
2050 case GL_FRONT_FACE: *params = mState.frontFace; return true;
2051 case GL_RED_BITS:
2052 case GL_GREEN_BITS:
2053 case GL_BLUE_BITS:
2054 case GL_ALPHA_BITS:
2055 {
2056 Framebuffer *framebuffer = getDrawFramebuffer();
2057 Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer(0) : nullptr;
2058
2059 if(colorbuffer)
2060 {
2061 switch(pname)
2062 {
2063 case GL_RED_BITS: *params = colorbuffer->getRedSize(); return true;
2064 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); return true;
2065 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); return true;
2066 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); return true;
2067 }
2068 }
2069 else
2070 {
2071 *params = 0;
2072 }
2073 }
2074 return true;
2075 case GL_DEPTH_BITS:
2076 {
2077 Framebuffer *framebuffer = getDrawFramebuffer();
2078 Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
2079
2080 if(depthbuffer)
2081 {
2082 *params = depthbuffer->getDepthSize();
2083 }
2084 else
2085 {
2086 *params = 0;
2087 }
2088 }
2089 return true;
2090 case GL_STENCIL_BITS:
2091 {
2092 Framebuffer *framebuffer = getDrawFramebuffer();
2093 Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
2094
2095 if(stencilbuffer)
2096 {
2097 *params = stencilbuffer->getStencilSize();
2098 }
2099 else
2100 {
2101 *params = 0;
2102 }
2103 }
2104 return true;
2105 case GL_TEXTURE_BINDING_2D:
2106 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2107 {
2108 error(GL_INVALID_OPERATION);
2109 return false;
2110 }
2111
2112 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2113 return true;
2114 case GL_TEXTURE_BINDING_CUBE_MAP:
2115 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2116 {
2117 error(GL_INVALID_OPERATION);
2118 return false;
2119 }
2120
2121 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2122 return true;
2123 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2124 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2125 {
2126 error(GL_INVALID_OPERATION);
2127 return false;
2128 }
2129
2130 *params = mState.samplerTexture[TEXTURE_2D_RECT][mState.activeSampler].name();
2131 return true;
2132 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2133 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2134 {
2135 error(GL_INVALID_OPERATION);
2136 return false;
2137 }
2138
2139 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2140 return true;
2141 case GL_TEXTURE_BINDING_3D_OES:
2142 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2143 {
2144 error(GL_INVALID_OPERATION);
2145 return false;
2146 }
2147
2148 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2149 return true;
2150 case GL_DRAW_BUFFER0:
2151 case GL_DRAW_BUFFER1:
2152 case GL_DRAW_BUFFER2:
2153 case GL_DRAW_BUFFER3:
2154 case GL_DRAW_BUFFER4:
2155 case GL_DRAW_BUFFER5:
2156 case GL_DRAW_BUFFER6:
2157 case GL_DRAW_BUFFER7:
2158 case GL_DRAW_BUFFER8:
2159 case GL_DRAW_BUFFER9:
2160 case GL_DRAW_BUFFER10:
2161 case GL_DRAW_BUFFER11:
2162 case GL_DRAW_BUFFER12:
2163 case GL_DRAW_BUFFER13:
2164 case GL_DRAW_BUFFER14:
2165 case GL_DRAW_BUFFER15:
2166 if((pname - GL_DRAW_BUFFER0) < MAX_DRAW_BUFFERS)
2167 {
2168 Framebuffer* framebuffer = getDrawFramebuffer();
2169 *params = framebuffer ? framebuffer->getDrawBuffer(pname - GL_DRAW_BUFFER0) : GL_NONE;
2170 }
2171 else
2172 {
2173 return false;
2174 }
2175 return true;
2176 case GL_MAX_DRAW_BUFFERS:
2177 *params = MAX_DRAW_BUFFERS;
2178 return true;
2179 case GL_MAX_COLOR_ATTACHMENTS: // Note: MAX_COLOR_ATTACHMENTS_EXT added by GL_EXT_draw_buffers
2180 *params = MAX_COLOR_ATTACHMENTS;
2181 return true;
2182 case GL_TEXTURE_BINDING_2D_ARRAY:
2183 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2184 {
2185 error(GL_INVALID_OPERATION);
2186 return false;
2187 }
2188
2189 *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
2190 return true;
2191 case GL_COPY_READ_BUFFER_BINDING:
2192 *params = mState.copyReadBuffer.name();
2193 return true;
2194 case GL_COPY_WRITE_BUFFER_BINDING:
2195 *params = mState.copyWriteBuffer.name();
2196 return true;
2197 case GL_MAJOR_VERSION:
2198 *params = 3;
2199 return true;
2200 case GL_MINOR_VERSION:
2201 *params = 0;
2202 return true;
2203 case GL_MAX_3D_TEXTURE_SIZE:
2204 *params = IMPLEMENTATION_MAX_3D_TEXTURE_SIZE;
2205 return true;
2206 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2207 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2208 return true;
2209 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2210 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2211 return true;
2212 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2213 *params = MAX_VERTEX_UNIFORM_BLOCKS + MAX_FRAGMENT_UNIFORM_BLOCKS;
2214 return true;
2215 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2216 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2217 return true;
2218 case GL_MAX_ELEMENT_INDEX:
2219 *params = MAX_ELEMENT_INDEX;
2220 return true;
2221 case GL_MAX_ELEMENTS_INDICES:
2222 *params = MAX_ELEMENTS_INDICES;
2223 return true;
2224 case GL_MAX_ELEMENTS_VERTICES:
2225 *params = MAX_ELEMENTS_VERTICES;
2226 return true;
2227 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2228 *params = MAX_FRAGMENT_INPUT_VECTORS * 4;
2229 return true;
2230 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2231 *params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2232 return true;
2233 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2234 *params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2235 return true;
2236 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2237 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2238 // In any case, any behavior outside the specified range is valid since the spec mentions:
2239 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2240 // "If any of the offset values are outside the range of the implementation-defined values
2241 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2242 // undefined."
2243 *params = MAX_PROGRAM_TEXEL_OFFSET;
2244 return true;
2245 case GL_MAX_SERVER_WAIT_TIMEOUT:
2246 *params = 0;
2247 return true;
2248 case GL_MAX_TEXTURE_LOD_BIAS:
2249 *params = MAX_TEXTURE_LOD_BIAS;
2250 return true;
2251 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2252 *params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
2253 return true;
2254 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2255 *params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2256 return true;
2257 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2258 *params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
2259 return true;
2260 case GL_MAX_UNIFORM_BLOCK_SIZE:
2261 *params = MAX_UNIFORM_BLOCK_SIZE;
2262 return true;
2263 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2264 *params = MAX_UNIFORM_BUFFER_BINDINGS;
2265 return true;
2266 case GL_MAX_VARYING_COMPONENTS:
2267 *params = MAX_VARYING_VECTORS * 4;
2268 return true;
2269 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2270 *params = MAX_VERTEX_OUTPUT_VECTORS * 4;
2271 return true;
2272 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2273 *params = MAX_VERTEX_UNIFORM_BLOCKS;
2274 return true;
2275 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2276 *params = MAX_VERTEX_UNIFORM_COMPONENTS;
2277 return true;
2278 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2279 // Note: SwiftShader has no actual texel offset limit, so this limit can be modified if required.
2280 // In any case, any behavior outside the specified range is valid since the spec mentions:
2281 // (see OpenGL ES 3.0.5, 3.8.10.1 Scale Factor and Level of Detail, p.153)
2282 // "If any of the offset values are outside the range of the implementation-defined values
2283 // MIN_PROGRAM_TEXEL_OFFSET and MAX_PROGRAM_TEXEL_OFFSET, results of the texture lookup are
2284 // undefined."
2285 *params = MIN_PROGRAM_TEXEL_OFFSET;
2286 return true;
2287 case GL_NUM_EXTENSIONS:
2288 GLuint numExtensions;
2289 getExtensions(0, &numExtensions);
2290 *params = numExtensions;
2291 return true;
2292 case GL_NUM_PROGRAM_BINARY_FORMATS:
2293 *params = NUM_PROGRAM_BINARY_FORMATS;
2294 return true;
2295 case GL_PACK_ROW_LENGTH:
2296 *params = mState.packParameters.rowLength;
2297 return true;
2298 case GL_PACK_SKIP_PIXELS:
2299 *params = mState.packParameters.skipPixels;
2300 return true;
2301 case GL_PACK_SKIP_ROWS:
2302 *params = mState.packParameters.skipRows;
2303 return true;
2304 case GL_PIXEL_PACK_BUFFER_BINDING:
2305 *params = mState.pixelPackBuffer.name();
2306 return true;
2307 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2308 *params = mState.pixelUnpackBuffer.name();
2309 return true;
2310 case GL_PROGRAM_BINARY_FORMATS:
2311 // Since NUM_PROGRAM_BINARY_FORMATS is 0, the input
2312 // should be a 0 sized array, so don't write to params
2313 return true;
2314 case GL_READ_BUFFER:
2315 {
2316 Framebuffer* framebuffer = getReadFramebuffer();
2317 *params = framebuffer ? framebuffer->getReadBuffer() : GL_NONE;
2318 }
2319 return true;
2320 case GL_SAMPLER_BINDING:
2321 *params = mState.sampler[mState.activeSampler].name();
2322 return true;
2323 case GL_UNIFORM_BUFFER_BINDING:
2324 *params = mState.genericUniformBuffer.name();
2325 return true;
2326 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2327 *params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2328 return true;
2329 case GL_UNPACK_IMAGE_HEIGHT:
2330 *params = mState.unpackParameters.imageHeight;
2331 return true;
2332 case GL_UNPACK_ROW_LENGTH:
2333 *params = mState.unpackParameters.rowLength;
2334 return true;
2335 case GL_UNPACK_SKIP_IMAGES:
2336 *params = mState.unpackParameters.skipImages;
2337 return true;
2338 case GL_UNPACK_SKIP_PIXELS:
2339 *params = mState.unpackParameters.skipPixels;
2340 return true;
2341 case GL_UNPACK_SKIP_ROWS:
2342 *params = mState.unpackParameters.skipRows;
2343 return true;
2344 case GL_VERTEX_ARRAY_BINDING:
2345 *params = getCurrentVertexArray()->name;
2346 return true;
2347 case GL_TRANSFORM_FEEDBACK_BINDING:
2348 {
2349 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2350 if(transformFeedback)
2351 {
2352 *params = transformFeedback->name;
2353 }
2354 else
2355 {
2356 return false;
2357 }
2358 }
2359 return true;
2360 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2361 {
2362 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2363 if(transformFeedback)
2364 {
2365 *params = transformFeedback->getGenericBufferName();
2366 }
2367 else
2368 {
2369 return false;
2370 }
2371 }
2372 return true;
2373 default:
2374 break;
2375 }
2376
2377 return false;
2378 }
2379
2380 template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2381 template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2382
getTransformFeedbackiv(GLuint index,GLenum pname,T * param) const2383 template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2384 {
2385 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2386 if(!transformFeedback)
2387 {
2388 return false;
2389 }
2390
2391 switch(pname)
2392 {
2393 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2394 *param = transformFeedback->name;
2395 break;
2396 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2397 *param = transformFeedback->isActive();
2398 break;
2399 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2400 *param = transformFeedback->getBufferName(index);
2401 break;
2402 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2403 *param = transformFeedback->isPaused();
2404 break;
2405 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2406 if(transformFeedback->getBuffer(index))
2407 {
2408 *param = transformFeedback->getSize(index);
2409 break;
2410 }
2411 else return false;
2412 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2413 if(transformFeedback->getBuffer(index))
2414 {
2415 *param = transformFeedback->getOffset(index);
2416 break;
2417 }
2418 else return false;
2419 default:
2420 return false;
2421 }
2422
2423 return true;
2424 }
2425
2426 template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2427 template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2428
getUniformBufferiv(GLuint index,GLenum pname,T * param) const2429 template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2430 {
2431 switch(pname)
2432 {
2433 case GL_UNIFORM_BUFFER_BINDING:
2434 case GL_UNIFORM_BUFFER_SIZE:
2435 case GL_UNIFORM_BUFFER_START:
2436 break;
2437 default:
2438 return false;
2439 }
2440
2441 if(index >= MAX_UNIFORM_BUFFER_BINDINGS)
2442 {
2443 return error(GL_INVALID_VALUE, true);
2444 }
2445
2446 const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
2447
2448 switch(pname)
2449 {
2450 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2451 *param = uniformBuffer.get().name();
2452 break;
2453 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2454 *param = uniformBuffer.getSize();
2455 break;
2456 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2457 *param = uniformBuffer.getOffset();
2458 break;
2459 default:
2460 return false;
2461 }
2462
2463 return true;
2464 }
2465
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams) const2466 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2467 {
2468 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2469 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2470 // to the fact that it is stored internally as a float, and so would require conversion
2471 // if returned from Context::getIntegerv. Since this conversion is already implemented
2472 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2473 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2474 // application.
2475 switch(pname)
2476 {
2477 case GL_COMPRESSED_TEXTURE_FORMATS:
2478 {
2479 *type = GL_INT;
2480 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2481 }
2482 break;
2483 case GL_SHADER_BINARY_FORMATS:
2484 {
2485 *type = GL_INT;
2486 *numParams = 0;
2487 }
2488 break;
2489 case GL_MAX_VERTEX_ATTRIBS:
2490 case GL_MAX_VERTEX_UNIFORM_VECTORS:
2491 case GL_MAX_VARYING_VECTORS:
2492 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2493 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2494 case GL_MAX_TEXTURE_IMAGE_UNITS:
2495 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2496 case GL_MAX_RENDERBUFFER_SIZE:
2497 case GL_NUM_SHADER_BINARY_FORMATS:
2498 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2499 case GL_ARRAY_BUFFER_BINDING:
2500 case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2501 case GL_READ_FRAMEBUFFER_BINDING: // Same as GL_READ_FRAMEBUFFER_BINDING_ANGLE
2502 case GL_RENDERBUFFER_BINDING:
2503 case GL_CURRENT_PROGRAM:
2504 case GL_PACK_ALIGNMENT:
2505 case GL_UNPACK_ALIGNMENT:
2506 case GL_GENERATE_MIPMAP_HINT:
2507 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2508 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2509 case GL_RED_BITS:
2510 case GL_GREEN_BITS:
2511 case GL_BLUE_BITS:
2512 case GL_ALPHA_BITS:
2513 case GL_DEPTH_BITS:
2514 case GL_STENCIL_BITS:
2515 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2516 case GL_CULL_FACE_MODE:
2517 case GL_FRONT_FACE:
2518 case GL_ACTIVE_TEXTURE:
2519 case GL_STENCIL_FUNC:
2520 case GL_STENCIL_VALUE_MASK:
2521 case GL_STENCIL_REF:
2522 case GL_STENCIL_FAIL:
2523 case GL_STENCIL_PASS_DEPTH_FAIL:
2524 case GL_STENCIL_PASS_DEPTH_PASS:
2525 case GL_STENCIL_BACK_FUNC:
2526 case GL_STENCIL_BACK_VALUE_MASK:
2527 case GL_STENCIL_BACK_REF:
2528 case GL_STENCIL_BACK_FAIL:
2529 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2530 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2531 case GL_DEPTH_FUNC:
2532 case GL_BLEND_SRC_RGB:
2533 case GL_BLEND_SRC_ALPHA:
2534 case GL_BLEND_DST_RGB:
2535 case GL_BLEND_DST_ALPHA:
2536 case GL_BLEND_EQUATION_RGB:
2537 case GL_BLEND_EQUATION_ALPHA:
2538 case GL_STENCIL_WRITEMASK:
2539 case GL_STENCIL_BACK_WRITEMASK:
2540 case GL_STENCIL_CLEAR_VALUE:
2541 case GL_SUBPIXEL_BITS:
2542 case GL_MAX_TEXTURE_SIZE:
2543 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2544 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB:
2545 case GL_SAMPLE_BUFFERS:
2546 case GL_SAMPLES:
2547 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2548 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2549 case GL_TEXTURE_BINDING_2D:
2550 case GL_TEXTURE_BINDING_CUBE_MAP:
2551 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
2552 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2553 case GL_TEXTURE_BINDING_3D_OES:
2554 case GL_COPY_READ_BUFFER_BINDING:
2555 case GL_COPY_WRITE_BUFFER_BINDING:
2556 case GL_DRAW_BUFFER0:
2557 case GL_DRAW_BUFFER1:
2558 case GL_DRAW_BUFFER2:
2559 case GL_DRAW_BUFFER3:
2560 case GL_DRAW_BUFFER4:
2561 case GL_DRAW_BUFFER5:
2562 case GL_DRAW_BUFFER6:
2563 case GL_DRAW_BUFFER7:
2564 case GL_DRAW_BUFFER8:
2565 case GL_DRAW_BUFFER9:
2566 case GL_DRAW_BUFFER10:
2567 case GL_DRAW_BUFFER11:
2568 case GL_DRAW_BUFFER12:
2569 case GL_DRAW_BUFFER13:
2570 case GL_DRAW_BUFFER14:
2571 case GL_DRAW_BUFFER15:
2572 case GL_MAJOR_VERSION:
2573 case GL_MAX_3D_TEXTURE_SIZE:
2574 case GL_MAX_ARRAY_TEXTURE_LAYERS:
2575 case GL_MAX_COLOR_ATTACHMENTS:
2576 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2577 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2578 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2579 case GL_MAX_DRAW_BUFFERS:
2580 case GL_MAX_ELEMENT_INDEX:
2581 case GL_MAX_ELEMENTS_INDICES:
2582 case GL_MAX_ELEMENTS_VERTICES:
2583 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2584 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2585 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2586 case GL_MAX_PROGRAM_TEXEL_OFFSET:
2587 case GL_MAX_SERVER_WAIT_TIMEOUT:
2588 case GL_MAX_TEXTURE_LOD_BIAS:
2589 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2590 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2591 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2592 case GL_MAX_UNIFORM_BLOCK_SIZE:
2593 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2594 case GL_MAX_VARYING_COMPONENTS:
2595 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2596 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2597 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2598 case GL_MIN_PROGRAM_TEXEL_OFFSET:
2599 case GL_MINOR_VERSION:
2600 case GL_NUM_EXTENSIONS:
2601 case GL_NUM_PROGRAM_BINARY_FORMATS:
2602 case GL_PACK_ROW_LENGTH:
2603 case GL_PACK_SKIP_PIXELS:
2604 case GL_PACK_SKIP_ROWS:
2605 case GL_PIXEL_PACK_BUFFER_BINDING:
2606 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2607 case GL_PROGRAM_BINARY_FORMATS:
2608 case GL_READ_BUFFER:
2609 case GL_SAMPLER_BINDING:
2610 case GL_TEXTURE_BINDING_2D_ARRAY:
2611 case GL_UNIFORM_BUFFER_BINDING:
2612 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2613 case GL_UNPACK_IMAGE_HEIGHT:
2614 case GL_UNPACK_ROW_LENGTH:
2615 case GL_UNPACK_SKIP_IMAGES:
2616 case GL_UNPACK_SKIP_PIXELS:
2617 case GL_UNPACK_SKIP_ROWS:
2618 case GL_VERTEX_ARRAY_BINDING:
2619 case GL_TRANSFORM_FEEDBACK_BINDING:
2620 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2621 {
2622 *type = GL_INT;
2623 *numParams = 1;
2624 }
2625 break;
2626 case GL_MAX_SAMPLES:
2627 {
2628 *type = GL_INT;
2629 *numParams = 1;
2630 }
2631 break;
2632 case GL_MAX_VIEWPORT_DIMS:
2633 {
2634 *type = GL_INT;
2635 *numParams = 2;
2636 }
2637 break;
2638 case GL_VIEWPORT:
2639 case GL_SCISSOR_BOX:
2640 {
2641 *type = GL_INT;
2642 *numParams = 4;
2643 }
2644 break;
2645 case GL_SHADER_COMPILER:
2646 case GL_SAMPLE_COVERAGE_INVERT:
2647 case GL_DEPTH_WRITEMASK:
2648 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
2649 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
2650 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2651 case GL_SAMPLE_COVERAGE:
2652 case GL_SCISSOR_TEST:
2653 case GL_STENCIL_TEST:
2654 case GL_DEPTH_TEST:
2655 case GL_BLEND:
2656 case GL_DITHER:
2657 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2658 case GL_RASTERIZER_DISCARD:
2659 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2660 case GL_TRANSFORM_FEEDBACK_PAUSED:
2661 {
2662 *type = GL_BOOL;
2663 *numParams = 1;
2664 }
2665 break;
2666 case GL_COLOR_WRITEMASK:
2667 {
2668 *type = GL_BOOL;
2669 *numParams = 4;
2670 }
2671 break;
2672 case GL_POLYGON_OFFSET_FACTOR:
2673 case GL_POLYGON_OFFSET_UNITS:
2674 case GL_SAMPLE_COVERAGE_VALUE:
2675 case GL_DEPTH_CLEAR_VALUE:
2676 case GL_LINE_WIDTH:
2677 {
2678 *type = GL_FLOAT;
2679 *numParams = 1;
2680 }
2681 break;
2682 case GL_ALIASED_LINE_WIDTH_RANGE:
2683 case GL_ALIASED_POINT_SIZE_RANGE:
2684 case GL_DEPTH_RANGE:
2685 {
2686 *type = GL_FLOAT;
2687 *numParams = 2;
2688 }
2689 break;
2690 case GL_COLOR_CLEAR_VALUE:
2691 case GL_BLEND_COLOR:
2692 {
2693 *type = GL_FLOAT;
2694 *numParams = 4;
2695 }
2696 break;
2697 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2698 *type = GL_FLOAT;
2699 *numParams = 1;
2700 break;
2701 default:
2702 return false;
2703 }
2704
2705 return true;
2706 }
2707
applyScissor(int width,int height)2708 void Context::applyScissor(int width, int height)
2709 {
2710 if(mState.scissorTestEnabled)
2711 {
2712 sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2713 scissor.clip(0, 0, width, height);
2714
2715 device->setScissorRect(scissor);
2716 device->setScissorEnable(true);
2717 }
2718 else
2719 {
2720 device->setScissorEnable(false);
2721 }
2722 }
2723
2724 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()2725 bool Context::applyRenderTarget()
2726 {
2727 Framebuffer *framebuffer = getDrawFramebuffer();
2728 int width, height, samples;
2729
2730 if(!framebuffer || (framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE))
2731 {
2732 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2733 }
2734
2735 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2736 {
2737 if(framebuffer->getDrawBuffer(i) != GL_NONE)
2738 {
2739 egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2740 GLint layer = framebuffer->getColorbufferLayer(i);
2741 device->setRenderTarget(i, renderTarget, layer);
2742 if(renderTarget) renderTarget->release();
2743 }
2744 else
2745 {
2746 device->setRenderTarget(i, nullptr, 0);
2747 }
2748 }
2749
2750 egl::Image *depthBuffer = framebuffer->getDepthBuffer();
2751 GLint dLayer = framebuffer->getDepthbufferLayer();
2752 device->setDepthBuffer(depthBuffer, dLayer);
2753 if(depthBuffer) depthBuffer->release();
2754
2755 egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
2756 GLint sLayer = framebuffer->getStencilbufferLayer();
2757 device->setStencilBuffer(stencilBuffer, sLayer);
2758 if(stencilBuffer) stencilBuffer->release();
2759
2760 Viewport viewport;
2761 float zNear = clamp01(mState.zNear);
2762 float zFar = clamp01(mState.zFar);
2763
2764 viewport.x0 = mState.viewportX;
2765 viewport.y0 = mState.viewportY;
2766 viewport.width = mState.viewportWidth;
2767 viewport.height = mState.viewportHeight;
2768 viewport.minZ = zNear;
2769 viewport.maxZ = zFar;
2770
2771 device->setViewport(viewport);
2772
2773 applyScissor(width, height);
2774
2775 Program *program = getCurrentProgram();
2776
2777 if(program)
2778 {
2779 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2780 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2781 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2782 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2783 }
2784
2785 return true;
2786 }
2787
2788 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)2789 void Context::applyState(GLenum drawMode)
2790 {
2791 Framebuffer *framebuffer = getDrawFramebuffer();
2792 bool frontFaceCCW = (mState.frontFace == GL_CCW);
2793
2794 if(mState.cullFaceEnabled)
2795 {
2796 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
2797 }
2798 else
2799 {
2800 device->setCullMode(sw::CULL_NONE, frontFaceCCW);
2801 }
2802
2803 if(mDepthStateDirty)
2804 {
2805 if(mState.depthTestEnabled)
2806 {
2807 device->setDepthBufferEnable(true);
2808 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2809 }
2810 else
2811 {
2812 device->setDepthBufferEnable(false);
2813 }
2814
2815 mDepthStateDirty = false;
2816 }
2817
2818 if(mBlendStateDirty)
2819 {
2820 if(mState.blendEnabled)
2821 {
2822 device->setAlphaBlendEnable(true);
2823 device->setSeparateAlphaBlendEnable(true);
2824
2825 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2826
2827 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2828 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2829 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2830
2831 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2832 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2833 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2834 }
2835 else
2836 {
2837 device->setAlphaBlendEnable(false);
2838 }
2839
2840 mBlendStateDirty = false;
2841 }
2842
2843 if(mStencilStateDirty || mFrontFaceDirty)
2844 {
2845 if(mState.stencilTestEnabled && framebuffer->hasStencil())
2846 {
2847 device->setStencilEnable(true);
2848 device->setTwoSidedStencil(true);
2849
2850 // get the maximum size of the stencil ref
2851 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2852 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2853
2854 if(mState.frontFace == GL_CCW)
2855 {
2856 device->setStencilWriteMask(mState.stencilWritemask);
2857 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2858
2859 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2860 device->setStencilMask(mState.stencilMask);
2861
2862 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2863 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2864 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2865
2866 device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2867 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2868
2869 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2870 device->setStencilMaskCCW(mState.stencilBackMask);
2871
2872 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2873 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2874 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2875 }
2876 else
2877 {
2878 device->setStencilWriteMaskCCW(mState.stencilWritemask);
2879 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2880
2881 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2882 device->setStencilMaskCCW(mState.stencilMask);
2883
2884 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2885 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2886 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2887
2888 device->setStencilWriteMask(mState.stencilBackWritemask);
2889 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2890
2891 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2892 device->setStencilMask(mState.stencilBackMask);
2893
2894 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2895 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2896 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2897 }
2898 }
2899 else
2900 {
2901 device->setStencilEnable(false);
2902 }
2903
2904 mStencilStateDirty = false;
2905 mFrontFaceDirty = false;
2906 }
2907
2908 if(mMaskStateDirty)
2909 {
2910 for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
2911 {
2912 device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2913 }
2914
2915 device->setDepthWriteEnable(mState.depthMask);
2916
2917 mMaskStateDirty = false;
2918 }
2919
2920 if(mPolygonOffsetStateDirty)
2921 {
2922 if(mState.polygonOffsetFillEnabled)
2923 {
2924 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2925 if(depthbuffer)
2926 {
2927 device->setSlopeDepthBias(mState.polygonOffsetFactor);
2928 float depthBias = ldexp(mState.polygonOffsetUnits, -23); // We use 32-bit floating-point for all depth formats, with 23 mantissa bits.
2929 device->setDepthBias(depthBias);
2930 }
2931 }
2932 else
2933 {
2934 device->setSlopeDepthBias(0);
2935 device->setDepthBias(0);
2936 }
2937
2938 mPolygonOffsetStateDirty = false;
2939 }
2940
2941 if(mSampleStateDirty)
2942 {
2943 if(mState.sampleAlphaToCoverageEnabled)
2944 {
2945 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
2946 }
2947 else
2948 {
2949 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
2950 }
2951
2952 if(mState.sampleCoverageEnabled)
2953 {
2954 unsigned int mask = 0;
2955 if(mState.sampleCoverageValue != 0)
2956 {
2957 int width, height, samples;
2958 framebuffer->completeness(width, height, samples);
2959
2960 float threshold = 0.5f;
2961
2962 for(int i = 0; i < samples; i++)
2963 {
2964 mask <<= 1;
2965
2966 if((i + 1) * mState.sampleCoverageValue >= threshold)
2967 {
2968 threshold += 1.0f;
2969 mask |= 1;
2970 }
2971 }
2972 }
2973
2974 if(mState.sampleCoverageInvert)
2975 {
2976 mask = ~mask;
2977 }
2978
2979 device->setMultiSampleMask(mask);
2980 }
2981 else
2982 {
2983 device->setMultiSampleMask(0xFFFFFFFF);
2984 }
2985
2986 mSampleStateDirty = false;
2987 }
2988
2989 if(mDitherStateDirty)
2990 {
2991 // UNIMPLEMENTED(); // FIXME
2992
2993 mDitherStateDirty = false;
2994 }
2995
2996 device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
2997 }
2998
applyVertexBuffer(GLint base,GLint first,GLsizei count,GLsizei instanceId)2999 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3000 {
3001 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3002
3003 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3004 if(err != GL_NO_ERROR)
3005 {
3006 return err;
3007 }
3008
3009 Program *program = getCurrentProgram();
3010
3011 device->resetInputStreams(false);
3012
3013 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3014 {
3015 if(program->getAttributeStream(i) == -1)
3016 {
3017 continue;
3018 }
3019
3020 sw::Resource *resource = attributes[i].vertexBuffer;
3021 const void *buffer = (char*)resource->data() + attributes[i].offset;
3022
3023 int stride = attributes[i].stride;
3024
3025 buffer = (char*)buffer + stride * base;
3026
3027 sw::Stream attribute(resource, buffer, stride);
3028
3029 attribute.type = attributes[i].type;
3030 attribute.count = attributes[i].count;
3031 attribute.normalized = attributes[i].normalized;
3032
3033 int stream = program->getAttributeStream(i);
3034 device->setInputStream(stream, attribute);
3035 }
3036
3037 return GL_NO_ERROR;
3038 }
3039
3040 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLuint start,GLuint end,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)3041 GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3042 {
3043 GLenum err = mIndexDataManager->prepareIndexData(mode, type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo, isPrimitiveRestartFixedIndexEnabled());
3044
3045 if(err == GL_NO_ERROR)
3046 {
3047 device->setIndexBuffer(indexInfo->indexBuffer);
3048 }
3049
3050 return err;
3051 }
3052
3053 // Applies the shaders and shader constants
applyShaders()3054 void Context::applyShaders()
3055 {
3056 Program *programObject = getCurrentProgram();
3057 sw::VertexShader *vertexShader = programObject->getVertexShader();
3058 sw::PixelShader *pixelShader = programObject->getPixelShader();
3059
3060 device->setVertexShader(vertexShader);
3061 device->setPixelShader(pixelShader);
3062
3063 if(programObject->getSerial() != mAppliedProgramSerial)
3064 {
3065 programObject->dirtyAllUniforms();
3066 mAppliedProgramSerial = programObject->getSerial();
3067 }
3068
3069 programObject->applyTransformFeedback(device, getTransformFeedback());
3070 programObject->applyUniformBuffers(device, mState.uniformBuffers);
3071 programObject->applyUniforms(device);
3072 }
3073
applyTextures()3074 void Context::applyTextures()
3075 {
3076 applyTextures(sw::SAMPLER_PIXEL);
3077 applyTextures(sw::SAMPLER_VERTEX);
3078 }
3079
applyTextures(sw::SamplerType samplerType)3080 void Context::applyTextures(sw::SamplerType samplerType)
3081 {
3082 Program *programObject = getCurrentProgram();
3083
3084 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type
3085
3086 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3087 {
3088 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index
3089
3090 if(textureUnit != -1)
3091 {
3092 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3093
3094 Texture *texture = getSamplerTexture(textureUnit, textureType);
3095 Sampler *samplerObject = mState.sampler[textureUnit];
3096
3097 if(texture->isSamplerComplete(samplerObject))
3098 {
3099 GLenum wrapS, wrapT, wrapR, minFilter, magFilter, compFunc, compMode;
3100 GLfloat minLOD, maxLOD, maxAnisotropy;
3101
3102 if(samplerObject)
3103 {
3104 wrapS = samplerObject->getWrapS();
3105 wrapT = samplerObject->getWrapT();
3106 wrapR = samplerObject->getWrapR();
3107 minFilter = samplerObject->getMinFilter();
3108 magFilter = samplerObject->getMagFilter();
3109 minLOD = samplerObject->getMinLod();
3110 maxLOD = samplerObject->getMaxLod();
3111 compFunc = samplerObject->getCompareFunc();
3112 compMode = samplerObject->getCompareMode();
3113 maxAnisotropy = samplerObject->getMaxAnisotropy();
3114 }
3115 else
3116 {
3117 wrapS = texture->getWrapS();
3118 wrapT = texture->getWrapT();
3119 wrapR = texture->getWrapR();
3120 minFilter = texture->getMinFilter();
3121 magFilter = texture->getMagFilter();
3122 minLOD = texture->getMinLOD();
3123 maxLOD = texture->getMaxLOD();
3124 compFunc = texture->getCompareFunc();
3125 compMode = texture->getCompareMode();
3126 maxAnisotropy = texture->getMaxAnisotropy();
3127 }
3128
3129 GLint baseLevel = texture->getBaseLevel();
3130 GLint maxLevel = texture->getMaxLevel();
3131 GLenum swizzleR = texture->getSwizzleR();
3132 GLenum swizzleG = texture->getSwizzleG();
3133 GLenum swizzleB = texture->getSwizzleB();
3134 GLenum swizzleA = texture->getSwizzleA();
3135
3136 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3137 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3138 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3139 device->setCompareFunc(samplerType, samplerIndex, es2sw::ConvertCompareFunc(compFunc, compMode));
3140 device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3141 device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3142 device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3143 device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3144 device->setMinLod(samplerType, samplerIndex, minLOD);
3145 device->setMaxLod(samplerType, samplerIndex, maxLOD);
3146 device->setBaseLevel(samplerType, samplerIndex, baseLevel);
3147 device->setMaxLevel(samplerType, samplerIndex, maxLevel);
3148 device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3149 device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3150 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3151 device->setHighPrecisionFiltering(samplerType, samplerIndex, mState.textureFilteringHint == GL_NICEST);
3152 device->setSyncRequired(samplerType, samplerIndex, texture->requiresSync());
3153
3154 applyTexture(samplerType, samplerIndex, texture);
3155 }
3156 else
3157 {
3158 applyTexture(samplerType, samplerIndex, nullptr);
3159 }
3160 }
3161 else
3162 {
3163 applyTexture(samplerType, samplerIndex, nullptr);
3164 }
3165 }
3166 }
3167
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)3168 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3169 {
3170 Program *program = getCurrentProgram();
3171 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3172 bool textureUsed = false;
3173
3174 if(type == sw::SAMPLER_PIXEL)
3175 {
3176 textureUsed = program->getPixelShader()->usesSampler(index);
3177 }
3178 else if(type == sw::SAMPLER_VERTEX)
3179 {
3180 textureUsed = program->getVertexShader()->usesSampler(index);
3181 }
3182 else UNREACHABLE(type);
3183
3184 sw::Resource *resource = nullptr;
3185
3186 if(baseTexture && textureUsed)
3187 {
3188 resource = baseTexture->getResource();
3189 }
3190
3191 device->setTextureResource(sampler, resource);
3192
3193 if(baseTexture && textureUsed)
3194 {
3195 int baseLevel = baseTexture->getBaseLevel();
3196 int maxLevel = std::min(baseTexture->getTopLevel(), baseTexture->getMaxLevel());
3197 GLenum target = baseTexture->getTarget();
3198
3199 switch(target)
3200 {
3201 case GL_TEXTURE_2D:
3202 case GL_TEXTURE_EXTERNAL_OES:
3203 case GL_TEXTURE_RECTANGLE_ARB:
3204 {
3205 Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3206
3207 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3208 {
3209 int surfaceLevel = mipmapLevel + baseLevel;
3210
3211 if(surfaceLevel > maxLevel)
3212 {
3213 surfaceLevel = maxLevel;
3214 }
3215
3216 egl::Image *surface = texture->getImage(surfaceLevel);
3217 device->setTextureLevel(sampler, 0, mipmapLevel, surface,
3218 (target == GL_TEXTURE_RECTANGLE_ARB) ? sw::TEXTURE_RECTANGLE : sw::TEXTURE_2D);
3219 }
3220 }
3221 break;
3222 case GL_TEXTURE_3D:
3223 {
3224 Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3225
3226 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3227 {
3228 int surfaceLevel = mipmapLevel + baseLevel;
3229
3230 if(surfaceLevel > maxLevel)
3231 {
3232 surfaceLevel = maxLevel;
3233 }
3234
3235 egl::Image *surface = texture->getImage(surfaceLevel);
3236 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3237 }
3238 }
3239 break;
3240 case GL_TEXTURE_2D_ARRAY:
3241 {
3242 Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3243
3244 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3245 {
3246 int surfaceLevel = mipmapLevel + baseLevel;
3247
3248 if(surfaceLevel > maxLevel)
3249 {
3250 surfaceLevel = maxLevel;
3251 }
3252
3253 egl::Image *surface = texture->getImage(surfaceLevel);
3254 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3255 }
3256 }
3257 break;
3258 case GL_TEXTURE_CUBE_MAP:
3259 {
3260 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3261
3262 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
3263 {
3264 cubeTexture->updateBorders(mipmapLevel);
3265
3266 for(int face = 0; face < 6; face++)
3267 {
3268 int surfaceLevel = mipmapLevel + baseLevel;
3269
3270 if(surfaceLevel > maxLevel)
3271 {
3272 surfaceLevel = maxLevel;
3273 }
3274
3275 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3276 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3277 }
3278 }
3279 }
3280 break;
3281 default:
3282 UNIMPLEMENTED();
3283 break;
3284 }
3285 }
3286 else
3287 {
3288 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3289 }
3290 }
3291
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)3292 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3293 {
3294 Framebuffer *framebuffer = getReadFramebuffer();
3295 int framebufferWidth, framebufferHeight, framebufferSamples;
3296
3297 if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE))
3298 {
3299 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3300 }
3301
3302 if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3303 {
3304 return error(GL_INVALID_OPERATION);
3305 }
3306
3307 if(!ValidateReadPixelsFormatType(framebuffer, format, type))
3308 {
3309 return;
3310 }
3311
3312 GLsizei outputWidth = (mState.packParameters.rowLength > 0) ? mState.packParameters.rowLength : width;
3313 GLsizei outputPitch = gl::ComputePitch(outputWidth, format, type, mState.packParameters.alignment);
3314 GLsizei outputHeight = (mState.packParameters.imageHeight == 0) ? height : mState.packParameters.imageHeight;
3315 pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3316 pixels = ((char*)pixels) + gl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packParameters);
3317
3318 // Sized query sanity check
3319 if(bufSize)
3320 {
3321 int requiredSize = outputPitch * height;
3322 if(requiredSize > *bufSize)
3323 {
3324 return error(GL_INVALID_OPERATION);
3325 }
3326 }
3327
3328 egl::Image *renderTarget = nullptr;
3329 switch(format)
3330 {
3331 case GL_DEPTH_COMPONENT: // GL_NV_read_depth
3332 case GL_DEPTH_STENCIL_OES: // GL_NV_read_depth_stencil
3333 renderTarget = framebuffer->getDepthBuffer();
3334 break;
3335 case GL_STENCIL_INDEX_OES: // GL_NV_read_stencil
3336 renderTarget = framebuffer->getStencilBuffer();
3337 break;
3338 default:
3339 renderTarget = framebuffer->getReadRenderTarget();
3340 break;
3341 }
3342
3343 if(!renderTarget)
3344 {
3345 return error(GL_INVALID_OPERATION);
3346 }
3347
3348 sw::SliceRectF srcRect((float)x, (float)y, (float)(x + width), (float)(y + height), 0);
3349 sw::SliceRect dstRect(0, 0, width, height, 0);
3350 srcRect.clip(0.0f, 0.0f, (float)renderTarget->getWidth(), (float)renderTarget->getHeight());
3351
3352 if(format != GL_DEPTH_STENCIL_OES) // The blitter only handles reading either depth or stencil.
3353 {
3354 sw::Surface *externalSurface = sw::Surface::create(width, height, 1, es2::ConvertReadFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
3355 device->blit(renderTarget, srcRect, externalSurface, dstRect, false, false, false);
3356 externalSurface->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3357 externalSurface->unlockExternal();
3358 delete externalSurface;
3359 }
3360 else // format == GL_DEPTH_STENCIL_OES
3361 {
3362 ASSERT(renderTarget->getInternalFormat() == sw::FORMAT_D32F_LOCKABLE);
3363 float *depth = (float*)renderTarget->lockInternal((int)srcRect.x0, (int)srcRect.y0, 0, sw::LOCK_READONLY, sw::PUBLIC);
3364 uint8_t *stencil = (uint8_t*)renderTarget->lockStencil((int)srcRect.x0, (int)srcRect.y0, 0, sw::PUBLIC);
3365
3366 switch(type)
3367 {
3368 case GL_UNSIGNED_INT_24_8_OES:
3369 {
3370 uint32_t *output = (uint32_t*)pixels;
3371
3372 for(int y = 0; y < height; y++)
3373 {
3374 for(int x = 0; x < width; x++)
3375 {
3376 output[x] = ((uint32_t)roundf(depth[x] * 0xFFFFFF00) & 0xFFFFFF00) | stencil[x];
3377 }
3378
3379 depth += renderTarget->getInternalPitchP();
3380 stencil += renderTarget->getStencilPitchB();
3381 (uint8_t*&)output += outputPitch;
3382 }
3383 }
3384 break;
3385 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
3386 {
3387 struct D32FS8 { float depth32f; unsigned int stencil24_8; };
3388 D32FS8 *output = (D32FS8*)pixels;
3389
3390 for(int y = 0; y < height; y++)
3391 {
3392 for(int x = 0; x < width; x++)
3393 {
3394 output[x].depth32f = depth[x];
3395 output[x].stencil24_8 = stencil[x];
3396 }
3397
3398 depth += renderTarget->getInternalPitchP();
3399 stencil += renderTarget->getStencilPitchB();
3400 (uint8_t*&)output += outputPitch;
3401 }
3402 }
3403 break;
3404 default: UNREACHABLE(type);
3405 }
3406
3407 renderTarget->unlockInternal();
3408 renderTarget->unlockStencil();
3409 }
3410
3411 renderTarget->release();
3412 }
3413
clear(GLbitfield mask)3414 void Context::clear(GLbitfield mask)
3415 {
3416 if(mState.rasterizerDiscardEnabled)
3417 {
3418 return;
3419 }
3420
3421 Framebuffer *framebuffer = getDrawFramebuffer();
3422
3423 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3424 {
3425 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3426 }
3427
3428 if(!applyRenderTarget())
3429 {
3430 return;
3431 }
3432
3433 if(mask & GL_COLOR_BUFFER_BIT)
3434 {
3435 unsigned int rgbaMask = getColorMask();
3436
3437 if(rgbaMask != 0)
3438 {
3439 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3440 }
3441 }
3442
3443 if(mask & GL_DEPTH_BUFFER_BIT)
3444 {
3445 if(mState.depthMask != 0)
3446 {
3447 float depth = clamp01(mState.depthClearValue);
3448 device->clearDepth(depth);
3449 }
3450 }
3451
3452 if(mask & GL_STENCIL_BUFFER_BIT)
3453 {
3454 if(mState.stencilWritemask != 0)
3455 {
3456 int stencil = mState.stencilClearValue & 0x000000FF;
3457 device->clearStencil(stencil, mState.stencilWritemask);
3458 }
3459 }
3460 }
3461
clearColorBuffer(GLint drawbuffer,void * value,sw::Format format)3462 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3463 {
3464 unsigned int rgbaMask = getColorMask();
3465 if(rgbaMask && !mState.rasterizerDiscardEnabled)
3466 {
3467 Framebuffer *framebuffer = getDrawFramebuffer();
3468 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3469 {
3470 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3471 }
3472 egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
3473
3474 if(colorbuffer)
3475 {
3476 sw::Rect clearRect = colorbuffer->getRect();
3477
3478 if(mState.scissorTestEnabled)
3479 {
3480 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3481 }
3482
3483 device->clear(value, format, colorbuffer, clearRect, rgbaMask);
3484
3485 colorbuffer->release();
3486 }
3487 }
3488 }
3489
clearColorBuffer(GLint drawbuffer,const GLint * value)3490 void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3491 {
3492 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3493 }
3494
clearColorBuffer(GLint drawbuffer,const GLuint * value)3495 void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3496 {
3497 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3498 }
3499
clearColorBuffer(GLint drawbuffer,const GLfloat * value)3500 void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3501 {
3502 clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3503 }
3504
clearDepthBuffer(const GLfloat value)3505 void Context::clearDepthBuffer(const GLfloat value)
3506 {
3507 if(mState.depthMask && !mState.rasterizerDiscardEnabled)
3508 {
3509 Framebuffer *framebuffer = getDrawFramebuffer();
3510 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3511 {
3512 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3513 }
3514 egl::Image *depthbuffer = framebuffer->getDepthBuffer();
3515
3516 if(depthbuffer)
3517 {
3518 float depth = clamp01(value);
3519 sw::Rect clearRect = depthbuffer->getRect();
3520
3521 if(mState.scissorTestEnabled)
3522 {
3523 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3524 }
3525
3526 depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3527
3528 depthbuffer->release();
3529 }
3530 }
3531 }
3532
clearStencilBuffer(const GLint value)3533 void Context::clearStencilBuffer(const GLint value)
3534 {
3535 if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
3536 {
3537 Framebuffer *framebuffer = getDrawFramebuffer();
3538 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE))
3539 {
3540 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3541 }
3542 egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
3543
3544 if(stencilbuffer)
3545 {
3546 unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
3547 sw::Rect clearRect = stencilbuffer->getRect();
3548
3549 if(mState.scissorTestEnabled)
3550 {
3551 clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
3552 }
3553
3554 stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
3555
3556 stencilbuffer->release();
3557 }
3558 }
3559 }
3560
drawArrays(GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)3561 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3562 {
3563 if(!applyRenderTarget())
3564 {
3565 return;
3566 }
3567
3568 if(mState.currentProgram == 0)
3569 {
3570 return; // Nothing to process.
3571 }
3572
3573 sw::DrawType primitiveType;
3574 int primitiveCount;
3575 int verticesPerPrimitive;
3576
3577 if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
3578 {
3579 return error(GL_INVALID_ENUM);
3580 }
3581
3582 applyState(mode);
3583
3584 for(int i = 0; i < instanceCount; ++i)
3585 {
3586 device->setInstanceID(i);
3587
3588 GLenum err = applyVertexBuffer(0, first, count, i);
3589 if(err != GL_NO_ERROR)
3590 {
3591 return error(err);
3592 }
3593
3594 applyShaders();
3595 applyTextures();
3596
3597 if(!getCurrentProgram()->validateSamplers(false))
3598 {
3599 return error(GL_INVALID_OPERATION);
3600 }
3601
3602 if(primitiveCount <= 0)
3603 {
3604 return;
3605 }
3606
3607 TransformFeedback* transformFeedback = getTransformFeedback();
3608 if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3609 {
3610 device->drawPrimitive(primitiveType, primitiveCount);
3611 }
3612 if(transformFeedback)
3613 {
3614 transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
3615 }
3616 }
3617 }
3618
drawElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const void * indices,GLsizei instanceCount)3619 void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3620 {
3621 if(!applyRenderTarget())
3622 {
3623 return;
3624 }
3625
3626 if(mState.currentProgram == 0)
3627 {
3628 return; // Nothing to process.
3629 }
3630
3631 if(count == 0)
3632 {
3633 return;
3634 }
3635
3636 if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3637 {
3638 return error(GL_INVALID_OPERATION);
3639 }
3640
3641 GLenum internalMode = mode;
3642 if(isPrimitiveRestartFixedIndexEnabled())
3643 {
3644 switch(mode)
3645 {
3646 case GL_TRIANGLE_FAN:
3647 case GL_TRIANGLE_STRIP:
3648 internalMode = GL_TRIANGLES;
3649 break;
3650 case GL_LINE_LOOP:
3651 case GL_LINE_STRIP:
3652 internalMode = GL_LINES;
3653 break;
3654 default:
3655 break;
3656 }
3657 }
3658
3659 sw::DrawType primitiveType;
3660 int primitiveCount;
3661 int verticesPerPrimitive;
3662
3663 if(!es2sw::ConvertPrimitiveType(internalMode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
3664 {
3665 return error(GL_INVALID_ENUM);
3666 }
3667
3668 TranslatedIndexData indexInfo(primitiveCount);
3669 GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3670 if(err != GL_NO_ERROR)
3671 {
3672 return error(err);
3673 }
3674
3675 applyState(internalMode);
3676
3677 for(int i = 0; i < instanceCount; ++i)
3678 {
3679 device->setInstanceID(i);
3680
3681 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3682 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3683 if(err != GL_NO_ERROR)
3684 {
3685 return error(err);
3686 }
3687
3688 applyShaders();
3689 applyTextures();
3690
3691 if(!getCurrentProgram()->validateSamplers(false))
3692 {
3693 return error(GL_INVALID_OPERATION);
3694 }
3695
3696 if(primitiveCount <= 0)
3697 {
3698 return;
3699 }
3700
3701 TransformFeedback* transformFeedback = getTransformFeedback();
3702 if(!cullSkipsDraw(internalMode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
3703 {
3704 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, indexInfo.primitiveCount);
3705 }
3706 if(transformFeedback)
3707 {
3708 transformFeedback->addVertexOffset(indexInfo.primitiveCount * verticesPerPrimitive);
3709 }
3710 }
3711 }
3712
blit(sw::Surface * source,const sw::SliceRect & sRect,sw::Surface * dest,const sw::SliceRect & dRect)3713 void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
3714 {
3715 sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
3716 device->blit(source, sRectF, dest, dRect, false);
3717 }
3718
finish()3719 void Context::finish()
3720 {
3721 device->finish();
3722 }
3723
flush()3724 void Context::flush()
3725 {
3726 // We don't queue anything without processing it as fast as possible
3727 }
3728
recordInvalidEnum()3729 void Context::recordInvalidEnum()
3730 {
3731 mInvalidEnum = true;
3732 }
3733
recordInvalidValue()3734 void Context::recordInvalidValue()
3735 {
3736 mInvalidValue = true;
3737 }
3738
recordInvalidOperation()3739 void Context::recordInvalidOperation()
3740 {
3741 mInvalidOperation = true;
3742 }
3743
recordOutOfMemory()3744 void Context::recordOutOfMemory()
3745 {
3746 mOutOfMemory = true;
3747 }
3748
recordInvalidFramebufferOperation()3749 void Context::recordInvalidFramebufferOperation()
3750 {
3751 mInvalidFramebufferOperation = true;
3752 }
3753
3754 // Get one of the recorded errors and clear its flag, if any.
3755 // [OpenGL ES 2.0.24] section 2.5 page 13.
getError()3756 GLenum Context::getError()
3757 {
3758 if(mInvalidEnum)
3759 {
3760 mInvalidEnum = false;
3761
3762 return GL_INVALID_ENUM;
3763 }
3764
3765 if(mInvalidValue)
3766 {
3767 mInvalidValue = false;
3768
3769 return GL_INVALID_VALUE;
3770 }
3771
3772 if(mInvalidOperation)
3773 {
3774 mInvalidOperation = false;
3775
3776 return GL_INVALID_OPERATION;
3777 }
3778
3779 if(mOutOfMemory)
3780 {
3781 mOutOfMemory = false;
3782
3783 return GL_OUT_OF_MEMORY;
3784 }
3785
3786 if(mInvalidFramebufferOperation)
3787 {
3788 mInvalidFramebufferOperation = false;
3789
3790 return GL_INVALID_FRAMEBUFFER_OPERATION;
3791 }
3792
3793 return GL_NO_ERROR;
3794 }
3795
getSupportedMultisampleCount(int requested)3796 int Context::getSupportedMultisampleCount(int requested)
3797 {
3798 int supported = 0;
3799
3800 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3801 {
3802 if(supported >= requested)
3803 {
3804 return supported;
3805 }
3806
3807 supported = multisampleCount[i];
3808 }
3809
3810 return supported;
3811 }
3812
detachBuffer(GLuint buffer)3813 void Context::detachBuffer(GLuint buffer)
3814 {
3815 // [OpenGL ES 2.0.24] section 2.9 page 22:
3816 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3817 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3818
3819 if(mState.copyReadBuffer.name() == buffer)
3820 {
3821 mState.copyReadBuffer = nullptr;
3822 }
3823
3824 if(mState.copyWriteBuffer.name() == buffer)
3825 {
3826 mState.copyWriteBuffer = nullptr;
3827 }
3828
3829 if(mState.pixelPackBuffer.name() == buffer)
3830 {
3831 mState.pixelPackBuffer = nullptr;
3832 }
3833
3834 if(mState.pixelUnpackBuffer.name() == buffer)
3835 {
3836 mState.pixelUnpackBuffer = nullptr;
3837 }
3838
3839 if(mState.genericUniformBuffer.name() == buffer)
3840 {
3841 mState.genericUniformBuffer = nullptr;
3842 }
3843
3844 if(getArrayBufferName() == buffer)
3845 {
3846 mState.arrayBuffer = nullptr;
3847 }
3848
3849 // Only detach from the current transform feedback
3850 TransformFeedback* currentTransformFeedback = getTransformFeedback();
3851 if(currentTransformFeedback)
3852 {
3853 currentTransformFeedback->detachBuffer(buffer);
3854 }
3855
3856 // Only detach from the current vertex array
3857 VertexArray* currentVertexArray = getCurrentVertexArray();
3858 if(currentVertexArray)
3859 {
3860 currentVertexArray->detachBuffer(buffer);
3861 }
3862
3863 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3864 {
3865 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3866 {
3867 mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3868 }
3869 }
3870 }
3871
detachTexture(GLuint texture)3872 void Context::detachTexture(GLuint texture)
3873 {
3874 // [OpenGL ES 2.0.24] section 3.8 page 84:
3875 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3876 // rebound to texture object zero
3877
3878 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3879 {
3880 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3881 {
3882 if(mState.samplerTexture[type][sampler].name() == texture)
3883 {
3884 mState.samplerTexture[type][sampler] = nullptr;
3885 }
3886 }
3887 }
3888
3889 // [OpenGL ES 2.0.24] section 4.4 page 112:
3890 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3891 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3892 // image was attached in the currently bound framebuffer.
3893
3894 Framebuffer *readFramebuffer = getReadFramebuffer();
3895 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3896
3897 if(readFramebuffer)
3898 {
3899 readFramebuffer->detachTexture(texture);
3900 }
3901
3902 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3903 {
3904 drawFramebuffer->detachTexture(texture);
3905 }
3906 }
3907
detachFramebuffer(GLuint framebuffer)3908 void Context::detachFramebuffer(GLuint framebuffer)
3909 {
3910 // [OpenGL ES 2.0.24] section 4.4 page 107:
3911 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3912 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3913
3914 if(mState.readFramebuffer == framebuffer)
3915 {
3916 bindReadFramebuffer(0);
3917 }
3918
3919 if(mState.drawFramebuffer == framebuffer)
3920 {
3921 bindDrawFramebuffer(0);
3922 }
3923 }
3924
detachRenderbuffer(GLuint renderbuffer)3925 void Context::detachRenderbuffer(GLuint renderbuffer)
3926 {
3927 // [OpenGL ES 2.0.24] section 4.4 page 109:
3928 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3929 // had been executed with the target RENDERBUFFER and name of zero.
3930
3931 if(mState.renderbuffer.name() == renderbuffer)
3932 {
3933 bindRenderbuffer(0);
3934 }
3935
3936 // [OpenGL ES 2.0.24] section 4.4 page 111:
3937 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3938 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3939 // point to which this image was attached in the currently bound framebuffer.
3940
3941 Framebuffer *readFramebuffer = getReadFramebuffer();
3942 Framebuffer *drawFramebuffer = getDrawFramebuffer();
3943
3944 if(readFramebuffer)
3945 {
3946 readFramebuffer->detachRenderbuffer(renderbuffer);
3947 }
3948
3949 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3950 {
3951 drawFramebuffer->detachRenderbuffer(renderbuffer);
3952 }
3953 }
3954
detachSampler(GLuint sampler)3955 void Context::detachSampler(GLuint sampler)
3956 {
3957 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3958 // If a sampler object that is currently bound to one or more texture units is
3959 // deleted, it is as though BindSampler is called once for each texture unit to
3960 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3961 for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
3962 {
3963 gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
3964 if(samplerBinding.name() == sampler)
3965 {
3966 samplerBinding = nullptr;
3967 }
3968 }
3969 }
3970
cullSkipsDraw(GLenum drawMode)3971 bool Context::cullSkipsDraw(GLenum drawMode)
3972 {
3973 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3974 }
3975
isTriangleMode(GLenum drawMode)3976 bool Context::isTriangleMode(GLenum drawMode)
3977 {
3978 switch(drawMode)
3979 {
3980 case GL_TRIANGLES:
3981 case GL_TRIANGLE_FAN:
3982 case GL_TRIANGLE_STRIP:
3983 return true;
3984 case GL_POINTS:
3985 case GL_LINES:
3986 case GL_LINE_LOOP:
3987 case GL_LINE_STRIP:
3988 return false;
3989 default: UNREACHABLE(drawMode);
3990 }
3991
3992 return false;
3993 }
3994
setVertexAttrib(GLuint index,const GLfloat * values)3995 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3996 {
3997 ASSERT(index < MAX_VERTEX_ATTRIBS);
3998
3999 mState.vertexAttribute[index].setCurrentValue(values);
4000
4001 mVertexDataManager->dirtyCurrentValue(index);
4002 }
4003
setVertexAttrib(GLuint index,const GLint * values)4004 void Context::setVertexAttrib(GLuint index, const GLint *values)
4005 {
4006 ASSERT(index < MAX_VERTEX_ATTRIBS);
4007
4008 mState.vertexAttribute[index].setCurrentValue(values);
4009
4010 mVertexDataManager->dirtyCurrentValue(index);
4011 }
4012
setVertexAttrib(GLuint index,const GLuint * values)4013 void Context::setVertexAttrib(GLuint index, const GLuint *values)
4014 {
4015 ASSERT(index < MAX_VERTEX_ATTRIBS);
4016
4017 mState.vertexAttribute[index].setCurrentValue(values);
4018
4019 mVertexDataManager->dirtyCurrentValue(index);
4020 }
4021
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,bool filter,bool allowPartialDepthStencilBlit)4022 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4023 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4024 GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit)
4025 {
4026 Framebuffer *readFramebuffer = getReadFramebuffer();
4027 Framebuffer *drawFramebuffer = getDrawFramebuffer();
4028
4029 int readBufferWidth, readBufferHeight, readBufferSamples;
4030 int drawBufferWidth, drawBufferHeight, drawBufferSamples;
4031
4032 if(!readFramebuffer || (readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE) ||
4033 !drawFramebuffer || (drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE))
4034 {
4035 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
4036 }
4037
4038 if(drawBufferSamples > 1)
4039 {
4040 return error(GL_INVALID_OPERATION);
4041 }
4042
4043 sw::SliceRect sourceRect;
4044 sw::SliceRect destRect;
4045 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
4046 bool flipY = (srcY0 < srcY1) ^ (dstY0 < dstY1);
4047
4048 if(srcX0 < srcX1)
4049 {
4050 sourceRect.x0 = srcX0;
4051 sourceRect.x1 = srcX1;
4052 }
4053 else
4054 {
4055 sourceRect.x0 = srcX1;
4056 sourceRect.x1 = srcX0;
4057 }
4058
4059 if(dstX0 < dstX1)
4060 {
4061 destRect.x0 = dstX0;
4062 destRect.x1 = dstX1;
4063 }
4064 else
4065 {
4066 destRect.x0 = dstX1;
4067 destRect.x1 = dstX0;
4068 }
4069
4070 if(srcY0 < srcY1)
4071 {
4072 sourceRect.y0 = srcY0;
4073 sourceRect.y1 = srcY1;
4074 }
4075 else
4076 {
4077 sourceRect.y0 = srcY1;
4078 sourceRect.y1 = srcY0;
4079 }
4080
4081 if(dstY0 < dstY1)
4082 {
4083 destRect.y0 = dstY0;
4084 destRect.y1 = dstY1;
4085 }
4086 else
4087 {
4088 destRect.y0 = dstY1;
4089 destRect.y1 = dstY0;
4090 }
4091
4092 sw::RectF sourceScissoredRect(static_cast<float>(sourceRect.x0), static_cast<float>(sourceRect.y0),
4093 static_cast<float>(sourceRect.x1), static_cast<float>(sourceRect.y1));
4094 sw::Rect destScissoredRect = destRect;
4095
4096 if(mState.scissorTestEnabled) // Only write to parts of the destination framebuffer which pass the scissor test
4097 {
4098 sw::Rect scissorRect(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
4099 Device::ClipDstRect(sourceScissoredRect, destScissoredRect, scissorRect, flipX, flipY);
4100 }
4101
4102 sw::SliceRectF sourceTrimmedRect = sourceScissoredRect;
4103 sw::SliceRect destTrimmedRect = destScissoredRect;
4104
4105 // The source & destination rectangles also may need to be trimmed if
4106 // they fall out of the bounds of the actual draw and read surfaces.
4107 sw::Rect sourceTrimRect(0, 0, readBufferWidth, readBufferHeight);
4108 Device::ClipSrcRect(sourceTrimmedRect, destTrimmedRect, sourceTrimRect, flipX, flipY);
4109
4110 sw::Rect destTrimRect(0, 0, drawBufferWidth, drawBufferHeight);
4111 Device::ClipDstRect(sourceTrimmedRect, destTrimmedRect, destTrimRect, flipX, flipY);
4112
4113 bool partialBufferCopy = false;
4114
4115 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4116 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4117 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4118 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4119 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4120 {
4121 partialBufferCopy = true;
4122 }
4123
4124 bool sameBounds = (srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1);
4125 bool blitRenderTarget = false;
4126 bool blitDepth = false;
4127 bool blitStencil = false;
4128
4129 if(mask & GL_COLOR_BUFFER_BIT)
4130 {
4131 GLenum readColorbufferType = readFramebuffer->getReadBufferType();
4132 GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
4133 const bool validReadType = readColorbufferType == GL_TEXTURE_2D || readColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(readColorbufferType);
4134 const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || drawColorbufferType == GL_TEXTURE_RECTANGLE_ARB || Framebuffer::IsRenderbuffer(drawColorbufferType);
4135 if(!validReadType || !validDrawType)
4136 {
4137 return error(GL_INVALID_OPERATION);
4138 }
4139
4140 if(partialBufferCopy && readBufferSamples > 1 && !sameBounds)
4141 {
4142 return error(GL_INVALID_OPERATION);
4143 }
4144
4145 // The GL ES 3.0.2 spec (pg 193) states that:
4146 // 1) If the read buffer is fixed point format, the draw buffer must be as well
4147 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
4148 // as well
4149 // 3) If the read buffer is a signed integer format, the draw buffer must be as
4150 // well
4151 es2::Renderbuffer *readRenderbuffer = readFramebuffer->getReadColorbuffer();
4152 es2::Renderbuffer *drawRenderbuffer = drawFramebuffer->getColorbuffer(0);
4153 GLint readFormat = readRenderbuffer->getFormat();
4154 GLint drawFormat = drawRenderbuffer->getFormat();
4155 GLenum readComponentType = GetComponentType(readFormat, GL_COLOR_ATTACHMENT0);
4156 GLenum drawComponentType = GetComponentType(drawFormat, GL_COLOR_ATTACHMENT0);
4157 bool readFixedPoint = ((readComponentType == GL_UNSIGNED_NORMALIZED) ||
4158 (readComponentType == GL_SIGNED_NORMALIZED));
4159 bool drawFixedPoint = ((drawComponentType == GL_UNSIGNED_NORMALIZED) ||
4160 (drawComponentType == GL_SIGNED_NORMALIZED));
4161 bool readFixedOrFloat = (readFixedPoint || (readComponentType == GL_FLOAT));
4162 bool drawFixedOrFloat = (drawFixedPoint || (drawComponentType == GL_FLOAT));
4163
4164 if(readFixedOrFloat != drawFixedOrFloat)
4165 {
4166 return error(GL_INVALID_OPERATION);
4167 }
4168
4169 if((readComponentType == GL_UNSIGNED_INT) && (drawComponentType != GL_UNSIGNED_INT))
4170 {
4171 return error(GL_INVALID_OPERATION);
4172 }
4173
4174 if((readComponentType == GL_INT) && (drawComponentType != GL_INT))
4175 {
4176 return error(GL_INVALID_OPERATION);
4177 }
4178
4179 // Cannot filter integer data
4180 if(((readComponentType == GL_UNSIGNED_INT) || (readComponentType == GL_INT)) && filter)
4181 {
4182 return error(GL_INVALID_OPERATION);
4183 }
4184
4185 if((readRenderbuffer->getSamples() > 0) && (readFormat != drawFormat))
4186 {
4187 // RGBA8 and BGRA8 should be interchangeable here
4188 if(!(((readFormat == GL_RGBA8) && (drawFormat == GL_BGRA8_EXT)) ||
4189 ((readFormat == GL_BGRA8_EXT) && (drawFormat == GL_RGBA8))))
4190 {
4191 return error(GL_INVALID_OPERATION);
4192 }
4193 }
4194
4195 blitRenderTarget = true;
4196 }
4197
4198 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4199 {
4200 Renderbuffer *readDSBuffer = nullptr;
4201 Renderbuffer *drawDSBuffer = nullptr;
4202
4203 if(mask & GL_DEPTH_BUFFER_BIT)
4204 {
4205 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4206 {
4207 GLenum readDepthBufferType = readFramebuffer->getDepthbufferType();
4208 GLenum drawDepthBufferType = drawFramebuffer->getDepthbufferType();
4209 if((readDepthBufferType != drawDepthBufferType) &&
4210 !(Framebuffer::IsRenderbuffer(readDepthBufferType) && Framebuffer::IsRenderbuffer(drawDepthBufferType)))
4211 {
4212 return error(GL_INVALID_OPERATION);
4213 }
4214
4215 blitDepth = true;
4216 readDSBuffer = readFramebuffer->getDepthbuffer();
4217 drawDSBuffer = drawFramebuffer->getDepthbuffer();
4218
4219 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4220 {
4221 return error(GL_INVALID_OPERATION);
4222 }
4223 }
4224 }
4225
4226 if(mask & GL_STENCIL_BUFFER_BIT)
4227 {
4228 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4229 {
4230 GLenum readStencilBufferType = readFramebuffer->getStencilbufferType();
4231 GLenum drawStencilBufferType = drawFramebuffer->getStencilbufferType();
4232 if((readStencilBufferType != drawStencilBufferType) &&
4233 !(Framebuffer::IsRenderbuffer(readStencilBufferType) && Framebuffer::IsRenderbuffer(drawStencilBufferType)))
4234 {
4235 return error(GL_INVALID_OPERATION);
4236 }
4237
4238 blitStencil = true;
4239 readDSBuffer = readFramebuffer->getStencilbuffer();
4240 drawDSBuffer = drawFramebuffer->getStencilbuffer();
4241
4242 if(readDSBuffer->getFormat() != drawDSBuffer->getFormat())
4243 {
4244 return error(GL_INVALID_OPERATION);
4245 }
4246 }
4247 }
4248
4249 if(partialBufferCopy && !allowPartialDepthStencilBlit)
4250 {
4251 ERR("Only whole-buffer depth and stencil blits are supported by ANGLE_framebuffer_blit.");
4252 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted
4253 }
4254
4255 // OpenGL ES 3.0.4 spec, p.199:
4256 // ...an INVALID_OPERATION error is generated if the formats of the read
4257 // and draw framebuffers are not identical or if the source and destination
4258 // rectangles are not defined with the same(X0, Y 0) and (X1, Y 1) bounds.
4259 // If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, an
4260 // INVALID_OPERATION error is generated.
4261 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4262 ((readDSBuffer && readDSBuffer->getSamples() > 1) &&
4263 (!sameBounds || (drawDSBuffer->getFormat() != readDSBuffer->getFormat()))))
4264 {
4265 return error(GL_INVALID_OPERATION);
4266 }
4267 }
4268
4269 if(blitRenderTarget || blitDepth || blitStencil)
4270 {
4271 if(flipX)
4272 {
4273 swap(destTrimmedRect.x0, destTrimmedRect.x1);
4274 }
4275 if(flipY)
4276 {
4277 swap(destTrimmedRect.y0, destTrimmedRect.y1);
4278 }
4279
4280 if(blitRenderTarget)
4281 {
4282 egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4283 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4284
4285 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::COLOR_BUFFER);
4286
4287 readRenderTarget->release();
4288 drawRenderTarget->release();
4289
4290 if(!success)
4291 {
4292 ERR("BlitFramebuffer failed.");
4293 return;
4294 }
4295 }
4296
4297 if(blitDepth)
4298 {
4299 egl::Image *readRenderTarget = readFramebuffer->getDepthBuffer();
4300 egl::Image *drawRenderTarget = drawFramebuffer->getDepthBuffer();
4301
4302 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::DEPTH_BUFFER);
4303
4304 readRenderTarget->release();
4305 drawRenderTarget->release();
4306
4307 if(!success)
4308 {
4309 ERR("BlitFramebuffer failed.");
4310 return;
4311 }
4312 }
4313
4314 if(blitStencil)
4315 {
4316 egl::Image *readRenderTarget = readFramebuffer->getStencilBuffer();
4317 egl::Image *drawRenderTarget = drawFramebuffer->getStencilBuffer();
4318
4319 bool success = device->stretchRect(readRenderTarget, &sourceTrimmedRect, drawRenderTarget, &destTrimmedRect, (filter ? Device::USE_FILTER : 0) | Device::STENCIL_BUFFER);
4320
4321 readRenderTarget->release();
4322 drawRenderTarget->release();
4323
4324 if(!success)
4325 {
4326 ERR("BlitFramebuffer failed.");
4327 return;
4328 }
4329 }
4330 }
4331 }
4332
bindTexImage(gl::Surface * surface)4333 void Context::bindTexImage(gl::Surface *surface)
4334 {
4335 bool isRect = (surface->getTextureTarget() == EGL_TEXTURE_RECTANGLE_ANGLE);
4336 es2::Texture2D *textureObject = isRect ? getTexture2DRect() : getTexture2D();
4337
4338 if(textureObject)
4339 {
4340 textureObject->bindTexImage(surface);
4341 }
4342 }
4343
validateSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4344 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4345 {
4346 GLenum textureTarget = GL_NONE;
4347
4348 switch(target)
4349 {
4350 case EGL_GL_TEXTURE_2D_KHR:
4351 textureTarget = GL_TEXTURE_2D;
4352 break;
4353 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
4354 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
4355 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
4356 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
4357 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
4358 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
4359 textureTarget = GL_TEXTURE_CUBE_MAP;
4360 break;
4361 case EGL_GL_RENDERBUFFER_KHR:
4362 break;
4363 default:
4364 return EGL_BAD_PARAMETER;
4365 }
4366
4367 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4368 {
4369 return EGL_BAD_MATCH;
4370 }
4371
4372 if(textureTarget != GL_NONE)
4373 {
4374 es2::Texture *texture = getTexture(name);
4375
4376 if(!texture || texture->getTarget() != textureTarget)
4377 {
4378 return EGL_BAD_PARAMETER;
4379 }
4380
4381 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
4382 {
4383 return EGL_BAD_ACCESS;
4384 }
4385
4386 if(textureLevel != 0 && !texture->isSamplerComplete(nullptr))
4387 {
4388 return EGL_BAD_PARAMETER;
4389 }
4390
4391 if(textureLevel == 0 && !(texture->isSamplerComplete(nullptr) && texture->getTopLevel() == 0))
4392 {
4393 return EGL_BAD_PARAMETER;
4394 }
4395 }
4396 else if(target == EGL_GL_RENDERBUFFER_KHR)
4397 {
4398 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4399
4400 if(!renderbuffer)
4401 {
4402 return EGL_BAD_PARAMETER;
4403 }
4404
4405 if(renderbuffer->isShared()) // Already an EGLImage sibling
4406 {
4407 return EGL_BAD_ACCESS;
4408 }
4409 }
4410 else UNREACHABLE(target);
4411
4412 return EGL_SUCCESS;
4413 }
4414
createSharedImage(EGLenum target,GLuint name,GLuint textureLevel)4415 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4416 {
4417 GLenum textureTarget = GL_NONE;
4418
4419 switch(target)
4420 {
4421 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break;
4422 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4423 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4424 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4425 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4426 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4427 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4428 }
4429
4430 if(textureTarget != GL_NONE)
4431 {
4432 es2::Texture *texture = getTexture(name);
4433
4434 return texture->createSharedImage(textureTarget, textureLevel);
4435 }
4436 else if(target == EGL_GL_RENDERBUFFER_KHR)
4437 {
4438 es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4439
4440 return renderbuffer->createSharedImage();
4441 }
4442 else UNREACHABLE(target);
4443
4444 return nullptr;
4445 }
4446
getSharedImage(GLeglImageOES image)4447 egl::Image *Context::getSharedImage(GLeglImageOES image)
4448 {
4449 return display->getSharedImage(image);
4450 }
4451
getDevice()4452 Device *Context::getDevice()
4453 {
4454 return device;
4455 }
4456
getExtensions(GLuint index,GLuint * numExt) const4457 const GLubyte *Context::getExtensions(GLuint index, GLuint *numExt) const
4458 {
4459 // Keep list sorted in following order:
4460 // OES extensions
4461 // EXT extensions
4462 // Vendor extensions
4463 static const char *extensions[] =
4464 {
4465 "GL_OES_compressed_ETC1_RGB8_texture",
4466 "GL_OES_depth24",
4467 "GL_OES_depth32",
4468 "GL_OES_depth_texture",
4469 "GL_OES_depth_texture_cube_map",
4470 "GL_OES_EGL_image",
4471 "GL_OES_EGL_image_external",
4472 "GL_OES_EGL_image_external_essl3", // client version is always 3, so this is fine
4473 "GL_OES_EGL_sync",
4474 "GL_OES_element_index_uint",
4475 "GL_OES_fbo_render_mipmap",
4476 "GL_OES_framebuffer_object",
4477 "GL_OES_packed_depth_stencil",
4478 "GL_OES_rgb8_rgba8",
4479 "GL_OES_standard_derivatives",
4480 "GL_OES_surfaceless_context",
4481 "GL_OES_texture_float",
4482 "GL_OES_texture_float_linear",
4483 "GL_OES_texture_half_float",
4484 "GL_OES_texture_half_float_linear",
4485 "GL_OES_texture_npot",
4486 "GL_OES_texture_3D",
4487 "GL_OES_vertex_array_object",
4488 "GL_OES_vertex_half_float",
4489 "GL_EXT_blend_minmax",
4490 "GL_EXT_color_buffer_float", // OpenGL ES 3.0 specific.
4491 "GL_EXT_color_buffer_half_float",
4492 "GL_EXT_draw_buffers",
4493 "GL_EXT_instanced_arrays",
4494 "GL_EXT_occlusion_query_boolean",
4495 "GL_EXT_read_format_bgra",
4496 "GL_EXT_texture_compression_dxt1",
4497 "GL_EXT_texture_filter_anisotropic",
4498 "GL_EXT_texture_format_BGRA8888",
4499 "GL_EXT_texture_rg",
4500 #if (ASTC_SUPPORT)
4501 "GL_KHR_texture_compression_astc_hdr",
4502 "GL_KHR_texture_compression_astc_ldr",
4503 #endif
4504 "GL_ARB_texture_rectangle",
4505 "GL_ANGLE_framebuffer_blit",
4506 "GL_ANGLE_framebuffer_multisample",
4507 "GL_ANGLE_instanced_arrays",
4508 "GL_ANGLE_texture_compression_dxt3",
4509 "GL_ANGLE_texture_compression_dxt5",
4510 "GL_APPLE_texture_format_BGRA8888",
4511 "GL_CHROMIUM_color_buffer_float_rgba", // A subset of EXT_color_buffer_float on top of OpenGL ES 2.0
4512 "GL_CHROMIUM_texture_filtering_hint",
4513 "GL_NV_depth_buffer_float2",
4514 "GL_NV_fence",
4515 "GL_NV_framebuffer_blit",
4516 "GL_NV_read_depth",
4517 "GL_NV_read_depth_stencil",
4518 "GL_NV_read_stencil",
4519 };
4520
4521 GLuint numExtensions = sizeof(extensions) / sizeof(extensions[0]);
4522
4523 if(numExt)
4524 {
4525 *numExt = numExtensions;
4526
4527 return nullptr;
4528 }
4529
4530 if(index == GL_INVALID_INDEX)
4531 {
4532 static std::string extensionsCat;
4533
4534 if(extensionsCat.empty() && (numExtensions > 0))
4535 {
4536 for(const char *extension : extensions)
4537 {
4538 extensionsCat += std::string(extension) + " ";
4539 }
4540 }
4541
4542 return (const GLubyte*)extensionsCat.c_str();
4543 }
4544
4545 if(index >= numExtensions)
4546 {
4547 return nullptr;
4548 }
4549
4550 return (const GLubyte*)extensions[index];
4551 }
4552
4553 }
4554
es2CreateContext(egl::Display * display,const egl::Context * shareContext,const egl::Config * config)4555 NO_SANITIZE_FUNCTION egl::Context *es2CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
4556 {
4557 return new es2::Context(display, static_cast<const es2::Context*>(shareContext), config);
4558 }
4559