blob: 45c26ee8852a30a764001a2afbdce76ae4aec728 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// 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 es1::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 "Framebuffer.h"
26#include "Renderbuffer.h"
27#include "Texture.h"
28#include "VertexDataManager.h"
29#include "IndexDataManager.h"
30#include "libEGL/Display.h"
Nicolas Capens31c07a32017-06-13 23:44:13 -040031#include "common/Surface.hpp"
Nicolas Capens0bac2852016-05-07 06:09:58 -040032#include "Common/Half.hpp"
33
34#include <EGL/eglext.h>
35
36using std::abs;
37
38namespace es1
39{
Nicolas Capensf6a377b2017-05-19 09:31:35 -040040Context::Context(egl::Display *const display, const Context *shareContext, const egl::Config *config)
41 : egl::Context(display), config(config),
Nicolas Capense7e70d02016-06-07 14:40:12 -040042 modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
Nicolas Capens0bac2852016-05-07 06:09:58 -040043 projectionStack(MAX_PROJECTION_STACK_DEPTH),
44 textureStack0(MAX_TEXTURE_STACK_DEPTH),
45 textureStack1(MAX_TEXTURE_STACK_DEPTH)
46{
47 sw::Context *context = new sw::Context();
48 device = new es1::Device(context);
49
50 mVertexDataManager = new VertexDataManager(this);
51 mIndexDataManager = new IndexDataManager();
52
53 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
54
55 mState.depthClearValue = 1.0f;
56 mState.stencilClearValue = 0;
57
58 mState.cullFaceEnabled = false;
59 mState.cullMode = GL_BACK;
60 mState.frontFace = GL_CCW;
61 mState.depthTestEnabled = false;
62 mState.depthFunc = GL_LESS;
63 mState.blendEnabled = false;
64 mState.sourceBlendRGB = GL_ONE;
65 mState.sourceBlendAlpha = GL_ONE;
66 mState.destBlendRGB = GL_ZERO;
67 mState.destBlendAlpha = GL_ZERO;
68 mState.blendEquationRGB = GL_FUNC_ADD_OES;
69 mState.blendEquationAlpha = GL_FUNC_ADD_OES;
70 mState.stencilTestEnabled = false;
71 mState.stencilFunc = GL_ALWAYS;
72 mState.stencilRef = 0;
73 mState.stencilMask = -1;
74 mState.stencilWritemask = -1;
75 mState.stencilFail = GL_KEEP;
76 mState.stencilPassDepthFail = GL_KEEP;
77 mState.stencilPassDepthPass = GL_KEEP;
78 mState.polygonOffsetFillEnabled = false;
79 mState.polygonOffsetFactor = 0.0f;
80 mState.polygonOffsetUnits = 0.0f;
81 mState.sampleAlphaToCoverageEnabled = false;
82 mState.sampleCoverageEnabled = false;
83 mState.sampleCoverageValue = 1.0f;
84 mState.sampleCoverageInvert = false;
85 mState.scissorTestEnabled = false;
86 mState.ditherEnabled = true;
87 mState.shadeModel = GL_SMOOTH;
88 mState.generateMipmapHint = GL_DONT_CARE;
89 mState.perspectiveCorrectionHint = GL_DONT_CARE;
90 mState.fogHint = GL_DONT_CARE;
91
92 mState.lineWidth = 1.0f;
93
94 mState.viewportX = 0;
95 mState.viewportY = 0;
96 mState.viewportWidth = 0;
97 mState.viewportHeight = 0;
98 mState.zNear = 0.0f;
99 mState.zFar = 1.0f;
100
101 mState.scissorX = 0;
102 mState.scissorY = 0;
103 mState.scissorWidth = 0;
104 mState.scissorHeight = 0;
105
106 mState.colorMaskRed = true;
107 mState.colorMaskGreen = true;
108 mState.colorMaskBlue = true;
109 mState.colorMaskAlpha = true;
110 mState.depthMask = true;
111
112 for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
113 {
114 mState.textureUnit[i].color = {0, 0, 0, 0};
115 mState.textureUnit[i].environmentMode = GL_MODULATE;
116 mState.textureUnit[i].combineRGB = GL_MODULATE;
117 mState.textureUnit[i].combineAlpha = GL_MODULATE;
118 mState.textureUnit[i].src0RGB = GL_TEXTURE;
119 mState.textureUnit[i].src1RGB = GL_PREVIOUS;
120 mState.textureUnit[i].src2RGB = GL_CONSTANT;
121 mState.textureUnit[i].src0Alpha = GL_TEXTURE;
122 mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
123 mState.textureUnit[i].src2Alpha = GL_CONSTANT;
124 mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
125 mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
126 mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
127 mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
128 mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
129 mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
130 }
131
132 if(shareContext)
133 {
134 mResourceManager = shareContext->mResourceManager;
135 mResourceManager->addRef();
136 }
137 else
138 {
139 mResourceManager = new ResourceManager();
140 }
141
142 // [OpenGL ES 2.0.24] section 3.7 page 83:
143 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
144 // and cube map texture state vectors respectively associated with them.
145 // In order that access to these initial textures not be lost, they are treated as texture
146 // objects all of whose names are 0.
147
148 mTexture2DZero = new Texture2D(0);
149 mTextureExternalZero = new TextureExternal(0);
150
151 mState.activeSampler = 0;
Nicolas Capens2ce08b12018-03-02 12:37:47 -0500152
153 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
154 {
155 bindTexture((TextureType)type, 0);
156 }
157
Nicolas Capens0bac2852016-05-07 06:09:58 -0400158 bindArrayBuffer(0);
159 bindElementArrayBuffer(0);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400160 bindFramebuffer(0);
161 bindRenderbuffer(0);
162
163 mState.packAlignment = 4;
164 mState.unpackAlignment = 4;
165
166 mInvalidEnum = false;
167 mInvalidValue = false;
168 mInvalidOperation = false;
169 mOutOfMemory = false;
170 mInvalidFramebufferOperation = false;
171 mMatrixStackOverflow = false;
172 mMatrixStackUnderflow = false;
173
174 lightingEnabled = false;
175
176 for(int i = 0; i < MAX_LIGHTS; i++)
177 {
178 light[i].enabled = false;
179 light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
180 light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
181 light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
182 light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
183 light[i].direction = {0.0f, 0.0f, -1.0f};
184 light[i].attenuation = {1.0f, 0.0f, 0.0f};
185 light[i].spotExponent = 0.0f;
186 light[i].spotCutoffAngle = 180.0f;
187 }
188
189 light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
190 light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
191
192 globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
193 materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
194 materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
195 materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
196 materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
197 materialShininess = 0.0f;
198 lightModelTwoSide = false;
199
200 matrixMode = GL_MODELVIEW;
201
202 for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
203 {
204 texture2Denabled[i] = false;
205 textureExternalEnabled[i] = false;
206 }
207
208 clientTexture = GL_TEXTURE0;
209
210 setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
211
212 for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
213 {
214 setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
215 }
216
217 setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
218 setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
219
220 clipFlags = 0;
221
222 alphaTestEnabled = false;
223 alphaTestFunc = GL_ALWAYS;
224 alphaTestRef = 0;
225
226 fogEnabled = false;
227 fogMode = GL_EXP;
228 fogDensity = 1.0f;
229 fogStart = 0.0f;
230 fogEnd = 1.0f;
231 fogColor = {0, 0, 0, 0};
232
233 lineSmoothEnabled = false;
234 colorMaterialEnabled = false;
235 normalizeEnabled = false;
236 rescaleNormalEnabled = false;
237 multisampleEnabled = true;
238 sampleAlphaToOneEnabled = false;
239
240 colorLogicOpEnabled = false;
241 logicalOperation = GL_COPY;
242
243 pointSpriteEnabled = false;
244 pointSmoothEnabled = false;
245 pointSizeMin = 0.0f;
246 pointSizeMax = 1.0f;
247 pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
248 pointFadeThresholdSize = 1.0f;
249
250 mHasBeenCurrent = false;
251
252 markAllStateDirty();
253}
254
255Context::~Context()
256{
257 while(!mFramebufferNameSpace.empty())
258 {
259 deleteFramebuffer(mFramebufferNameSpace.firstName());
260 }
261
262 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
263 {
264 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
265 {
266 mState.samplerTexture[type][sampler] = nullptr;
267 }
268 }
269
270 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
271 {
272 mState.vertexAttribute[i].mBoundBuffer = nullptr;
273 }
274
275 mState.arrayBuffer = nullptr;
276 mState.elementArrayBuffer = nullptr;
277 mState.renderbuffer = nullptr;
278
279 mTexture2DZero = nullptr;
280 mTextureExternalZero = nullptr;
281
282 delete mVertexDataManager;
283 delete mIndexDataManager;
284
285 mResourceManager->release();
286 delete device;
287}
288
Nicolas Capens31c07a32017-06-13 23:44:13 -0400289void Context::makeCurrent(gl::Surface *surface)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400290{
291 if(!mHasBeenCurrent)
292 {
293 mState.viewportX = 0;
294 mState.viewportY = 0;
Alexis Hetu5cd502b2018-03-22 08:29:31 -0400295 mState.viewportWidth = surface ? surface->getWidth() : 0;
296 mState.viewportHeight = surface ? surface->getHeight() : 0;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400297
298 mState.scissorX = 0;
299 mState.scissorY = 0;
Alexis Hetu5cd502b2018-03-22 08:29:31 -0400300 mState.scissorWidth = surface ? surface->getWidth() : 0;
301 mState.scissorHeight = surface ? surface->getHeight() : 0;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400302
303 mHasBeenCurrent = true;
304 }
305
306 // Wrap the existing resources into GL objects and assign them to the '0' names
Alexis Hetu5cd502b2018-03-22 08:29:31 -0400307 egl::Image *defaultRenderTarget = surface ? surface->getRenderTarget() : nullptr;
308 egl::Image *depthStencil = surface ? surface->getDepthStencil() : nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400309
310 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
311 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
312 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
313
314 setFramebufferZero(framebufferZero);
315
316 if(defaultRenderTarget)
317 {
318 defaultRenderTarget->release();
319 }
320
321 if(depthStencil)
322 {
323 depthStencil->release();
324 }
325
326 markAllStateDirty();
327}
328
Nicolas Capensf6a377b2017-05-19 09:31:35 -0400329EGLint Context::getClientVersion() const
Nicolas Capens0bac2852016-05-07 06:09:58 -0400330{
331 return 1;
332}
333
Nicolas Capensf6a377b2017-05-19 09:31:35 -0400334EGLint Context::getConfigID() const
335{
336 return config->mConfigID;
337}
338
Nicolas Capens0bac2852016-05-07 06:09:58 -0400339// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
340void Context::markAllStateDirty()
341{
342 mDepthStateDirty = true;
343 mMaskStateDirty = true;
344 mBlendStateDirty = true;
345 mStencilStateDirty = true;
346 mPolygonOffsetStateDirty = true;
347 mSampleStateDirty = true;
348 mDitherStateDirty = true;
349 mFrontFaceDirty = true;
350}
351
352void Context::setClearColor(float red, float green, float blue, float alpha)
353{
354 mState.colorClearValue.red = red;
355 mState.colorClearValue.green = green;
356 mState.colorClearValue.blue = blue;
357 mState.colorClearValue.alpha = alpha;
358}
359
360void Context::setClearDepth(float depth)
361{
362 mState.depthClearValue = depth;
363}
364
365void Context::setClearStencil(int stencil)
366{
367 mState.stencilClearValue = stencil;
368}
369
370void Context::setCullFaceEnabled(bool enabled)
371{
372 mState.cullFaceEnabled = enabled;
373}
374
375bool Context::isCullFaceEnabled() const
376{
377 return mState.cullFaceEnabled;
378}
379
380void Context::setCullMode(GLenum mode)
381{
382 mState.cullMode = mode;
383}
384
385void Context::setFrontFace(GLenum front)
386{
387 if(mState.frontFace != front)
388 {
389 mState.frontFace = front;
390 mFrontFaceDirty = true;
391 }
392}
393
394void Context::setDepthTestEnabled(bool enabled)
395{
396 if(mState.depthTestEnabled != enabled)
397 {
398 mState.depthTestEnabled = enabled;
399 mDepthStateDirty = true;
400 }
401}
402
403bool Context::isDepthTestEnabled() const
404{
405 return mState.depthTestEnabled;
406}
407
408void Context::setDepthFunc(GLenum depthFunc)
409{
410 if(mState.depthFunc != depthFunc)
411 {
412 mState.depthFunc = depthFunc;
413 mDepthStateDirty = true;
414 }
415}
416
417void Context::setDepthRange(float zNear, float zFar)
418{
419 mState.zNear = zNear;
420 mState.zFar = zFar;
421}
422
423void Context::setAlphaTestEnabled(bool enabled)
424{
425 alphaTestEnabled = enabled;
426}
427
428bool Context::isAlphaTestEnabled() const
429{
430 return alphaTestEnabled;
431}
432
433void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)
434{
435 alphaTestFunc = alphaFunc;
436 alphaTestRef = reference;
437}
438
439void Context::setBlendEnabled(bool enabled)
440{
441 if(mState.blendEnabled != enabled)
442 {
443 mState.blendEnabled = enabled;
444 mBlendStateDirty = true;
445 }
446}
447
448bool Context::isBlendEnabled() const
449{
450 return mState.blendEnabled;
451}
452
453void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
454{
455 if(mState.sourceBlendRGB != sourceRGB ||
456 mState.sourceBlendAlpha != sourceAlpha ||
457 mState.destBlendRGB != destRGB ||
458 mState.destBlendAlpha != destAlpha)
459 {
460 mState.sourceBlendRGB = sourceRGB;
461 mState.destBlendRGB = destRGB;
462 mState.sourceBlendAlpha = sourceAlpha;
463 mState.destBlendAlpha = destAlpha;
464 mBlendStateDirty = true;
465 }
466}
467
468void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
469{
470 if(mState.blendEquationRGB != rgbEquation ||
471 mState.blendEquationAlpha != alphaEquation)
472 {
473 mState.blendEquationRGB = rgbEquation;
474 mState.blendEquationAlpha = alphaEquation;
475 mBlendStateDirty = true;
476 }
477}
478
479void Context::setStencilTestEnabled(bool enabled)
480{
481 if(mState.stencilTestEnabled != enabled)
482 {
483 mState.stencilTestEnabled = enabled;
484 mStencilStateDirty = true;
485 }
486}
487
488bool Context::isStencilTestEnabled() const
489{
490 return mState.stencilTestEnabled;
491}
492
493void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
494{
495 if(mState.stencilFunc != stencilFunc ||
496 mState.stencilRef != stencilRef ||
497 mState.stencilMask != stencilMask)
498 {
499 mState.stencilFunc = stencilFunc;
500 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
501 mState.stencilMask = stencilMask;
502 mStencilStateDirty = true;
503 }
504}
505
506void Context::setStencilWritemask(GLuint stencilWritemask)
507{
508 if(mState.stencilWritemask != stencilWritemask)
509 {
510 mState.stencilWritemask = stencilWritemask;
511 mStencilStateDirty = true;
512 }
513}
514
515void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
516{
517 if(mState.stencilFail != stencilFail ||
518 mState.stencilPassDepthFail != stencilPassDepthFail ||
519 mState.stencilPassDepthPass != stencilPassDepthPass)
520 {
521 mState.stencilFail = stencilFail;
522 mState.stencilPassDepthFail = stencilPassDepthFail;
523 mState.stencilPassDepthPass = stencilPassDepthPass;
524 mStencilStateDirty = true;
525 }
526}
527
528void Context::setPolygonOffsetFillEnabled(bool enabled)
529{
530 if(mState.polygonOffsetFillEnabled != enabled)
531 {
532 mState.polygonOffsetFillEnabled = enabled;
533 mPolygonOffsetStateDirty = true;
534 }
535}
536
537bool Context::isPolygonOffsetFillEnabled() const
538{
539 return mState.polygonOffsetFillEnabled;
540}
541
542void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
543{
544 if(mState.polygonOffsetFactor != factor ||
545 mState.polygonOffsetUnits != units)
546 {
547 mState.polygonOffsetFactor = factor;
548 mState.polygonOffsetUnits = units;
549 mPolygonOffsetStateDirty = true;
550 }
551}
552
553void Context::setSampleAlphaToCoverageEnabled(bool enabled)
554{
555 if(mState.sampleAlphaToCoverageEnabled != enabled)
556 {
557 mState.sampleAlphaToCoverageEnabled = enabled;
558 mSampleStateDirty = true;
559 }
560}
561
562bool Context::isSampleAlphaToCoverageEnabled() const
563{
564 return mState.sampleAlphaToCoverageEnabled;
565}
566
567void Context::setSampleCoverageEnabled(bool enabled)
568{
569 if(mState.sampleCoverageEnabled != enabled)
570 {
571 mState.sampleCoverageEnabled = enabled;
572 mSampleStateDirty = true;
573 }
574}
575
576bool Context::isSampleCoverageEnabled() const
577{
578 return mState.sampleCoverageEnabled;
579}
580
581void Context::setSampleCoverageParams(GLclampf value, bool invert)
582{
583 if(mState.sampleCoverageValue != value ||
584 mState.sampleCoverageInvert != invert)
585 {
586 mState.sampleCoverageValue = value;
587 mState.sampleCoverageInvert = invert;
588 mSampleStateDirty = true;
589 }
590}
591
592void Context::setScissorTestEnabled(bool enabled)
593{
594 mState.scissorTestEnabled = enabled;
595}
596
597bool Context::isScissorTestEnabled() const
598{
599 return mState.scissorTestEnabled;
600}
601
602void Context::setShadeModel(GLenum mode)
603{
604 mState.shadeModel = mode;
605}
606
607void Context::setDitherEnabled(bool enabled)
608{
609 if(mState.ditherEnabled != enabled)
610 {
611 mState.ditherEnabled = enabled;
612 mDitherStateDirty = true;
613 }
614}
615
616bool Context::isDitherEnabled() const
617{
618 return mState.ditherEnabled;
619}
620
621void Context::setLightingEnabled(bool enable)
622{
623 lightingEnabled = enable;
624}
625
626bool Context::isLightingEnabled() const
627{
628 return lightingEnabled;
629}
630
631void Context::setLightEnabled(int index, bool enable)
632{
633 light[index].enabled = enable;
634}
635
636bool Context::isLightEnabled(int index) const
637{
638 return light[index].enabled;
639}
640
641void Context::setLightAmbient(int index, float r, float g, float b, float a)
642{
643 light[index].ambient = {r, g, b, a};
644}
645
646void Context::setLightDiffuse(int index, float r, float g, float b, float a)
647{
648 light[index].diffuse = {r, g, b, a};
649}
650
651void Context::setLightSpecular(int index, float r, float g, float b, float a)
652{
653 light[index].specular = {r, g, b, a};
654}
655
656void Context::setLightPosition(int index, float x, float y, float z, float w)
657{
658 sw::float4 v = {x, y, z, w};
659
660 // Transform from object coordinates to eye coordinates
661 v = modelViewStack.current() * v;
662
663 light[index].position = {v.x, v.y, v.z, v.w};
664}
665
666void Context::setLightDirection(int index, float x, float y, float z)
667{
668 // FIXME: Transform by inverse of 3x3 model-view matrix
669 light[index].direction = {x, y, z};
670}
671
672void Context::setLightAttenuationConstant(int index, float constant)
673{
674 light[index].attenuation.constant = constant;
675}
676
677void Context::setLightAttenuationLinear(int index, float linear)
678{
679 light[index].attenuation.linear = linear;
680}
681
682void Context::setLightAttenuationQuadratic(int index, float quadratic)
683{
684 light[index].attenuation.quadratic = quadratic;
685}
686
687void Context::setSpotLightExponent(int index, float exponent)
688{
689 light[index].spotExponent = exponent;
690}
691
692void Context::setSpotLightCutoff(int index, float cutoff)
693{
694 light[index].spotCutoffAngle = cutoff;
695}
696
697void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
698{
699 globalAmbient.red = red;
700 globalAmbient.green = green;
701 globalAmbient.blue = blue;
702 globalAmbient.alpha = alpha;
703}
704
705void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
706{
707 materialAmbient.red = red;
708 materialAmbient.green = green;
709 materialAmbient.blue = blue;
710 materialAmbient.alpha = alpha;
711}
712
713void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
714{
715 materialDiffuse.red = red;
716 materialDiffuse.green = green;
717 materialDiffuse.blue = blue;
718 materialDiffuse.alpha = alpha;
719}
720
721void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
722{
723 materialSpecular.red = red;
724 materialSpecular.green = green;
725 materialSpecular.blue = blue;
726 materialSpecular.alpha = alpha;
727}
728
729void Context::setMaterialEmission(float red, float green, float blue, float alpha)
730{
731 materialEmission.red = red;
732 materialEmission.green = green;
733 materialEmission.blue = blue;
734 materialEmission.alpha = alpha;
735}
736
737void Context::setMaterialShininess(float shininess)
738{
739 materialShininess = shininess;
740}
741
742void Context::setLightModelTwoSide(bool enable)
743{
744 lightModelTwoSide = enable;
745}
746
747void Context::setFogEnabled(bool enable)
748{
749 fogEnabled = enable;
750}
751
752bool Context::isFogEnabled() const
753{
754 return fogEnabled;
755}
756
757void Context::setFogMode(GLenum mode)
758{
759 fogMode = mode;
760}
761
762void Context::setFogDensity(float fogDensity)
763{
764 this->fogDensity = fogDensity;
765}
766
767void Context::setFogStart(float fogStart)
768{
769 this->fogStart = fogStart;
770}
771
772void Context::setFogEnd(float fogEnd)
773{
774 this->fogEnd = fogEnd;
775}
776
777void Context::setFogColor(float r, float g, float b, float a)
778{
779 this->fogColor = {r, g, b, a};
780}
781
782void Context::setTexture2Denabled(bool enable)
783{
784 texture2Denabled[mState.activeSampler] = enable;
785}
786
787bool Context::isTexture2Denabled() const
788{
789 return texture2Denabled[mState.activeSampler];
790}
791
792void Context::setTextureExternalEnabled(bool enable)
793{
794 textureExternalEnabled[mState.activeSampler] = enable;
795}
796
797bool Context::isTextureExternalEnabled() const
798{
799 return textureExternalEnabled[mState.activeSampler];
800}
801
802void Context::setLineWidth(GLfloat width)
803{
804 mState.lineWidth = width;
805 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
806}
807
808void Context::setGenerateMipmapHint(GLenum hint)
809{
810 mState.generateMipmapHint = hint;
811}
812
813void Context::setPerspectiveCorrectionHint(GLenum hint)
814{
815 mState.perspectiveCorrectionHint = hint;
816}
817
818void Context::setFogHint(GLenum hint)
819{
820 mState.fogHint = hint;
821}
822
823void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
824{
825 mState.viewportX = x;
826 mState.viewportY = y;
827 mState.viewportWidth = width;
828 mState.viewportHeight = height;
829}
830
831void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
832{
833 mState.scissorX = x;
834 mState.scissorY = y;
835 mState.scissorWidth = width;
836 mState.scissorHeight = height;
837}
838
839void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
840{
841 if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
842 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
843 {
844 mState.colorMaskRed = red;
845 mState.colorMaskGreen = green;
846 mState.colorMaskBlue = blue;
847 mState.colorMaskAlpha = alpha;
848 mMaskStateDirty = true;
849 }
850}
851
852void Context::setDepthMask(bool mask)
853{
854 if(mState.depthMask != mask)
855 {
856 mState.depthMask = mask;
857 mMaskStateDirty = true;
858 }
859}
860
861void Context::setActiveSampler(unsigned int active)
862{
863 mState.activeSampler = active;
864}
865
866GLuint Context::getFramebufferName() const
867{
868 return mState.framebuffer;
869}
870
871GLuint Context::getRenderbufferName() const
872{
873 return mState.renderbuffer.name();
874}
875
876GLuint Context::getArrayBufferName() const
877{
878 return mState.arrayBuffer.name();
879}
880
881void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
882{
883 mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
884}
885
886const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
887{
888 return mState.vertexAttribute[attribNum];
889}
890
891void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
892 GLsizei stride, const void *pointer)
893{
894 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
895 mState.vertexAttribute[attribNum].mSize = size;
896 mState.vertexAttribute[attribNum].mType = type;
897 mState.vertexAttribute[attribNum].mNormalized = normalized;
898 mState.vertexAttribute[attribNum].mStride = stride;
899 mState.vertexAttribute[attribNum].mPointer = pointer;
900}
901
902const void *Context::getVertexAttribPointer(unsigned int attribNum) const
903{
904 return mState.vertexAttribute[attribNum].mPointer;
905}
906
907const VertexAttributeArray &Context::getVertexAttributes()
908{
909 return mState.vertexAttribute;
910}
911
912void Context::setPackAlignment(GLint alignment)
913{
914 mState.packAlignment = alignment;
915}
916
917GLint Context::getPackAlignment() const
918{
919 return mState.packAlignment;
920}
921
922void Context::setUnpackAlignment(GLint alignment)
923{
924 mState.unpackAlignment = alignment;
925}
926
927GLint Context::getUnpackAlignment() const
928{
929 return mState.unpackAlignment;
930}
931
932GLuint Context::createBuffer()
933{
934 return mResourceManager->createBuffer();
935}
936
937GLuint Context::createTexture()
938{
939 return mResourceManager->createTexture();
940}
941
942GLuint Context::createRenderbuffer()
943{
944 return mResourceManager->createRenderbuffer();
945}
946
947// Returns an unused framebuffer name
948GLuint Context::createFramebuffer()
949{
950 return mFramebufferNameSpace.allocate();
951}
952
953void Context::deleteBuffer(GLuint buffer)
954{
955 detachBuffer(buffer);
956
957 mResourceManager->deleteBuffer(buffer);
958}
959
960void Context::deleteTexture(GLuint texture)
961{
962 detachTexture(texture);
963
964 mResourceManager->deleteTexture(texture);
965}
966
967void Context::deleteRenderbuffer(GLuint renderbuffer)
968{
969 detachRenderbuffer(renderbuffer);
970
971 mResourceManager->deleteRenderbuffer(renderbuffer);
972}
973
974void Context::deleteFramebuffer(GLuint framebuffer)
975{
976 detachFramebuffer(framebuffer);
977
978 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
979
980 if(framebufferObject)
981 {
982 delete framebufferObject;
983 }
984}
985
986Buffer *Context::getBuffer(GLuint handle)
987{
988 return mResourceManager->getBuffer(handle);
989}
990
991Texture *Context::getTexture(GLuint handle)
992{
993 return mResourceManager->getTexture(handle);
994}
995
996Renderbuffer *Context::getRenderbuffer(GLuint handle)
997{
998 return mResourceManager->getRenderbuffer(handle);
999}
1000
1001Framebuffer *Context::getFramebuffer()
1002{
1003 return getFramebuffer(mState.framebuffer);
1004}
1005
1006void Context::bindArrayBuffer(unsigned int buffer)
1007{
1008 mResourceManager->checkBufferAllocation(buffer);
1009
1010 mState.arrayBuffer = getBuffer(buffer);
1011}
1012
1013void Context::bindElementArrayBuffer(unsigned int buffer)
1014{
1015 mResourceManager->checkBufferAllocation(buffer);
1016
1017 mState.elementArrayBuffer = getBuffer(buffer);
1018}
1019
Nicolas Capens2ce08b12018-03-02 12:37:47 -05001020void Context::bindTexture(TextureType type, GLuint texture)
Nicolas Capens0bac2852016-05-07 06:09:58 -04001021{
Nicolas Capens2ce08b12018-03-02 12:37:47 -05001022 mResourceManager->checkTextureAllocation(texture, type);
Nicolas Capens0bac2852016-05-07 06:09:58 -04001023
Nicolas Capens2ce08b12018-03-02 12:37:47 -05001024 mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
Nicolas Capens0bac2852016-05-07 06:09:58 -04001025}
1026
1027void Context::bindFramebuffer(GLuint framebuffer)
1028{
1029 if(!getFramebuffer(framebuffer))
1030 {
1031 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
1032 }
1033
1034 mState.framebuffer = framebuffer;
1035}
1036
1037void Context::bindRenderbuffer(GLuint renderbuffer)
1038{
1039 mResourceManager->checkRenderbufferAllocation(renderbuffer);
1040
1041 mState.renderbuffer = getRenderbuffer(renderbuffer);
1042}
1043
1044void Context::setFramebufferZero(Framebuffer *buffer)
1045{
1046 delete mFramebufferNameSpace.remove(0);
1047 mFramebufferNameSpace.insert(0, buffer);
1048}
1049
1050void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1051{
1052 Renderbuffer *renderbufferObject = mState.renderbuffer;
1053 renderbufferObject->setStorage(renderbuffer);
1054}
1055
1056Framebuffer *Context::getFramebuffer(unsigned int handle)
1057{
1058 return mFramebufferNameSpace.find(handle);
1059}
1060
1061Buffer *Context::getArrayBuffer()
1062{
1063 return mState.arrayBuffer;
1064}
1065
1066Buffer *Context::getElementArrayBuffer()
1067{
1068 return mState.elementArrayBuffer;
1069}
1070
1071Texture2D *Context::getTexture2D()
1072{
1073 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1074}
1075
1076TextureExternal *Context::getTextureExternal()
1077{
1078 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1079}
1080
1081Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1082{
1083 GLuint texid = mState.samplerTexture[type][sampler].name();
1084
1085 if(texid == 0) // Special case: 0 refers to different initial textures based on the target
1086 {
1087 switch(type)
1088 {
1089 case TEXTURE_2D: return mTexture2DZero;
1090 case TEXTURE_EXTERNAL: return mTextureExternalZero;
1091 default: UNREACHABLE(type);
1092 }
1093 }
1094
1095 return mState.samplerTexture[type][sampler];
1096}
1097
1098bool Context::getBooleanv(GLenum pname, GLboolean *params)
1099{
1100 switch(pname)
1101 {
1102 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1103 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
1104 case GL_COLOR_WRITEMASK:
1105 params[0] = mState.colorMaskRed;
1106 params[1] = mState.colorMaskGreen;
1107 params[2] = mState.colorMaskBlue;
1108 params[3] = mState.colorMaskAlpha;
1109 break;
1110 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break;
1111 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break;
1112 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1113 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break;
1114 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break;
1115 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break;
1116 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break;
1117 case GL_BLEND: *params = mState.blendEnabled; break;
1118 case GL_DITHER: *params = mState.ditherEnabled; break;
1119 case GL_LIGHT_MODEL_TWO_SIDE: *params = lightModelTwoSide; break;
1120 default:
1121 return false;
1122 }
1123
1124 return true;
1125}
1126
1127bool Context::getFloatv(GLenum pname, GLfloat *params)
1128{
1129 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1130 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1131 // GetIntegerv as its native query function. As it would require conversion in any
1132 // case, this should make no difference to the calling application.
1133 switch(pname)
1134 {
1135 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1136 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1137 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1138 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
1139 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
1140 case GL_ALIASED_LINE_WIDTH_RANGE:
1141 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1142 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1143 break;
1144 case GL_ALIASED_POINT_SIZE_RANGE:
1145 params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1146 params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1147 break;
1148 case GL_SMOOTH_LINE_WIDTH_RANGE:
1149 params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;
1150 params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;
1151 break;
1152 case GL_SMOOTH_POINT_SIZE_RANGE:
1153 params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;
1154 params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;
1155 break;
1156 case GL_DEPTH_RANGE:
1157 params[0] = mState.zNear;
1158 params[1] = mState.zFar;
1159 break;
1160 case GL_COLOR_CLEAR_VALUE:
1161 params[0] = mState.colorClearValue.red;
1162 params[1] = mState.colorClearValue.green;
1163 params[2] = mState.colorClearValue.blue;
1164 params[3] = mState.colorClearValue.alpha;
1165 break;
1166 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1167 *params = MAX_TEXTURE_MAX_ANISOTROPY;
1168 break;
1169 case GL_MODELVIEW_MATRIX:
1170 for(int i = 0; i < 16; i++)
1171 {
1172 params[i] = modelViewStack.current()[i % 4][i / 4];
1173 }
1174 break;
1175 case GL_PROJECTION_MATRIX:
1176 for(int i = 0; i < 16; i++)
1177 {
1178 params[i] = projectionStack.current()[i % 4][i / 4];
1179 }
1180 break;
Nicolas Capens59dca942017-04-13 13:35:09 -04001181 case GL_CURRENT_COLOR:
1182 for(int i = 0; i < 4; i++)
1183 {
1184 params[i] = mState.vertexAttribute[sw::Color0].mCurrentValue[i];
1185 }
1186 break;
1187 case GL_CURRENT_NORMAL:
1188 for(int i = 0; i < 3; i++)
1189 {
1190 params[i] = mState.vertexAttribute[sw::Normal].mCurrentValue[i];
1191 }
1192 break;
1193 case GL_CURRENT_TEXTURE_COORDS:
1194 for(int i = 0; i < 4; i++)
1195 {
1196 params[i] = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[i];
1197 }
1198 break;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001199 default:
1200 return false;
1201 }
1202
1203 return true;
1204}
1205
1206bool Context::getIntegerv(GLenum pname, GLint *params)
1207{
1208 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1209 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1210 // GetIntegerv as its native query function. As it would require conversion in any
1211 // case, this should make no difference to the calling application. You may find it in
1212 // Context::getFloatv.
1213 switch(pname)
1214 {
1215 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break;
1216 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break;
1217 case GL_FRAMEBUFFER_BINDING_OES: *params = mState.framebuffer; break;
1218 case GL_RENDERBUFFER_BINDING_OES: *params = mState.renderbuffer.name(); break;
1219 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
1220 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
1221 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
1222 case GL_PERSPECTIVE_CORRECTION_HINT: *params = mState.perspectiveCorrectionHint; break;
1223 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
1224 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break;
1225 case GL_STENCIL_REF: *params = mState.stencilRef; break;
1226 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break;
1227 case GL_STENCIL_FAIL: *params = mState.stencilFail; break;
1228 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break;
1229 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break;
1230 case GL_DEPTH_FUNC: *params = mState.depthFunc; break;
1231 case GL_BLEND_SRC_RGB_OES: *params = mState.sourceBlendRGB; break;
1232 case GL_BLEND_SRC_ALPHA_OES: *params = mState.sourceBlendAlpha; break;
1233 case GL_BLEND_DST_RGB_OES: *params = mState.destBlendRGB; break;
1234 case GL_BLEND_DST_ALPHA_OES: *params = mState.destBlendAlpha; break;
1235 case GL_BLEND_EQUATION_RGB_OES: *params = mState.blendEquationRGB; break;
1236 case GL_BLEND_EQUATION_ALPHA_OES: *params = mState.blendEquationAlpha; break;
1237 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break;
1238 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
1239 case GL_SUBPIXEL_BITS: *params = 4; break;
1240 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break;
1241 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break;
1242 case GL_SAMPLE_BUFFERS:
1243 case GL_SAMPLES:
1244 {
1245 Framebuffer *framebuffer = getFramebuffer();
1246 int width, height, samples;
1247
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001248 if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES))
Nicolas Capens0bac2852016-05-07 06:09:58 -04001249 {
1250 switch(pname)
1251 {
1252 case GL_SAMPLE_BUFFERS:
1253 if(samples > 1)
1254 {
1255 *params = 1;
1256 }
1257 else
1258 {
1259 *params = 0;
1260 }
1261 break;
1262 case GL_SAMPLES:
1263 *params = samples;
1264 break;
1265 }
1266 }
1267 else
1268 {
1269 *params = 0;
1270 }
1271 }
1272 break;
1273 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1274 {
1275 Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001276 if(framebuffer)
1277 {
1278 *params = framebuffer->getImplementationColorReadType();
1279 }
1280 else
1281 {
1282 return error(GL_INVALID_OPERATION, true);
1283 }
Nicolas Capens0bac2852016-05-07 06:09:58 -04001284 }
1285 break;
1286 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1287 {
1288 Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001289 if(framebuffer)
1290 {
1291 *params = framebuffer->getImplementationColorReadFormat();
1292 }
1293 else
1294 {
1295 return error(GL_INVALID_OPERATION, true);
1296 }
Nicolas Capens0bac2852016-05-07 06:09:58 -04001297 }
1298 break;
1299 case GL_MAX_VIEWPORT_DIMS:
1300 {
1301 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1302 params[0] = maxDimension;
1303 params[1] = maxDimension;
1304 }
1305 break;
1306 case GL_COMPRESSED_TEXTURE_FORMATS:
1307 {
1308 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1309 {
1310 params[i] = compressedTextureFormats[i];
1311 }
1312 }
1313 break;
1314 case GL_VIEWPORT:
1315 params[0] = mState.viewportX;
1316 params[1] = mState.viewportY;
1317 params[2] = mState.viewportWidth;
1318 params[3] = mState.viewportHeight;
1319 break;
1320 case GL_SCISSOR_BOX:
1321 params[0] = mState.scissorX;
1322 params[1] = mState.scissorY;
1323 params[2] = mState.scissorWidth;
1324 params[3] = mState.scissorHeight;
1325 break;
1326 case GL_CULL_FACE_MODE: *params = mState.cullMode; break;
1327 case GL_FRONT_FACE: *params = mState.frontFace; break;
1328 case GL_RED_BITS:
1329 case GL_GREEN_BITS:
1330 case GL_BLUE_BITS:
1331 case GL_ALPHA_BITS:
1332 {
1333 Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001334 Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer() : nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001335
1336 if(colorbuffer)
1337 {
1338 switch(pname)
1339 {
1340 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1341 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1342 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1343 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1344 }
1345 }
1346 else
1347 {
1348 *params = 0;
1349 }
1350 }
1351 break;
1352 case GL_DEPTH_BITS:
1353 {
1354 Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001355 Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001356
1357 if(depthbuffer)
1358 {
1359 *params = depthbuffer->getDepthSize();
1360 }
1361 else
1362 {
1363 *params = 0;
1364 }
1365 }
1366 break;
1367 case GL_STENCIL_BITS:
1368 {
1369 Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04001370 Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001371
1372 if(stencilbuffer)
1373 {
1374 *params = stencilbuffer->getStencilSize();
1375 }
1376 else
1377 {
1378 *params = 0;
1379 }
1380 }
1381 break;
1382 case GL_TEXTURE_BINDING_2D: *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); break;
Nicolas Capens0bac2852016-05-07 06:09:58 -04001383 case GL_TEXTURE_BINDING_EXTERNAL_OES: *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); break;
1384 case GL_MAX_LIGHTS: *params = MAX_LIGHTS; break;
1385 case GL_MAX_MODELVIEW_STACK_DEPTH: *params = MAX_MODELVIEW_STACK_DEPTH; break;
1386 case GL_MAX_PROJECTION_STACK_DEPTH: *params = MAX_PROJECTION_STACK_DEPTH; break;
1387 case GL_MAX_TEXTURE_STACK_DEPTH: *params = MAX_TEXTURE_STACK_DEPTH; break;
1388 case GL_MAX_TEXTURE_UNITS: *params = MAX_TEXTURE_UNITS; break;
1389 case GL_MAX_CLIP_PLANES: *params = MAX_CLIP_PLANES; break;
1390 case GL_POINT_SIZE_ARRAY_TYPE_OES: *params = mState.vertexAttribute[sw::PointSize].mType; break;
1391 case GL_POINT_SIZE_ARRAY_STRIDE_OES: *params = mState.vertexAttribute[sw::PointSize].mStride; break;
1392 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name(); break;
1393 case GL_VERTEX_ARRAY_SIZE: *params = mState.vertexAttribute[sw::Position].mSize; break;
1394 case GL_VERTEX_ARRAY_TYPE: *params = mState.vertexAttribute[sw::Position].mType; break;
1395 case GL_VERTEX_ARRAY_STRIDE: *params = mState.vertexAttribute[sw::Position].mStride; break;
1396 case GL_VERTEX_ARRAY_BUFFER_BINDING: *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name(); break;
1397 case GL_NORMAL_ARRAY_TYPE: *params = mState.vertexAttribute[sw::Normal].mType; break;
1398 case GL_NORMAL_ARRAY_STRIDE: *params = mState.vertexAttribute[sw::Normal].mStride; break;
1399 case GL_NORMAL_ARRAY_BUFFER_BINDING: *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name(); break;
1400 case GL_COLOR_ARRAY_SIZE: *params = mState.vertexAttribute[sw::Color0].mSize; break;
1401 case GL_COLOR_ARRAY_TYPE: *params = mState.vertexAttribute[sw::Color0].mType; break;
1402 case GL_COLOR_ARRAY_STRIDE: *params = mState.vertexAttribute[sw::Color0].mStride; break;
1403 case GL_COLOR_ARRAY_BUFFER_BINDING: *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name(); break;
1404 case GL_TEXTURE_COORD_ARRAY_SIZE: *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize; break;
1405 case GL_TEXTURE_COORD_ARRAY_TYPE: *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType; break;
1406 case GL_TEXTURE_COORD_ARRAY_STRIDE: *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride; break;
1407 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;
1408 default:
1409 return false;
1410 }
1411
1412 return true;
1413}
1414
1415bool Context::getPointerv(GLenum pname, const GLvoid **params)
1416{
1417 switch(pname)
1418 {
1419 case GL_VERTEX_ARRAY_POINTER: *params = mState.vertexAttribute[sw::Position].mPointer; break;
1420 case GL_NORMAL_ARRAY_POINTER: *params = mState.vertexAttribute[sw::Normal].mPointer; break;
1421 case GL_COLOR_ARRAY_POINTER: *params = mState.vertexAttribute[sw::Color0].mPointer; break;
1422 case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer; break;
1423 case GL_TEXTURE_COORD_ARRAY_POINTER: *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;
1424 default:
1425 return false;
1426 }
1427
1428 return true;
1429}
1430
1431int Context::getQueryParameterNum(GLenum pname)
1432{
1433 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1434 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1435 // to the fact that it is stored internally as a float, and so would require conversion
1436 // if returned from Context::getIntegerv. Since this conversion is already implemented
1437 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1438 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1439 // application.
1440 switch(pname)
1441 {
1442 case GL_COMPRESSED_TEXTURE_FORMATS:
1443 return NUM_COMPRESSED_TEXTURE_FORMATS;
1444 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1445 case GL_ARRAY_BUFFER_BINDING:
1446 case GL_FRAMEBUFFER_BINDING_OES:
1447 case GL_RENDERBUFFER_BINDING_OES:
1448 case GL_PACK_ALIGNMENT:
1449 case GL_UNPACK_ALIGNMENT:
1450 case GL_GENERATE_MIPMAP_HINT:
1451 case GL_RED_BITS:
1452 case GL_GREEN_BITS:
1453 case GL_BLUE_BITS:
1454 case GL_ALPHA_BITS:
1455 case GL_DEPTH_BITS:
1456 case GL_STENCIL_BITS:
1457 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1458 case GL_CULL_FACE_MODE:
1459 case GL_FRONT_FACE:
1460 case GL_ACTIVE_TEXTURE:
1461 case GL_STENCIL_FUNC:
1462 case GL_STENCIL_VALUE_MASK:
1463 case GL_STENCIL_REF:
1464 case GL_STENCIL_FAIL:
1465 case GL_STENCIL_PASS_DEPTH_FAIL:
1466 case GL_STENCIL_PASS_DEPTH_PASS:
1467 case GL_DEPTH_FUNC:
1468 case GL_BLEND_SRC_RGB_OES:
1469 case GL_BLEND_SRC_ALPHA_OES:
1470 case GL_BLEND_DST_RGB_OES:
1471 case GL_BLEND_DST_ALPHA_OES:
1472 case GL_BLEND_EQUATION_RGB_OES:
1473 case GL_BLEND_EQUATION_ALPHA_OES:
1474 case GL_STENCIL_WRITEMASK:
1475 case GL_STENCIL_CLEAR_VALUE:
1476 case GL_SUBPIXEL_BITS:
1477 case GL_MAX_TEXTURE_SIZE:
1478 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1479 case GL_SAMPLE_BUFFERS:
1480 case GL_SAMPLES:
1481 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1482 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1483 case GL_TEXTURE_BINDING_2D:
1484 case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1485 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1486 return 1;
1487 case GL_MAX_VIEWPORT_DIMS:
1488 return 2;
1489 case GL_VIEWPORT:
1490 case GL_SCISSOR_BOX:
1491 return 4;
1492 case GL_SAMPLE_COVERAGE_INVERT:
1493 case GL_DEPTH_WRITEMASK:
1494 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1495 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1496 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1497 case GL_SAMPLE_COVERAGE:
1498 case GL_SCISSOR_TEST:
1499 case GL_STENCIL_TEST:
1500 case GL_DEPTH_TEST:
1501 case GL_BLEND:
1502 case GL_DITHER:
1503 return 1;
1504 case GL_COLOR_WRITEMASK:
1505 return 4;
1506 case GL_POLYGON_OFFSET_FACTOR:
1507 case GL_POLYGON_OFFSET_UNITS:
1508 case GL_SAMPLE_COVERAGE_VALUE:
1509 case GL_DEPTH_CLEAR_VALUE:
1510 case GL_LINE_WIDTH:
1511 return 1;
1512 case GL_ALIASED_LINE_WIDTH_RANGE:
1513 case GL_ALIASED_POINT_SIZE_RANGE:
1514 case GL_DEPTH_RANGE:
1515 return 2;
1516 case GL_COLOR_CLEAR_VALUE:
1517 return 4;
1518 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1519 case GL_MAX_LIGHTS:
1520 case GL_MAX_MODELVIEW_STACK_DEPTH:
1521 case GL_MAX_PROJECTION_STACK_DEPTH:
1522 case GL_MAX_TEXTURE_STACK_DEPTH:
1523 case GL_MAX_TEXTURE_UNITS:
1524 case GL_MAX_CLIP_PLANES:
1525 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1526 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1527 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1528 return 1;
1529 case GL_CURRENT_COLOR:
1530 return 4;
1531 case GL_CURRENT_NORMAL:
1532 return 3;
1533 case GL_CURRENT_TEXTURE_COORDS:
1534 return 4;
1535 case GL_POINT_SIZE:
1536 case GL_POINT_SIZE_MIN:
1537 case GL_POINT_SIZE_MAX:
1538 case GL_POINT_FADE_THRESHOLD_SIZE:
1539 return 1;
1540 case GL_POINT_DISTANCE_ATTENUATION:
1541 return 3;
1542 case GL_SMOOTH_POINT_SIZE_RANGE:
1543 case GL_SMOOTH_LINE_WIDTH_RANGE:
1544 return 2;
1545 case GL_SHADE_MODEL:
1546 case GL_MATRIX_MODE:
1547 case GL_MODELVIEW_STACK_DEPTH:
1548 case GL_PROJECTION_STACK_DEPTH:
1549 case GL_TEXTURE_STACK_DEPTH:
1550 return 1;
1551 case GL_MODELVIEW_MATRIX:
1552 case GL_PROJECTION_MATRIX:
1553 case GL_TEXTURE_MATRIX:
1554 return 16;
1555 case GL_ALPHA_TEST_FUNC:
1556 case GL_ALPHA_TEST_REF:
1557 case GL_BLEND_DST:
1558 case GL_BLEND_SRC:
1559 case GL_LOGIC_OP_MODE:
1560 case GL_VERTEX_ARRAY_SIZE:
1561 case GL_VERTEX_ARRAY_TYPE:
1562 case GL_VERTEX_ARRAY_STRIDE:
1563 case GL_NORMAL_ARRAY_TYPE:
1564 case GL_NORMAL_ARRAY_STRIDE:
1565 case GL_COLOR_ARRAY_SIZE:
1566 case GL_COLOR_ARRAY_TYPE:
1567 case GL_COLOR_ARRAY_STRIDE:
1568 case GL_TEXTURE_COORD_ARRAY_SIZE:
1569 case GL_TEXTURE_COORD_ARRAY_TYPE:
1570 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1571 case GL_VERTEX_ARRAY_POINTER:
1572 case GL_NORMAL_ARRAY_POINTER:
1573 case GL_COLOR_ARRAY_POINTER:
1574 case GL_TEXTURE_COORD_ARRAY_POINTER:
1575 case GL_LIGHT_MODEL_TWO_SIDE:
1576 return 1;
1577 default:
1578 UNREACHABLE(pname);
1579 }
1580
1581 return -1;
1582}
1583
1584bool Context::isQueryParameterInt(GLenum pname)
1585{
1586 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1587 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1588 // to the fact that it is stored internally as a float, and so would require conversion
1589 // if returned from Context::getIntegerv. Since this conversion is already implemented
1590 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1591 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1592 // application.
1593 switch(pname)
1594 {
1595 case GL_COMPRESSED_TEXTURE_FORMATS:
1596 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1597 case GL_ARRAY_BUFFER_BINDING:
1598 case GL_FRAMEBUFFER_BINDING_OES:
1599 case GL_RENDERBUFFER_BINDING_OES:
1600 case GL_PACK_ALIGNMENT:
1601 case GL_UNPACK_ALIGNMENT:
1602 case GL_GENERATE_MIPMAP_HINT:
1603 case GL_RED_BITS:
1604 case GL_GREEN_BITS:
1605 case GL_BLUE_BITS:
1606 case GL_ALPHA_BITS:
1607 case GL_DEPTH_BITS:
1608 case GL_STENCIL_BITS:
1609 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1610 case GL_CULL_FACE_MODE:
1611 case GL_FRONT_FACE:
1612 case GL_ACTIVE_TEXTURE:
1613 case GL_STENCIL_FUNC:
1614 case GL_STENCIL_VALUE_MASK:
1615 case GL_STENCIL_REF:
1616 case GL_STENCIL_FAIL:
1617 case GL_STENCIL_PASS_DEPTH_FAIL:
1618 case GL_STENCIL_PASS_DEPTH_PASS:
1619 case GL_DEPTH_FUNC:
1620 case GL_BLEND_SRC_RGB_OES:
1621 case GL_BLEND_SRC_ALPHA_OES:
1622 case GL_BLEND_DST_RGB_OES:
1623 case GL_BLEND_DST_ALPHA_OES:
1624 case GL_BLEND_EQUATION_RGB_OES:
1625 case GL_BLEND_EQUATION_ALPHA_OES:
1626 case GL_STENCIL_WRITEMASK:
1627 case GL_STENCIL_CLEAR_VALUE:
1628 case GL_SUBPIXEL_BITS:
1629 case GL_MAX_TEXTURE_SIZE:
1630 case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1631 case GL_SAMPLE_BUFFERS:
1632 case GL_SAMPLES:
1633 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1634 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1635 case GL_TEXTURE_BINDING_2D:
1636 case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1637 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1638 case GL_MAX_VIEWPORT_DIMS:
1639 case GL_VIEWPORT:
1640 case GL_SCISSOR_BOX:
1641 case GL_MAX_LIGHTS:
1642 case GL_MAX_MODELVIEW_STACK_DEPTH:
1643 case GL_MAX_PROJECTION_STACK_DEPTH:
1644 case GL_MAX_TEXTURE_STACK_DEPTH:
1645 case GL_MAX_TEXTURE_UNITS:
1646 case GL_MAX_CLIP_PLANES:
1647 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1648 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1649 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1650 return true;
1651 }
1652
1653 return false;
1654}
1655
1656bool Context::isQueryParameterFloat(GLenum pname)
1657{
1658 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1659 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1660 // to the fact that it is stored internally as a float, and so would require conversion
1661 // if returned from Context::getIntegerv. Since this conversion is already implemented
1662 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1663 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1664 // application.
1665 switch(pname)
1666 {
1667 case GL_POLYGON_OFFSET_FACTOR:
1668 case GL_POLYGON_OFFSET_UNITS:
1669 case GL_SAMPLE_COVERAGE_VALUE:
1670 case GL_DEPTH_CLEAR_VALUE:
1671 case GL_LINE_WIDTH:
1672 case GL_ALIASED_LINE_WIDTH_RANGE:
1673 case GL_ALIASED_POINT_SIZE_RANGE:
1674 case GL_SMOOTH_LINE_WIDTH_RANGE:
1675 case GL_SMOOTH_POINT_SIZE_RANGE:
1676 case GL_DEPTH_RANGE:
1677 case GL_COLOR_CLEAR_VALUE:
1678 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1679 case GL_LIGHT_MODEL_AMBIENT:
1680 case GL_POINT_SIZE_MIN:
1681 case GL_POINT_SIZE_MAX:
1682 case GL_POINT_DISTANCE_ATTENUATION:
1683 case GL_POINT_FADE_THRESHOLD_SIZE:
1684 return true;
1685 }
1686
1687 return false;
1688}
1689
1690bool Context::isQueryParameterBool(GLenum pname)
1691{
1692 switch(pname)
1693 {
1694 case GL_SAMPLE_COVERAGE_INVERT:
1695 case GL_DEPTH_WRITEMASK:
1696 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1697 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1698 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1699 case GL_SAMPLE_COVERAGE:
1700 case GL_SCISSOR_TEST:
1701 case GL_STENCIL_TEST:
1702 case GL_DEPTH_TEST:
1703 case GL_BLEND:
1704 case GL_DITHER:
1705 case GL_COLOR_WRITEMASK:
1706 case GL_LIGHT_MODEL_TWO_SIDE:
1707 return true;
1708 }
1709
1710 return false;
1711}
1712
1713bool Context::isQueryParameterPointer(GLenum pname)
1714{
1715 switch(pname)
1716 {
1717 case GL_VERTEX_ARRAY_POINTER:
1718 case GL_NORMAL_ARRAY_POINTER:
1719 case GL_COLOR_ARRAY_POINTER:
1720 case GL_TEXTURE_COORD_ARRAY_POINTER:
1721 case GL_POINT_SIZE_ARRAY_POINTER_OES:
1722 return true;
1723 }
1724
1725 return false;
1726}
1727
1728// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
1729bool Context::applyRenderTarget()
1730{
1731 Framebuffer *framebuffer = getFramebuffer();
1732 int width, height, samples;
1733
1734 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
1735 {
1736 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
1737 }
1738
1739 egl::Image *renderTarget = framebuffer->getRenderTarget();
1740 device->setRenderTarget(0, renderTarget);
1741 if(renderTarget) renderTarget->release();
1742
1743 egl::Image *depthBuffer = framebuffer->getDepthBuffer();
1744 device->setDepthBuffer(depthBuffer);
1745 if(depthBuffer) depthBuffer->release();
1746
1747 egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
1748 device->setStencilBuffer(stencilBuffer);
1749 if(stencilBuffer) stencilBuffer->release();
1750
1751 Viewport viewport;
1752 float zNear = clamp01(mState.zNear);
1753 float zFar = clamp01(mState.zFar);
1754
1755 viewport.x0 = mState.viewportX;
1756 viewport.y0 = mState.viewportY;
1757 viewport.width = mState.viewportWidth;
1758 viewport.height = mState.viewportHeight;
1759 viewport.minZ = zNear;
1760 viewport.maxZ = zFar;
1761
1762 device->setViewport(viewport);
1763
1764 if(mState.scissorTestEnabled)
1765 {
1766 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1767 scissor.clip(0, 0, width, height);
1768
1769 device->setScissorRect(scissor);
1770 device->setScissorEnable(true);
1771 }
1772 else
1773 {
1774 device->setScissorEnable(false);
1775 }
1776
1777 return true;
1778}
1779
1780// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
1781void Context::applyState(GLenum drawMode)
1782{
1783 Framebuffer *framebuffer = getFramebuffer();
Nicolas Capensdd4c8632018-07-31 15:33:28 -04001784 bool frontFaceCCW = (mState.frontFace == GL_CCW);
Nicolas Capens0bac2852016-05-07 06:09:58 -04001785
1786 if(mState.cullFaceEnabled)
1787 {
Nicolas Capensdd4c8632018-07-31 15:33:28 -04001788 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace), frontFaceCCW);
Nicolas Capens0bac2852016-05-07 06:09:58 -04001789 }
1790 else
1791 {
Nicolas Capensdd4c8632018-07-31 15:33:28 -04001792 device->setCullMode(sw::CULL_NONE, frontFaceCCW);
Nicolas Capens0bac2852016-05-07 06:09:58 -04001793 }
1794
1795 if(mDepthStateDirty)
1796 {
1797 if(mState.depthTestEnabled)
1798 {
1799 device->setDepthBufferEnable(true);
1800 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1801 }
1802 else
1803 {
1804 device->setDepthBufferEnable(false);
1805 }
1806
1807 mDepthStateDirty = false;
1808 }
1809
1810 if(mBlendStateDirty)
1811 {
1812 if(mState.blendEnabled)
1813 {
1814 device->setAlphaBlendEnable(true);
1815 device->setSeparateAlphaBlendEnable(true);
1816
1817 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1818 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1819 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1820
1821 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1822 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1823 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1824 }
1825 else
1826 {
1827 device->setAlphaBlendEnable(false);
1828 }
1829
1830 mBlendStateDirty = false;
1831 }
1832
1833 if(mStencilStateDirty || mFrontFaceDirty)
1834 {
1835 if(mState.stencilTestEnabled && framebuffer->hasStencil())
1836 {
1837 device->setStencilEnable(true);
1838 device->setTwoSidedStencil(true);
1839
1840 // get the maximum size of the stencil ref
1841 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1842 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1843
1844 device->setStencilWriteMask(mState.stencilWritemask);
1845 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1846
1847 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1848 device->setStencilMask(mState.stencilMask);
1849
1850 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1851 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1852 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1853
1854 device->setStencilWriteMaskCCW(mState.stencilWritemask);
1855 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1856
1857 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1858 device->setStencilMaskCCW(mState.stencilMask);
1859
1860 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1861 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1862 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1863 }
1864 else
1865 {
1866 device->setStencilEnable(false);
1867 }
1868
1869 mStencilStateDirty = false;
1870 mFrontFaceDirty = false;
1871 }
1872
1873 if(mMaskStateDirty)
1874 {
1875 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1876 device->setDepthWriteEnable(mState.depthMask);
1877
1878 mMaskStateDirty = false;
1879 }
1880
1881 if(mPolygonOffsetStateDirty)
1882 {
1883 if(mState.polygonOffsetFillEnabled)
1884 {
1885 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1886 if(depthbuffer)
1887 {
1888 device->setSlopeDepthBias(mState.polygonOffsetFactor);
1889 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1890 device->setDepthBias(depthBias);
1891 }
1892 }
1893 else
1894 {
1895 device->setSlopeDepthBias(0);
1896 device->setDepthBias(0);
1897 }
1898
1899 mPolygonOffsetStateDirty = false;
1900 }
1901
1902 if(mSampleStateDirty)
1903 {
1904 if(mState.sampleAlphaToCoverageEnabled)
1905 {
1906 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1907 }
1908 else
1909 {
1910 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1911 }
1912
1913 if(mState.sampleCoverageEnabled)
1914 {
1915 unsigned int mask = 0;
1916 if(mState.sampleCoverageValue != 0)
1917 {
1918 int width, height, samples;
1919 framebuffer->completeness(width, height, samples);
1920
1921 float threshold = 0.5f;
1922
1923 for(int i = 0; i < samples; i++)
1924 {
1925 mask <<= 1;
1926
1927 if((i + 1) * mState.sampleCoverageValue >= threshold)
1928 {
1929 threshold += 1.0f;
1930 mask |= 1;
1931 }
1932 }
1933 }
1934
1935 if(mState.sampleCoverageInvert)
1936 {
1937 mask = ~mask;
1938 }
1939
1940 device->setMultiSampleMask(mask);
1941 }
1942 else
1943 {
1944 device->setMultiSampleMask(0xFFFFFFFF);
1945 }
1946
1947 mSampleStateDirty = false;
1948 }
1949
1950 if(mDitherStateDirty)
1951 {
1952 // UNIMPLEMENTED(); // FIXME
1953
1954 mDitherStateDirty = false;
1955 }
1956
1957 switch(mState.shadeModel)
1958 {
1959 default: UNREACHABLE(mState.shadeModel);
1960 case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
1961 case GL_FLAT: device->setShadingMode(sw::SHADING_FLAT); break;
1962 }
1963
1964 device->setLightingEnable(lightingEnabled);
1965 device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
1966
1967 for(int i = 0; i < MAX_LIGHTS; i++)
1968 {
1969 device->setLightEnable(i, light[i].enabled);
1970 device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
1971 device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
1972 device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
1973 device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
1974
1975 if(light[i].position.w != 0.0f)
1976 {
1977 device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
1978 }
1979 else // Directional light
1980 {
1981 // Hack: set the position far way
1982 float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));
1983 device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
1984 }
1985 }
1986
1987 device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
1988 device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
1989 device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
1990 device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
1991 device->setMaterialShininess(materialShininess);
1992
1993 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
1994 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
1995 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
1996 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
1997
Nicolas Capens00bfa182016-05-20 21:30:54 -07001998 device->setProjectionMatrix(projectionStack.current());
Nicolas Capens0bac2852016-05-07 06:09:58 -04001999 device->setModelMatrix(modelViewStack.current());
2000 device->setTextureMatrix(0, textureStack0.current());
2001 device->setTextureMatrix(1, textureStack1.current());
2002 device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
2003 device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
2004 device->setTexGen(0, sw::TEXGEN_NONE);
2005 device->setTexGen(1, sw::TEXGEN_NONE);
2006
2007 device->setAlphaTestEnable(alphaTestEnabled);
2008 device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));
2009 device->setAlphaReference(alphaTestRef * 0xFF);
2010
2011 device->setFogEnable(fogEnabled);
2012 device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));
2013 device->setFogDensity(fogDensity);
2014 device->setFogStart(fogStart);
2015 device->setFogEnd(fogEnd);
2016
2017 switch(fogMode)
2018 {
2019 case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
2020 case GL_EXP: device->setVertexFogMode(sw::FOG_EXP); break;
2021 case GL_EXP2: device->setVertexFogMode(sw::FOG_EXP2); break;
2022 default: UNREACHABLE(fogMode);
2023 }
2024
2025 device->setColorLogicOpEnabled(colorLogicOpEnabled);
2026 device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));
2027
2028 device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);
2029}
2030
2031GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
2032{
2033 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
2034
2035 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
2036 if(err != GL_NO_ERROR)
2037 {
2038 return err;
2039 }
2040
2041 device->resetInputStreams(false);
2042
2043 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2044 {
2045 sw::Resource *resource = attributes[i].vertexBuffer;
2046 const void *buffer = (char*)resource->data() + attributes[i].offset;
2047
2048 int stride = attributes[i].stride;
2049
2050 buffer = (char*)buffer + stride * base;
2051
2052 sw::Stream attribute(resource, buffer, stride);
2053
2054 attribute.type = attributes[i].type;
2055 attribute.count = attributes[i].count;
2056 attribute.normalized = attributes[i].normalized;
2057
2058 device->setInputStream(i, attribute);
2059 }
2060
2061 return GL_NO_ERROR;
2062}
2063
2064// Applies the indices and element array bindings
2065GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
2066{
2067 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
2068
2069 if(err == GL_NO_ERROR)
2070 {
2071 device->setIndexBuffer(indexInfo->indexBuffer);
2072 }
2073
2074 return err;
2075}
2076
2077void Context::applyTextures()
2078{
2079 for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
2080 {
2081 Texture *texture = nullptr;
2082
2083 if(textureExternalEnabled[unit])
2084 {
2085 texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
2086 }
2087 else if(texture2Denabled[unit])
2088 {
2089 texture = getSamplerTexture(unit, TEXTURE_2D);
2090 }
2091
2092 if(texture && texture->isSamplerComplete())
2093 {
2094 texture->autoGenerateMipmaps();
2095
2096 GLenum wrapS = texture->getWrapS();
2097 GLenum wrapT = texture->getWrapT();
2098 GLenum minFilter = texture->getMinFilter();
2099 GLenum magFilter = texture->getMagFilter();
2100 GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2101
2102 device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
2103 device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
2104
2105 device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
2106 device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));
2107 device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
2108
2109 applyTexture(unit, texture);
2110
2111 device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));
2112
2113 if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
2114 {
2115 device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE); // Cs
2116 device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2117 device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT); // Cp
2118 device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2119 device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT); // Cc
2120 device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2121
2122 device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE); // As
2123 device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2124 device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT); // Ap
2125 device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2126 device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT); // Ac
2127 device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2128
2129 GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
2130
2131 switch(mState.textureUnit[unit].environmentMode)
2132 {
2133 case GL_REPLACE:
2134 if(IsAlpha(texFormat)) // GL_ALPHA
2135 {
2136 // Cv = Cp, Av = As
2137 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2138 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2139 }
2140 else if(IsRGB(texFormat)) // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2141 {
2142 // Cv = Cs, Av = Ap
2143 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2144 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2145 }
2146 else if(IsRGBA(texFormat)) // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2147 {
2148 // Cv = Cs, Av = As
2149 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2150 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2151 }
2152 else UNREACHABLE(texFormat);
2153 break;
2154 case GL_MODULATE:
2155 if(IsAlpha(texFormat)) // GL_ALPHA
2156 {
2157 // Cv = Cp, Av = ApAs
2158 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2159 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2160 }
2161 else if(IsRGB(texFormat)) // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2162 {
2163 // Cv = CpCs, Av = Ap
2164 device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
2165 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2166 }
2167 else if(IsRGBA(texFormat)) // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2168 {
2169 // Cv = CpCs, Av = ApAs
2170 device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
2171 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2172 }
2173 else UNREACHABLE(texFormat);
2174 break;
2175 case GL_DECAL:
2176 if(texFormat == GL_ALPHA ||
2177 texFormat == GL_LUMINANCE ||
2178 texFormat == GL_LUMINANCE_ALPHA)
2179 {
2180 // undefined // FIXME: Log
2181 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2182 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2183 }
2184 else if(IsRGB(texFormat)) // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2185 {
2186 // Cv = Cs, Av = Ap
2187 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2188 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2189 }
2190 else if(IsRGBA(texFormat)) // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2191 {
2192 // Cv = Cp(1 - As) + CsAs, Av = Ap
2193 device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA); // Alpha * (Arg1 - Arg2) + Arg2
2194 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2195 }
2196 else UNREACHABLE(texFormat);
2197 break;
2198 case GL_BLEND:
2199 if(IsAlpha(texFormat)) // GL_ALPHA
2200 {
2201 // Cv = Cp, Av = ApAs
2202 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2203 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2204 }
2205 else if(IsRGB(texFormat)) // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2206 {
2207 // Cv = Cp(1 - Cs) + CcCs, Av = Ap
2208 device->setStageOperation(unit, sw::TextureStage::STAGE_LERP); // Arg3 * (Arg1 - Arg2) + Arg2
2209 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2210 }
2211 else if(IsRGBA(texFormat)) // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2212 {
2213 // Cv = Cp(1 - Cs) + CcCs, Av = ApAs
2214 device->setStageOperation(unit, sw::TextureStage::STAGE_LERP); // Arg3 * (Arg1 - Arg2) + Arg2
2215 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2216 }
2217 else UNREACHABLE(texFormat);
2218 break;
2219 case GL_ADD:
2220 if(IsAlpha(texFormat)) // GL_ALPHA
2221 {
2222 // Cv = Cp, Av = ApAs
2223 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2224 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2225 }
2226 else if(IsRGB(texFormat)) // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2227 {
2228 // Cv = Cp + Cs, Av = Ap
2229 device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2230 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2231 }
2232 else if(IsRGBA(texFormat)) // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2233 {
2234 // Cv = Cp + Cs, Av = ApAs
2235 device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2236 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2237 }
2238 else UNREACHABLE(texFormat);
2239 break;
2240 default:
2241 UNREACHABLE(mState.textureUnit[unit].environmentMode);
2242 }
2243 }
2244 else // GL_COMBINE
2245 {
2246 device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
2247 device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
2248 device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
2249 device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
2250 device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
2251 device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
2252
2253 device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
2254
2255 device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
2256 device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
2257 device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
2258 device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
2259 device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
2260 device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
2261
2262 device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
2263 }
2264 }
2265 else
2266 {
2267 applyTexture(unit, nullptr);
2268
2269 device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
2270 device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2271 device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2272
2273 device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
2274 device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2275 device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2276 }
2277 }
2278}
2279
2280void Context::setTextureEnvMode(GLenum texEnvMode)
2281{
2282 mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
2283}
2284
2285void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
2286{
2287 mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};
2288}
2289
2290void Context::setCombineRGB(GLenum combineRGB)
2291{
2292 mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
2293}
2294
2295void Context::setCombineAlpha(GLenum combineAlpha)
2296{
2297 mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
2298}
2299
2300void Context::setOperand0RGB(GLenum operand)
2301{
2302 mState.textureUnit[mState.activeSampler].operand0RGB = operand;
2303}
2304
2305void Context::setOperand1RGB(GLenum operand)
2306{
2307 mState.textureUnit[mState.activeSampler].operand1RGB = operand;
2308}
2309
2310void Context::setOperand2RGB(GLenum operand)
2311{
2312 mState.textureUnit[mState.activeSampler].operand2RGB = operand;
2313}
2314
2315void Context::setOperand0Alpha(GLenum operand)
2316{
2317 mState.textureUnit[mState.activeSampler].operand0Alpha = operand;
2318}
2319
2320void Context::setOperand1Alpha(GLenum operand)
2321{
2322 mState.textureUnit[mState.activeSampler].operand1Alpha = operand;
2323}
2324
2325void Context::setOperand2Alpha(GLenum operand)
2326{
2327 mState.textureUnit[mState.activeSampler].operand2Alpha = operand;
2328}
2329
2330void Context::setSrc0RGB(GLenum src)
2331{
2332 mState.textureUnit[mState.activeSampler].src0RGB = src;
2333}
2334
2335void Context::setSrc1RGB(GLenum src)
2336{
2337 mState.textureUnit[mState.activeSampler].src1RGB = src;
2338}
2339
2340void Context::setSrc2RGB(GLenum src)
2341{
2342 mState.textureUnit[mState.activeSampler].src2RGB = src;
2343}
2344
2345void Context::setSrc0Alpha(GLenum src)
2346{
2347 mState.textureUnit[mState.activeSampler].src0Alpha = src;
2348}
2349
2350void Context::setSrc1Alpha(GLenum src)
2351{
2352 mState.textureUnit[mState.activeSampler].src1Alpha = src;
2353}
2354
2355void Context::setSrc2Alpha(GLenum src)
2356{
2357 mState.textureUnit[mState.activeSampler].src2Alpha = src;
2358}
2359
2360void Context::applyTexture(int index, Texture *baseTexture)
2361{
2362 sw::Resource *resource = 0;
2363
2364 if(baseTexture)
2365 {
2366 resource = baseTexture->getResource();
2367 }
2368
2369 device->setTextureResource(index, resource);
2370
2371 if(baseTexture)
2372 {
Nicolas Capensb3f54e82017-12-19 13:38:18 -05002373 int topLevel = baseTexture->getTopLevel();
Nicolas Capens0bac2852016-05-07 06:09:58 -04002374
2375 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
2376 {
2377 Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2378
2379 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2380 {
2381 int surfaceLevel = mipmapLevel;
2382
2383 if(surfaceLevel < 0)
2384 {
2385 surfaceLevel = 0;
2386 }
Nicolas Capensb3f54e82017-12-19 13:38:18 -05002387 else if(surfaceLevel > topLevel)
Nicolas Capens0bac2852016-05-07 06:09:58 -04002388 {
Nicolas Capensb3f54e82017-12-19 13:38:18 -05002389 surfaceLevel = topLevel;
Nicolas Capens0bac2852016-05-07 06:09:58 -04002390 }
2391
2392 egl::Image *surface = texture->getImage(surfaceLevel);
2393 device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2394 }
2395 }
2396 else UNIMPLEMENTED();
2397 }
2398 else
2399 {
2400 device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
2401 }
2402}
2403
2404void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2405 GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2406{
2407 Framebuffer *framebuffer = getFramebuffer();
2408 int framebufferWidth, framebufferHeight, framebufferSamples;
2409
Alexis Hetu5cd502b2018-03-22 08:29:31 -04002410 if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES))
Nicolas Capens0bac2852016-05-07 06:09:58 -04002411 {
2412 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2413 }
2414
2415 if(getFramebufferName() != 0 && framebufferSamples != 0)
2416 {
2417 return error(GL_INVALID_OPERATION);
2418 }
2419
2420 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
2421 {
2422 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
2423 {
2424 return error(GL_INVALID_OPERATION);
2425 }
2426 }
2427
Nicolas Capens3b4a25c2018-02-22 20:14:07 -05002428 GLsizei outputPitch = gl::ComputePitch(width, format, type, mState.packAlignment);
Nicolas Capens0bac2852016-05-07 06:09:58 -04002429
2430 // Sized query sanity check
2431 if(bufSize)
2432 {
2433 int requiredSize = outputPitch * height;
2434 if(requiredSize > *bufSize)
2435 {
2436 return error(GL_INVALID_OPERATION);
2437 }
2438 }
2439
2440 egl::Image *renderTarget = framebuffer->getRenderTarget();
2441
2442 if(!renderTarget)
2443 {
2444 return error(GL_OUT_OF_MEMORY);
2445 }
2446
2447 sw::Rect rect = {x, y, x + width, y + height};
2448 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2449
Nicolas Capense5a57882018-02-07 17:18:00 -05002450 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, 0, sw::LOCK_READONLY);
Nicolas Capens0bac2852016-05-07 06:09:58 -04002451 unsigned char *dest = (unsigned char*)pixels;
2452 int inputPitch = (int)renderTarget->getPitch();
2453
2454 for(int j = 0; j < rect.y1 - rect.y0; j++)
2455 {
2456 unsigned short *dest16 = (unsigned short*)dest;
2457 unsigned int *dest32 = (unsigned int*)dest;
2458
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002459 if(renderTarget->getExternalFormat() == sw::FORMAT_A8B8G8R8 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002460 format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2461 {
2462 memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2463 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002464 else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002465 format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2466 {
2467 for(int i = 0; i < rect.x1 - rect.x0; i++)
2468 {
2469 unsigned int argb = *(unsigned int*)(source + 4 * i);
2470
2471 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
2472 }
2473 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002474 else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002475 format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2476 {
2477 for(int i = 0; i < rect.x1 - rect.x0; i++)
2478 {
2479 unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2480
2481 dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
2482 }
2483 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002484 else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002485 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2486 {
2487 for(int i = 0; i < rect.x1 - rect.x0; i++)
2488 {
2489 unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2490
2491 dest32[i] = xrgb | 0xFF000000;
2492 }
2493 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002494 else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002495 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2496 {
2497 memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2498 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002499 else if(renderTarget->getExternalFormat() == sw::FORMAT_A1R5G5B5 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002500 format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
2501 {
2502 memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2503 }
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002504 else if(renderTarget->getExternalFormat() == sw::FORMAT_R5G6B5 &&
Nicolas Capens0bac2852016-05-07 06:09:58 -04002505 format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT
2506 {
2507 memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2508 }
2509 else
2510 {
2511 for(int i = 0; i < rect.x1 - rect.x0; i++)
2512 {
Ben Clayton60a3d6f2019-02-26 17:24:46 +00002513 float r = 0.f;
2514 float g = 0.f;
2515 float b = 0.f;
2516 float a = 0.f;
Nicolas Capens0bac2852016-05-07 06:09:58 -04002517
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002518 switch(renderTarget->getExternalFormat())
Nicolas Capens0bac2852016-05-07 06:09:58 -04002519 {
2520 case sw::FORMAT_R5G6B5:
2521 {
2522 unsigned short rgb = *(unsigned short*)(source + 2 * i);
2523
2524 a = 1.0f;
2525 b = (rgb & 0x001F) * (1.0f / 0x001F);
2526 g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2527 r = (rgb & 0xF800) * (1.0f / 0xF800);
2528 }
2529 break;
2530 case sw::FORMAT_A1R5G5B5:
2531 {
2532 unsigned short argb = *(unsigned short*)(source + 2 * i);
2533
2534 a = (argb & 0x8000) ? 1.0f : 0.0f;
2535 b = (argb & 0x001F) * (1.0f / 0x001F);
2536 g = (argb & 0x03E0) * (1.0f / 0x03E0);
2537 r = (argb & 0x7C00) * (1.0f / 0x7C00);
2538 }
2539 break;
2540 case sw::FORMAT_A8R8G8B8:
2541 {
2542 unsigned int argb = *(unsigned int*)(source + 4 * i);
2543
2544 a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2545 b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2546 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2547 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2548 }
2549 break;
2550 case sw::FORMAT_A8B8G8R8:
2551 {
2552 unsigned int abgr = *(unsigned int*)(source + 4 * i);
2553
2554 a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
2555 b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2556 g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2557 r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
2558 }
2559 break;
2560 case sw::FORMAT_X8R8G8B8:
2561 {
2562 unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2563
2564 a = 1.0f;
2565 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2566 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2567 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2568 }
2569 break;
2570 case sw::FORMAT_X8B8G8R8:
2571 {
2572 unsigned int xbgr = *(unsigned int*)(source + 4 * i);
2573
2574 a = 1.0f;
2575 b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2576 g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2577 r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
2578 }
2579 break;
2580 case sw::FORMAT_A2R10G10B10:
2581 {
2582 unsigned int argb = *(unsigned int*)(source + 4 * i);
2583
2584 a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2585 b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2586 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2587 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2588 }
2589 break;
2590 default:
2591 UNIMPLEMENTED(); // FIXME
Nicolas Capens3e5f6fd2018-02-26 17:47:06 -05002592 UNREACHABLE(renderTarget->getExternalFormat());
Nicolas Capens0bac2852016-05-07 06:09:58 -04002593 }
2594
2595 switch(format)
2596 {
2597 case GL_RGBA:
2598 switch(type)
2599 {
2600 case GL_UNSIGNED_BYTE:
2601 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
2602 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2603 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
2604 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2605 break;
2606 default: UNREACHABLE(type);
2607 }
2608 break;
2609 case GL_BGRA_EXT:
2610 switch(type)
2611 {
2612 case GL_UNSIGNED_BYTE:
2613 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
2614 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2615 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
2616 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2617 break;
2618 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2619 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2620 // this type is packed as follows:
2621 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
2622 // --------------------------------------------------------------------------------
2623 // | 4th | 3rd | 2nd | 1st component |
2624 // --------------------------------------------------------------------------------
2625 // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2626 dest16[i] =
2627 ((unsigned short)(15 * a + 0.5f) << 12)|
2628 ((unsigned short)(15 * r + 0.5f) << 8) |
2629 ((unsigned short)(15 * g + 0.5f) << 4) |
2630 ((unsigned short)(15 * b + 0.5f) << 0);
2631 break;
2632 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2633 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2634 // this type is packed as follows:
2635 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
2636 // --------------------------------------------------------------------------------
2637 // | 4th | 3rd | 2nd | 1st component |
2638 // --------------------------------------------------------------------------------
2639 // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2640 dest16[i] =
2641 ((unsigned short)( a + 0.5f) << 15) |
2642 ((unsigned short)(31 * r + 0.5f) << 10) |
2643 ((unsigned short)(31 * g + 0.5f) << 5) |
2644 ((unsigned short)(31 * b + 0.5f) << 0);
2645 break;
2646 default: UNREACHABLE(type);
2647 }
2648 break;
2649 case GL_RGB:
2650 switch(type)
2651 {
2652 case GL_UNSIGNED_SHORT_5_6_5:
2653 dest16[i] =
2654 ((unsigned short)(31 * b + 0.5f) << 0) |
2655 ((unsigned short)(63 * g + 0.5f) << 5) |
2656 ((unsigned short)(31 * r + 0.5f) << 11);
2657 break;
2658 default: UNREACHABLE(type);
2659 }
2660 break;
2661 default: UNREACHABLE(format);
2662 }
2663 }
2664 }
2665
2666 source += inputPitch;
2667 dest += outputPitch;
2668 }
2669
2670 renderTarget->unlock();
2671 renderTarget->release();
2672}
2673
2674void Context::clear(GLbitfield mask)
2675{
2676 Framebuffer *framebuffer = getFramebuffer();
2677
2678 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
2679 {
2680 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2681 }
2682
2683 if(!applyRenderTarget())
2684 {
2685 return;
2686 }
2687
2688 float depth = clamp01(mState.depthClearValue);
2689 int stencil = mState.stencilClearValue & 0x000000FF;
2690
2691 if(mask & GL_COLOR_BUFFER_BIT)
2692 {
2693 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2694 (mState.colorMaskGreen ? 0x2 : 0) |
2695 (mState.colorMaskBlue ? 0x4 : 0) |
2696 (mState.colorMaskAlpha ? 0x8 : 0);
2697
2698 if(rgbaMask != 0)
2699 {
2700 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
2701 }
2702 }
2703
2704 if(mask & GL_DEPTH_BUFFER_BIT)
2705 {
2706 if(mState.depthMask != 0)
2707 {
2708 device->clearDepth(depth);
2709 }
2710 }
2711
2712 if(mask & GL_STENCIL_BUFFER_BIT)
2713 {
2714 if(mState.stencilWritemask != 0)
2715 {
2716 device->clearStencil(stencil, mState.stencilWritemask);
2717 }
2718 }
2719}
2720
2721void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2722{
2723 sw::DrawType primitiveType;
2724 int primitiveCount;
2725
2726 if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
2727 return error(GL_INVALID_ENUM);
2728
2729 if(primitiveCount <= 0)
2730 {
2731 return;
2732 }
2733
2734 if(!applyRenderTarget())
2735 {
2736 return;
2737 }
2738
2739 applyState(mode);
2740
2741 GLenum err = applyVertexBuffer(0, first, count);
2742 if(err != GL_NO_ERROR)
2743 {
2744 return error(err);
2745 }
2746
2747 applyTextures();
2748
2749 if(!cullSkipsDraw(mode))
2750 {
2751 device->drawPrimitive(primitiveType, primitiveCount);
2752 }
2753}
2754
2755void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2756{
2757 if(!indices && !mState.elementArrayBuffer)
2758 {
2759 return error(GL_INVALID_OPERATION);
2760 }
2761
2762 sw::DrawType primitiveType;
2763 int primitiveCount;
2764
2765 if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
2766 return error(GL_INVALID_ENUM);
2767
2768 if(primitiveCount <= 0)
2769 {
2770 return;
2771 }
2772
2773 if(!applyRenderTarget())
2774 {
2775 return;
2776 }
2777
2778 applyState(mode);
2779
2780 TranslatedIndexData indexInfo;
2781 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2782 if(err != GL_NO_ERROR)
2783 {
2784 return error(err);
2785 }
2786
2787 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2788 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2789 if(err != GL_NO_ERROR)
2790 {
2791 return error(err);
2792 }
2793
2794 applyTextures();
2795
2796 if(!cullSkipsDraw(mode))
2797 {
2798 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
2799 }
2800}
2801
2802void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
2803{
2804 es1::Framebuffer *framebuffer = getFramebuffer();
Alexis Hetu5cd502b2018-03-22 08:29:31 -04002805 es1::Renderbuffer *renderbuffer = framebuffer ? framebuffer->getColorbuffer() : nullptr;
2806 if(!renderbuffer)
2807 {
2808 return;
2809 }
2810
Nicolas Capens0bac2852016-05-07 06:09:58 -04002811 float targetWidth = (float)renderbuffer->getWidth();
2812 float targetHeight = (float)renderbuffer->getHeight();
2813 float x0 = 2.0f * x / targetWidth - 1.0f;
2814 float y0 = 2.0f * y / targetHeight - 1.0f;
2815 float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
2816 float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
2817 float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
2818
2819 float vertices[][3] = {{x0, y0, Zw},
2820 {x0, y1, Zw},
2821 {x1, y0, Zw},
2822 {x1, y1, Zw}};
2823
2824 ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0); // Multi-texturing unimplemented
2825 es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
2826 float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);
2827 float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);
2828 int Ucr = texture->getCropRectU();
2829 int Vcr = texture->getCropRectV();
2830 int Wcr = texture->getCropRectW();
2831 int Hcr = texture->getCropRectH();
2832
2833 float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
2834 {Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
2835 {(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
2836 {(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
2837
2838 VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
2839 VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
2840 gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;
2841 mState.arrayBuffer = nullptr;
2842
2843 glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
2844 glEnableClientState(GL_VERTEX_ARRAY);
2845 glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
2846 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2847
2848 sw::Matrix P = projectionStack.current();
2849 sw::Matrix M = modelViewStack.current();
2850 sw::Matrix T = textureStack0.current();
2851
2852 projectionStack.identity();
2853 modelViewStack.identity();
2854 textureStack0.identity();
2855
2856 drawArrays(GL_TRIANGLE_STRIP, 0, 4);
2857
2858 // Restore state
2859 mState.vertexAttribute[sw::Position] = oldPositionAttribute;
2860 mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
2861 mState.arrayBuffer = oldArrayBuffer;
2862 oldArrayBuffer = nullptr;
2863 oldPositionAttribute.mBoundBuffer = nullptr;
2864 oldTexCoord0Attribute.mBoundBuffer = nullptr;
2865 textureStack0.load(T);
2866 modelViewStack.load(M);
2867 projectionStack.load(P);
2868}
2869
Nicolas Capens81aa97b2017-06-27 17:08:08 -04002870void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
2871{
Alexis Hetu10c74a62017-11-29 14:00:32 -05002872 sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
2873 device->blit(source, sRectF, dest, dRect, false);
Nicolas Capens81aa97b2017-06-27 17:08:08 -04002874}
2875
Nicolas Capens0bac2852016-05-07 06:09:58 -04002876void Context::finish()
2877{
2878 device->finish();
2879}
2880
2881void Context::flush()
2882{
2883 // We don't queue anything without processing it as fast as possible
2884}
2885
2886void Context::recordInvalidEnum()
2887{
2888 mInvalidEnum = true;
2889}
2890
2891void Context::recordInvalidValue()
2892{
2893 mInvalidValue = true;
2894}
2895
2896void Context::recordInvalidOperation()
2897{
2898 mInvalidOperation = true;
2899}
2900
2901void Context::recordOutOfMemory()
2902{
2903 mOutOfMemory = true;
2904}
2905
2906void Context::recordInvalidFramebufferOperation()
2907{
2908 mInvalidFramebufferOperation = true;
2909}
2910
2911void Context::recordMatrixStackOverflow()
2912{
2913 mMatrixStackOverflow = true;
2914}
2915
2916void Context::recordMatrixStackUnderflow()
2917{
2918 mMatrixStackUnderflow = true;
2919}
2920
2921// Get one of the recorded errors and clear its flag, if any.
2922// [OpenGL ES 2.0.24] section 2.5 page 13.
2923GLenum Context::getError()
2924{
2925 if(mInvalidEnum)
2926 {
2927 mInvalidEnum = false;
2928
2929 return GL_INVALID_ENUM;
2930 }
2931
2932 if(mInvalidValue)
2933 {
2934 mInvalidValue = false;
2935
2936 return GL_INVALID_VALUE;
2937 }
2938
2939 if(mInvalidOperation)
2940 {
2941 mInvalidOperation = false;
2942
2943 return GL_INVALID_OPERATION;
2944 }
2945
2946 if(mOutOfMemory)
2947 {
2948 mOutOfMemory = false;
2949
2950 return GL_OUT_OF_MEMORY;
2951 }
2952
2953 if(mInvalidFramebufferOperation)
2954 {
2955 mInvalidFramebufferOperation = false;
2956
2957 return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2958 }
2959
2960 if(mMatrixStackOverflow)
2961 {
2962 mMatrixStackOverflow = false;
2963
2964 return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2965 }
2966
2967 if(mMatrixStackUnderflow)
2968 {
2969 mMatrixStackUnderflow = false;
2970
2971 return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2972 }
2973
2974 return GL_NO_ERROR;
2975}
2976
2977int Context::getSupportedMultisampleCount(int requested)
2978{
2979 int supported = 0;
2980
2981 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
2982 {
2983 if(supported >= requested)
2984 {
2985 return supported;
2986 }
2987
2988 supported = multisampleCount[i];
2989 }
2990
2991 return supported;
2992}
2993
2994void Context::detachBuffer(GLuint buffer)
2995{
2996 // [OpenGL ES 2.0.24] section 2.9 page 22:
2997 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2998 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2999
3000 if(mState.arrayBuffer.name() == buffer)
3001 {
3002 mState.arrayBuffer = nullptr;
3003 }
3004
3005 if(mState.elementArrayBuffer.name() == buffer)
3006 {
3007 mState.elementArrayBuffer = nullptr;
3008 }
3009
3010 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3011 {
3012 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3013 {
3014 mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
3015 }
3016 }
3017}
3018
3019void Context::detachTexture(GLuint texture)
3020{
3021 // [OpenGL ES 2.0.24] section 3.8 page 84:
3022 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3023 // rebound to texture object zero
3024
3025 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3026 {
3027 for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
3028 {
3029 if(mState.samplerTexture[type][sampler].name() == texture)
3030 {
3031 mState.samplerTexture[type][sampler] = nullptr;
3032 }
3033 }
3034 }
3035
3036 // [OpenGL ES 2.0.24] section 4.4 page 112:
3037 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3038 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3039 // image was attached in the currently bound framebuffer.
3040
3041 Framebuffer *framebuffer = getFramebuffer();
3042
3043 if(framebuffer)
3044 {
3045 framebuffer->detachTexture(texture);
3046 }
3047}
3048
3049void Context::detachFramebuffer(GLuint framebuffer)
3050{
3051 // [OpenGL ES 2.0.24] section 4.4 page 107:
3052 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3053 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3054
3055 if(mState.framebuffer == framebuffer)
3056 {
3057 bindFramebuffer(0);
3058 }
3059}
3060
3061void Context::detachRenderbuffer(GLuint renderbuffer)
3062{
3063 // [OpenGL ES 2.0.24] section 4.4 page 109:
3064 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3065 // had been executed with the target RENDERBUFFER and name of zero.
3066
3067 if(mState.renderbuffer.name() == renderbuffer)
3068 {
3069 bindRenderbuffer(0);
3070 }
3071
3072 // [OpenGL ES 2.0.24] section 4.4 page 111:
3073 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3074 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3075 // point to which this image was attached in the currently bound framebuffer.
3076
3077 Framebuffer *framebuffer = getFramebuffer();
3078
3079 if(framebuffer)
3080 {
3081 framebuffer->detachRenderbuffer(renderbuffer);
3082 }
3083}
3084
3085bool Context::cullSkipsDraw(GLenum drawMode)
3086{
3087 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3088}
3089
3090bool Context::isTriangleMode(GLenum drawMode)
3091{
3092 switch(drawMode)
3093 {
3094 case GL_TRIANGLES:
3095 case GL_TRIANGLE_FAN:
3096 case GL_TRIANGLE_STRIP:
3097 return true;
3098 case GL_POINTS:
3099 case GL_LINES:
3100 case GL_LINE_LOOP:
3101 case GL_LINE_STRIP:
3102 return false;
3103 default: UNREACHABLE(drawMode);
3104 }
3105
3106 return false;
3107}
3108
3109void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3110{
3111 ASSERT(index < MAX_VERTEX_ATTRIBS);
3112
3113 mState.vertexAttribute[index].mCurrentValue[0] = x;
3114 mState.vertexAttribute[index].mCurrentValue[1] = y;
3115 mState.vertexAttribute[index].mCurrentValue[2] = z;
3116 mState.vertexAttribute[index].mCurrentValue[3] = w;
3117
3118 mVertexDataManager->dirtyCurrentValue(index);
3119}
3120
Nicolas Capens31c07a32017-06-13 23:44:13 -04003121void Context::bindTexImage(gl::Surface *surface)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003122{
3123 es1::Texture2D *textureObject = getTexture2D();
3124
3125 if(textureObject)
3126 {
3127 textureObject->bindTexImage(surface);
3128 }
3129}
3130
3131EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3132{
3133 switch(target)
3134 {
3135 case EGL_GL_TEXTURE_2D_KHR:
3136 break;
3137 case EGL_GL_RENDERBUFFER_KHR:
3138 break;
3139 default:
3140 return EGL_BAD_PARAMETER;
3141 }
3142
3143 if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3144 {
3145 return EGL_BAD_MATCH;
3146 }
3147
3148 if(target == EGL_GL_TEXTURE_2D_KHR)
3149 {
3150 Texture *texture = getTexture(name);
3151
3152 if(!texture || texture->getTarget() != GL_TEXTURE_2D)
3153 {
3154 return EGL_BAD_PARAMETER;
3155 }
3156
3157 if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
3158 {
3159 return EGL_BAD_ACCESS;
3160 }
3161
3162 if(textureLevel != 0 && !texture->isSamplerComplete())
3163 {
3164 return EGL_BAD_PARAMETER;
3165 }
3166
Nicolas Capensb3f54e82017-12-19 13:38:18 -05003167 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
Nicolas Capens0bac2852016-05-07 06:09:58 -04003168 {
3169 return EGL_BAD_PARAMETER;
3170 }
3171 }
3172 else if(target == EGL_GL_RENDERBUFFER_KHR)
3173 {
3174 Renderbuffer *renderbuffer = getRenderbuffer(name);
3175
3176 if(!renderbuffer)
3177 {
3178 return EGL_BAD_PARAMETER;
3179 }
3180
3181 if(renderbuffer->isShared()) // Already an EGLImage sibling
3182 {
3183 return EGL_BAD_ACCESS;
3184 }
3185 }
3186 else UNREACHABLE(target);
3187
3188 return EGL_SUCCESS;
3189}
3190
3191egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3192{
3193 if(target == EGL_GL_TEXTURE_2D_KHR)
3194 {
3195 es1::Texture *texture = getTexture(name);
3196
3197 return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
3198 }
3199 else if(target == EGL_GL_RENDERBUFFER_KHR)
3200 {
3201 es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
3202
3203 return renderbuffer->createSharedImage();
3204 }
3205 else UNREACHABLE(target);
3206
Nicolas Capens58df2f62016-06-07 14:48:56 -04003207 return nullptr;
3208}
3209
3210egl::Image *Context::getSharedImage(GLeglImageOES image)
3211{
3212 return display->getSharedImage(image);
Nicolas Capens0bac2852016-05-07 06:09:58 -04003213}
3214
3215Device *Context::getDevice()
3216{
3217 return device;
3218}
3219
3220void Context::setMatrixMode(GLenum mode)
3221{
3222 matrixMode = mode;
3223}
3224
3225sw::MatrixStack &Context::currentMatrixStack()
3226{
3227 switch(matrixMode)
3228 {
3229 case GL_MODELVIEW:
3230 return modelViewStack;
3231 case GL_PROJECTION:
3232 return projectionStack;
3233 case GL_TEXTURE:
3234 switch(mState.activeSampler)
3235 {
3236 case 0: return textureStack0;
3237 case 1: return textureStack1;
3238 }
3239 break;
3240 }
3241
3242 UNREACHABLE(matrixMode);
3243 return textureStack0;
3244}
3245
3246void Context::loadIdentity()
3247{
3248 currentMatrixStack().identity();
3249}
3250
3251void Context::load(const GLfloat *m)
3252{
3253 currentMatrixStack().load(m);
3254}
3255
3256void Context::pushMatrix()
3257{
3258 if(!currentMatrixStack().push())
3259 {
3260 return error(GL_STACK_OVERFLOW);
3261 }
3262}
3263
3264void Context::popMatrix()
3265{
3266 if(!currentMatrixStack().pop())
3267 {
3268 return error(GL_STACK_OVERFLOW);
3269 }
3270}
3271
3272void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3273{
3274 currentMatrixStack().rotate(angle, x, y, z);
3275}
3276
3277void Context::translate(GLfloat x, GLfloat y, GLfloat z)
3278{
3279 currentMatrixStack().translate(x, y, z);
3280}
3281
3282void Context::scale(GLfloat x, GLfloat y, GLfloat z)
3283{
3284 currentMatrixStack().scale(x, y, z);
3285}
3286
3287void Context::multiply(const GLfloat *m)
3288{
3289 currentMatrixStack().multiply(m);
3290}
3291
3292void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3293{
3294 currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
3295}
3296
3297void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3298{
3299 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
3300}
3301
3302void Context::setClipPlane(int index, const float plane[4])
3303{
3304 sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);
3305 device->setClipPlane(index, &clipPlane.A);
3306}
3307
3308void Context::setClipPlaneEnabled(int index, bool enable)
3309{
3310 clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);
3311 device->setClipFlags(clipFlags);
3312}
3313
3314bool Context::isClipPlaneEnabled(int index) const
3315{
3316 return (clipFlags & (1 << index)) != 0;
3317}
3318
3319void Context::setColorLogicOpEnabled(bool enable)
3320{
3321 colorLogicOpEnabled = enable;
3322}
3323
3324bool Context::isColorLogicOpEnabled() const
3325{
3326 return colorLogicOpEnabled;
3327}
3328
3329void Context::setLogicalOperation(GLenum logicOp)
3330{
3331 logicalOperation = logicOp;
3332}
3333
3334void Context::setLineSmoothEnabled(bool enable)
3335{
3336 lineSmoothEnabled = enable;
3337}
3338
3339bool Context::isLineSmoothEnabled() const
3340{
3341 return lineSmoothEnabled;
3342}
3343
3344void Context::setColorMaterialEnabled(bool enable)
3345{
3346 colorMaterialEnabled = enable;
3347}
3348
3349bool Context::isColorMaterialEnabled() const
3350{
3351 return colorMaterialEnabled;
3352}
3353
3354void Context::setNormalizeEnabled(bool enable)
3355{
3356 normalizeEnabled = enable;
3357}
3358
3359bool Context::isNormalizeEnabled() const
3360{
3361 return normalizeEnabled;
3362}
3363
3364void Context::setRescaleNormalEnabled(bool enable)
3365{
3366 rescaleNormalEnabled = enable;
3367}
3368
3369bool Context::isRescaleNormalEnabled() const
3370{
3371 return rescaleNormalEnabled;
3372}
3373
3374void Context::setVertexArrayEnabled(bool enable)
3375{
3376 mState.vertexAttribute[sw::Position].mArrayEnabled = enable;
3377}
3378
3379bool Context::isVertexArrayEnabled() const
3380{
3381 return mState.vertexAttribute[sw::Position].mArrayEnabled;
3382}
3383
3384void Context::setNormalArrayEnabled(bool enable)
3385{
3386 mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;
3387}
3388
3389bool Context::isNormalArrayEnabled() const
3390{
3391 return mState.vertexAttribute[sw::Normal].mArrayEnabled;
3392}
3393
3394void Context::setColorArrayEnabled(bool enable)
3395{
3396 mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;
3397}
3398
3399bool Context::isColorArrayEnabled() const
3400{
3401 return mState.vertexAttribute[sw::Color0].mArrayEnabled;
3402}
3403
3404void Context::setPointSizeArrayEnabled(bool enable)
3405{
3406 mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;
3407}
3408
3409bool Context::isPointSizeArrayEnabled() const
3410{
3411 return mState.vertexAttribute[sw::PointSize].mArrayEnabled;
3412}
3413
3414void Context::setTextureCoordArrayEnabled(bool enable)
3415{
3416 mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;
3417}
3418
3419bool Context::isTextureCoordArrayEnabled() const
3420{
3421 return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;
3422}
3423
3424void Context::setMultisampleEnabled(bool enable)
3425{
3426 multisampleEnabled = enable;
3427}
3428
3429bool Context::isMultisampleEnabled() const
3430{
3431 return multisampleEnabled;
3432}
3433
3434void Context::setSampleAlphaToOneEnabled(bool enable)
3435{
3436 sampleAlphaToOneEnabled = enable;
3437}
3438
3439bool Context::isSampleAlphaToOneEnabled() const
3440{
3441 return sampleAlphaToOneEnabled;
3442}
3443
3444void Context::setPointSpriteEnabled(bool enable)
3445{
3446 pointSpriteEnabled = enable;
3447}
3448
3449bool Context::isPointSpriteEnabled() const
3450{
3451 return pointSpriteEnabled;
3452}
3453
3454void Context::setPointSmoothEnabled(bool enable)
3455{
3456 pointSmoothEnabled = enable;
3457}
3458
3459bool Context::isPointSmoothEnabled() const
3460{
3461 return pointSmoothEnabled;
3462}
3463
3464void Context::setPointSizeMin(float min)
3465{
3466 pointSizeMin = min;
3467}
3468
3469void Context::setPointSizeMax(float max)
3470{
3471 pointSizeMax = max;
3472}
3473
3474void Context::setPointDistanceAttenuation(float a, float b, float c)
3475{
3476 pointDistanceAttenuation = {a, b, c};
3477}
3478
3479void Context::setPointFadeThresholdSize(float threshold)
3480{
3481 pointFadeThresholdSize = threshold;
3482}
3483
3484void Context::clientActiveTexture(GLenum texture)
3485{
3486 clientTexture = texture;
3487}
3488
3489GLenum Context::getClientActiveTexture() const
3490{
3491 return clientTexture;
3492}
3493
3494unsigned int Context::getActiveTexture() const
3495{
3496 return mState.activeSampler;
3497}
3498
3499}
3500
Nicolas Capensf6a377b2017-05-19 09:31:35 -04003501egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
Nicolas Capens0bac2852016-05-07 06:09:58 -04003502{
3503 ASSERT(!shareContext || shareContext->getClientVersion() == 1); // Should be checked by eglCreateContext
Nicolas Capensf6a377b2017-05-19 09:31:35 -04003504 return new es1::Context(display, static_cast<const es1::Context*>(shareContext), config);
Nicolas Capens0bac2852016-05-07 06:09:58 -04003505}