1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
16 // rendering operations.
17
18 #include "Context.h"
19
20 #include "main.h"
21 #include "mathutil.h"
22 #include "utilities.h"
23 #include "ResourceManager.h"
24 #include "Buffer.h"
25 #include "Fence.h"
26 #include "Framebuffer.h"
27 #include "Program.h"
28 #include "Query.h"
29 #include "Renderbuffer.h"
30 #include "Shader.h"
31 #include "Texture.h"
32 #include "VertexDataManager.h"
33 #include "IndexDataManager.h"
34 #include "Display.h"
35 #include "Surface.h"
36 #include "Common/Half.hpp"
37
38 #define _GDI32_
39 #include <windows.h>
40 #include <GL/GL.h>
41 #include <GL/glext.h>
42
43 namespace gl
44 {
Context(const Context * shareContext)45 Context::Context(const Context *shareContext)
46 : modelView(32),
47 projection(2)
48 {
49 sw::Context *context = new sw::Context();
50 device = new gl::Device(context);
51
52 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
53
54 mState.depthClearValue = 1.0f;
55 mState.stencilClearValue = 0;
56
57 mState.cullFaceEnabled = false;
58 mState.cullMode = GL_BACK;
59 mState.frontFace = GL_CCW;
60 mState.depthTestEnabled = false;
61 mState.depthFunc = GL_LESS;
62 mState.blendEnabled = false;
63 mState.sourceBlendRGB = GL_ONE;
64 mState.sourceBlendAlpha = GL_ONE;
65 mState.destBlendRGB = GL_ZERO;
66 mState.destBlendAlpha = GL_ZERO;
67 mState.blendEquationRGB = GL_FUNC_ADD;
68 mState.blendEquationAlpha = GL_FUNC_ADD;
69 mState.blendColor.red = 0;
70 mState.blendColor.green = 0;
71 mState.blendColor.blue = 0;
72 mState.blendColor.alpha = 0;
73 mState.stencilTestEnabled = false;
74 mState.stencilFunc = GL_ALWAYS;
75 mState.stencilRef = 0;
76 mState.stencilMask = -1;
77 mState.stencilWritemask = -1;
78 mState.stencilBackFunc = GL_ALWAYS;
79 mState.stencilBackRef = 0;
80 mState.stencilBackMask = - 1;
81 mState.stencilBackWritemask = -1;
82 mState.stencilFail = GL_KEEP;
83 mState.stencilPassDepthFail = GL_KEEP;
84 mState.stencilPassDepthPass = GL_KEEP;
85 mState.stencilBackFail = GL_KEEP;
86 mState.stencilBackPassDepthFail = GL_KEEP;
87 mState.stencilBackPassDepthPass = GL_KEEP;
88 mState.polygonOffsetFillEnabled = false;
89 mState.polygonOffsetFactor = 0.0f;
90 mState.polygonOffsetUnits = 0.0f;
91 mState.sampleAlphaToCoverageEnabled = false;
92 mState.sampleCoverageEnabled = false;
93 mState.sampleCoverageValue = 1.0f;
94 mState.sampleCoverageInvert = false;
95 mState.scissorTestEnabled = false;
96 mState.ditherEnabled = true;
97 mState.generateMipmapHint = GL_DONT_CARE;
98 mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99 mState.colorLogicOpEnabled = false;
100 mState.logicalOperation = GL_COPY;
101
102 mState.lineWidth = 1.0f;
103
104 mState.viewportX = 0;
105 mState.viewportY = 0;
106 mState.viewportWidth = 0;
107 mState.viewportHeight = 0;
108 mState.zNear = 0.0f;
109 mState.zFar = 1.0f;
110
111 mState.scissorX = 0;
112 mState.scissorY = 0;
113 mState.scissorWidth = 0;
114 mState.scissorHeight = 0;
115
116 mState.colorMaskRed = true;
117 mState.colorMaskGreen = true;
118 mState.colorMaskBlue = true;
119 mState.colorMaskAlpha = true;
120 mState.depthMask = true;
121
122 if(shareContext)
123 {
124 mResourceManager = shareContext->mResourceManager;
125 mResourceManager->addRef();
126 }
127 else
128 {
129 mResourceManager = new ResourceManager();
130 }
131
132 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
133 // and cube map texture state vectors respectively associated with them.
134 // In order that access to these initial textures not be lost, they are treated as texture
135 // objects all of whose names are 0.
136
137 mTexture2DZero = new Texture2D(0);
138 mProxyTexture2DZero = new Texture2D(0);
139 mTextureCubeMapZero = new TextureCubeMap(0);
140
141 mState.activeSampler = 0;
142 bindArrayBuffer(0);
143 bindElementArrayBuffer(0);
144 bindTextureCubeMap(0);
145 bindTexture2D(0);
146 bindReadFramebuffer(0);
147 bindDrawFramebuffer(0);
148 bindRenderbuffer(0);
149
150 mState.currentProgram = 0;
151
152 mState.packAlignment = 4;
153 mState.unpackAlignment = 4;
154
155 mVertexDataManager = nullptr;
156 mIndexDataManager = nullptr;
157
158 mInvalidEnum = false;
159 mInvalidValue = false;
160 mInvalidOperation = false;
161 mOutOfMemory = false;
162 mInvalidFramebufferOperation = false;
163
164 mHasBeenCurrent = false;
165
166 markAllStateDirty();
167
168 matrixMode = GL_MODELVIEW;
169
170 listMode = 0;
171 //memset(displayList, 0, sizeof(displayList));
172 listIndex = 0;
173 list = 0;
174 firstFreeIndex = 1;
175
176 clientTexture = GL_TEXTURE0;
177
178 drawing = false;
179 drawMode = 0; // FIXME
180
181 mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f;
182 mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f;
183 mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f;
184 mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f;
185 mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f;
186 mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f;
187 mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f;
188 mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f;
189 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f;
190 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f;
191 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f;
192 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f;
193 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f;
194 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f;
195 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f;
196 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f;
197
198 for(int i = 0; i < 8; i++)
199 {
200 envEnable[i] = true;
201 }
202 }
203
~Context()204 Context::~Context()
205 {
206 if(mState.currentProgram != 0)
207 {
208 Program *programObject = mResourceManager->getProgram(mState.currentProgram);
209 if(programObject)
210 {
211 programObject->release();
212 }
213 mState.currentProgram = 0;
214 }
215
216 while(!mFramebufferNameSpace.empty())
217 {
218 deleteFramebuffer(mFramebufferNameSpace.firstName());
219 }
220
221 while(!mFenceNameSpace.empty())
222 {
223 deleteFence(mFenceNameSpace.firstName());
224 }
225
226 while(!mQueryNameSpace.empty())
227 {
228 deleteQuery(mQueryNameSpace.firstName());
229 }
230
231 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
232 {
233 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
234 {
235 mState.samplerTexture[type][sampler] = nullptr;
236 }
237 }
238
239 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
240 {
241 mState.vertexAttribute[i].mBoundBuffer = nullptr;
242 }
243
244 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
245 {
246 mState.activeQuery[i] = nullptr;
247 }
248
249 mState.arrayBuffer = nullptr;
250 mState.elementArrayBuffer = nullptr;
251 mState.renderbuffer = nullptr;
252
253 mTexture2DZero = nullptr;
254 mProxyTexture2DZero = nullptr;
255 mTextureCubeMapZero = nullptr;
256
257 delete mVertexDataManager;
258 delete mIndexDataManager;
259
260 mResourceManager->release();
261 delete device;
262 }
263
makeCurrent(Surface * surface)264 void Context::makeCurrent(Surface *surface)
265 {
266 if(!mHasBeenCurrent)
267 {
268 mVertexDataManager = new VertexDataManager(this);
269 mIndexDataManager = new IndexDataManager();
270
271 mState.viewportX = 0;
272 mState.viewportY = 0;
273 mState.viewportWidth = surface->getWidth();
274 mState.viewportHeight = surface->getHeight();
275
276 mState.scissorX = 0;
277 mState.scissorY = 0;
278 mState.scissorWidth = surface->getWidth();
279 mState.scissorHeight = surface->getHeight();
280
281 mHasBeenCurrent = true;
282 }
283
284 // Wrap the existing resources into GL objects and assign them to the '0' names
285 Image *defaultRenderTarget = surface->getRenderTarget();
286 Image *depthStencil = surface->getDepthStencil();
287
288 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
289 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
290 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
291
292 setFramebufferZero(framebufferZero);
293
294 if(defaultRenderTarget)
295 {
296 defaultRenderTarget->release();
297 }
298
299 if(depthStencil)
300 {
301 depthStencil->release();
302 }
303
304 markAllStateDirty();
305 }
306
307 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
markAllStateDirty()308 void Context::markAllStateDirty()
309 {
310 mAppliedProgramSerial = 0;
311
312 mDepthStateDirty = true;
313 mMaskStateDirty = true;
314 mBlendStateDirty = true;
315 mStencilStateDirty = true;
316 mPolygonOffsetStateDirty = true;
317 mSampleStateDirty = true;
318 mDitherStateDirty = true;
319 mFrontFaceDirty = true;
320 mColorLogicOperatorDirty = true;
321 }
322
setClearColor(float red,float green,float blue,float alpha)323 void Context::setClearColor(float red, float green, float blue, float alpha)
324 {
325 mState.colorClearValue.red = red;
326 mState.colorClearValue.green = green;
327 mState.colorClearValue.blue = blue;
328 mState.colorClearValue.alpha = alpha;
329 }
330
setClearDepth(float depth)331 void Context::setClearDepth(float depth)
332 {
333 mState.depthClearValue = depth;
334 }
335
setClearStencil(int stencil)336 void Context::setClearStencil(int stencil)
337 {
338 mState.stencilClearValue = stencil;
339 }
340
setCullFaceEnabled(bool enabled)341 void Context::setCullFaceEnabled(bool enabled)
342 {
343 mState.cullFaceEnabled = enabled;
344 }
345
isCullFaceEnabled() const346 bool Context::isCullFaceEnabled() const
347 {
348 return mState.cullFaceEnabled;
349 }
350
setCullMode(GLenum mode)351 void Context::setCullMode(GLenum mode)
352 {
353 mState.cullMode = mode;
354 }
355
setFrontFace(GLenum front)356 void Context::setFrontFace(GLenum front)
357 {
358 if(mState.frontFace != front)
359 {
360 mState.frontFace = front;
361 mFrontFaceDirty = true;
362 }
363 }
364
setDepthTestEnabled(bool enabled)365 void Context::setDepthTestEnabled(bool enabled)
366 {
367 if(mState.depthTestEnabled != enabled)
368 {
369 mState.depthTestEnabled = enabled;
370 mDepthStateDirty = true;
371 }
372 }
373
isDepthTestEnabled() const374 bool Context::isDepthTestEnabled() const
375 {
376 return mState.depthTestEnabled;
377 }
378
setDepthFunc(GLenum depthFunc)379 void Context::setDepthFunc(GLenum depthFunc)
380 {
381 if(mState.depthFunc != depthFunc)
382 {
383 mState.depthFunc = depthFunc;
384 mDepthStateDirty = true;
385 }
386 }
387
setDepthRange(float zNear,float zFar)388 void Context::setDepthRange(float zNear, float zFar)
389 {
390 mState.zNear = zNear;
391 mState.zFar = zFar;
392 }
393
setBlendEnabled(bool enabled)394 void Context::setBlendEnabled(bool enabled)
395 {
396 if(mState.blendEnabled != enabled)
397 {
398 mState.blendEnabled = enabled;
399 mBlendStateDirty = true;
400 }
401 }
402
isBlendEnabled() const403 bool Context::isBlendEnabled() const
404 {
405 return mState.blendEnabled;
406 }
407
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)408 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
409 {
410 if(mState.sourceBlendRGB != sourceRGB ||
411 mState.sourceBlendAlpha != sourceAlpha ||
412 mState.destBlendRGB != destRGB ||
413 mState.destBlendAlpha != destAlpha)
414 {
415 mState.sourceBlendRGB = sourceRGB;
416 mState.destBlendRGB = destRGB;
417 mState.sourceBlendAlpha = sourceAlpha;
418 mState.destBlendAlpha = destAlpha;
419 mBlendStateDirty = true;
420 }
421 }
422
setBlendColor(float red,float green,float blue,float alpha)423 void Context::setBlendColor(float red, float green, float blue, float alpha)
424 {
425 if(mState.blendColor.red != red ||
426 mState.blendColor.green != green ||
427 mState.blendColor.blue != blue ||
428 mState.blendColor.alpha != alpha)
429 {
430 mState.blendColor.red = red;
431 mState.blendColor.green = green;
432 mState.blendColor.blue = blue;
433 mState.blendColor.alpha = alpha;
434 mBlendStateDirty = true;
435 }
436 }
437
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)438 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
439 {
440 if(mState.blendEquationRGB != rgbEquation ||
441 mState.blendEquationAlpha != alphaEquation)
442 {
443 mState.blendEquationRGB = rgbEquation;
444 mState.blendEquationAlpha = alphaEquation;
445 mBlendStateDirty = true;
446 }
447 }
448
setStencilTestEnabled(bool enabled)449 void Context::setStencilTestEnabled(bool enabled)
450 {
451 if(mState.stencilTestEnabled != enabled)
452 {
453 mState.stencilTestEnabled = enabled;
454 mStencilStateDirty = true;
455 }
456 }
457
isStencilTestEnabled() const458 bool Context::isStencilTestEnabled() const
459 {
460 return mState.stencilTestEnabled;
461 }
462
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)463 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
464 {
465 if(mState.stencilFunc != stencilFunc ||
466 mState.stencilRef != stencilRef ||
467 mState.stencilMask != stencilMask)
468 {
469 mState.stencilFunc = stencilFunc;
470 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
471 mState.stencilMask = stencilMask;
472 mStencilStateDirty = true;
473 }
474 }
475
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)476 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
477 {
478 if(mState.stencilBackFunc != stencilBackFunc ||
479 mState.stencilBackRef != stencilBackRef ||
480 mState.stencilBackMask != stencilBackMask)
481 {
482 mState.stencilBackFunc = stencilBackFunc;
483 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
484 mState.stencilBackMask = stencilBackMask;
485 mStencilStateDirty = true;
486 }
487 }
488
setStencilWritemask(GLuint stencilWritemask)489 void Context::setStencilWritemask(GLuint stencilWritemask)
490 {
491 if(mState.stencilWritemask != stencilWritemask)
492 {
493 mState.stencilWritemask = stencilWritemask;
494 mStencilStateDirty = true;
495 }
496 }
497
setStencilBackWritemask(GLuint stencilBackWritemask)498 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
499 {
500 if(mState.stencilBackWritemask != stencilBackWritemask)
501 {
502 mState.stencilBackWritemask = stencilBackWritemask;
503 mStencilStateDirty = true;
504 }
505 }
506
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)507 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
508 {
509 if(mState.stencilFail != stencilFail ||
510 mState.stencilPassDepthFail != stencilPassDepthFail ||
511 mState.stencilPassDepthPass != stencilPassDepthPass)
512 {
513 mState.stencilFail = stencilFail;
514 mState.stencilPassDepthFail = stencilPassDepthFail;
515 mState.stencilPassDepthPass = stencilPassDepthPass;
516 mStencilStateDirty = true;
517 }
518 }
519
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)520 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
521 {
522 if(mState.stencilBackFail != stencilBackFail ||
523 mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
524 mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
525 {
526 mState.stencilBackFail = stencilBackFail;
527 mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
528 mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
529 mStencilStateDirty = true;
530 }
531 }
532
setPolygonOffsetFillEnabled(bool enabled)533 void Context::setPolygonOffsetFillEnabled(bool enabled)
534 {
535 if(mState.polygonOffsetFillEnabled != enabled)
536 {
537 mState.polygonOffsetFillEnabled = enabled;
538 mPolygonOffsetStateDirty = true;
539 }
540 }
541
isPolygonOffsetFillEnabled() const542 bool Context::isPolygonOffsetFillEnabled() const
543 {
544 return mState.polygonOffsetFillEnabled;
545 }
546
setPolygonOffsetParams(GLfloat factor,GLfloat units)547 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
548 {
549 if(mState.polygonOffsetFactor != factor ||
550 mState.polygonOffsetUnits != units)
551 {
552 mState.polygonOffsetFactor = factor;
553 mState.polygonOffsetUnits = units;
554 mPolygonOffsetStateDirty = true;
555 }
556 }
557
setSampleAlphaToCoverageEnabled(bool enabled)558 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
559 {
560 if(mState.sampleAlphaToCoverageEnabled != enabled)
561 {
562 mState.sampleAlphaToCoverageEnabled = enabled;
563 mSampleStateDirty = true;
564 }
565 }
566
isSampleAlphaToCoverageEnabled() const567 bool Context::isSampleAlphaToCoverageEnabled() const
568 {
569 return mState.sampleAlphaToCoverageEnabled;
570 }
571
setSampleCoverageEnabled(bool enabled)572 void Context::setSampleCoverageEnabled(bool enabled)
573 {
574 if(mState.sampleCoverageEnabled != enabled)
575 {
576 mState.sampleCoverageEnabled = enabled;
577 mSampleStateDirty = true;
578 }
579 }
580
isSampleCoverageEnabled() const581 bool Context::isSampleCoverageEnabled() const
582 {
583 return mState.sampleCoverageEnabled;
584 }
585
setSampleCoverageParams(GLclampf value,bool invert)586 void Context::setSampleCoverageParams(GLclampf value, bool invert)
587 {
588 if(mState.sampleCoverageValue != value ||
589 mState.sampleCoverageInvert != invert)
590 {
591 mState.sampleCoverageValue = value;
592 mState.sampleCoverageInvert = invert;
593 mSampleStateDirty = true;
594 }
595 }
596
setScissorTestEnabled(bool enabled)597 void Context::setScissorTestEnabled(bool enabled)
598 {
599 mState.scissorTestEnabled = enabled;
600 }
601
isScissorTestEnabled() const602 bool Context::isScissorTestEnabled() const
603 {
604 return mState.scissorTestEnabled;
605 }
606
setDitherEnabled(bool enabled)607 void Context::setDitherEnabled(bool enabled)
608 {
609 if(mState.ditherEnabled != enabled)
610 {
611 mState.ditherEnabled = enabled;
612 mDitherStateDirty = true;
613 }
614 }
615
isDitherEnabled() const616 bool Context::isDitherEnabled() const
617 {
618 return mState.ditherEnabled;
619 }
620
setLineWidth(GLfloat width)621 void Context::setLineWidth(GLfloat width)
622 {
623 mState.lineWidth = width;
624 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
625 }
626
setGenerateMipmapHint(GLenum hint)627 void Context::setGenerateMipmapHint(GLenum hint)
628 {
629 mState.generateMipmapHint = hint;
630 }
631
setFragmentShaderDerivativeHint(GLenum hint)632 void Context::setFragmentShaderDerivativeHint(GLenum hint)
633 {
634 mState.fragmentShaderDerivativeHint = hint;
635 // TODO: Propagate the hint to shader translator so we can write
636 // ddx, ddx_coarse, or ddx_fine depending on the hint.
637 // Ignore for now. It is valid for implementations to ignore hint.
638 }
639
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)640 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
641 {
642 mState.viewportX = x;
643 mState.viewportY = y;
644 mState.viewportWidth = width;
645 mState.viewportHeight = height;
646 }
647
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)648 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
649 {
650 mState.scissorX = x;
651 mState.scissorY = y;
652 mState.scissorWidth = width;
653 mState.scissorHeight = height;
654 }
655
setColorMask(bool red,bool green,bool blue,bool alpha)656 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
657 {
658 if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
659 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
660 {
661 mState.colorMaskRed = red;
662 mState.colorMaskGreen = green;
663 mState.colorMaskBlue = blue;
664 mState.colorMaskAlpha = alpha;
665 mMaskStateDirty = true;
666 }
667 }
668
setDepthMask(bool mask)669 void Context::setDepthMask(bool mask)
670 {
671 if(mState.depthMask != mask)
672 {
673 mState.depthMask = mask;
674 mMaskStateDirty = true;
675 }
676 }
677
setActiveSampler(unsigned int active)678 void Context::setActiveSampler(unsigned int active)
679 {
680 mState.activeSampler = active;
681 }
682
getReadFramebufferName() const683 GLuint Context::getReadFramebufferName() const
684 {
685 return mState.readFramebuffer;
686 }
687
getDrawFramebufferName() const688 GLuint Context::getDrawFramebufferName() const
689 {
690 return mState.drawFramebuffer;
691 }
692
getRenderbufferName() const693 GLuint Context::getRenderbufferName() const
694 {
695 return mState.renderbuffer.name();
696 }
697
getArrayBufferName() const698 GLuint Context::getArrayBufferName() const
699 {
700 return mState.arrayBuffer.name();
701 }
702
getActiveQuery(GLenum target) const703 GLuint Context::getActiveQuery(GLenum target) const
704 {
705 Query *queryObject = nullptr;
706
707 switch(target)
708 {
709 case GL_ANY_SAMPLES_PASSED:
710 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
711 break;
712 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
713 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
714 break;
715 default:
716 ASSERT(false);
717 }
718
719 if(queryObject)
720 {
721 return queryObject->name;
722 }
723
724 return 0;
725 }
726
setVertexAttribArrayEnabled(unsigned int attribNum,bool enabled)727 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
728 {
729 mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
730 }
731
getVertexAttribState(unsigned int attribNum)732 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
733 {
734 return mState.vertexAttribute[attribNum];
735 }
736
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,GLsizei stride,const void * pointer)737 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
738 GLsizei stride, const void *pointer)
739 {
740 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
741 mState.vertexAttribute[attribNum].mSize = size;
742 mState.vertexAttribute[attribNum].mType = type;
743 mState.vertexAttribute[attribNum].mNormalized = normalized;
744 mState.vertexAttribute[attribNum].mStride = stride;
745 mState.vertexAttribute[attribNum].mPointer = pointer;
746 }
747
getVertexAttribPointer(unsigned int attribNum) const748 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
749 {
750 return mState.vertexAttribute[attribNum].mPointer;
751 }
752
getVertexAttributes()753 const VertexAttributeArray &Context::getVertexAttributes()
754 {
755 return mState.vertexAttribute;
756 }
757
setPackAlignment(GLint alignment)758 void Context::setPackAlignment(GLint alignment)
759 {
760 mState.packAlignment = alignment;
761 }
762
getPackAlignment() const763 GLint Context::getPackAlignment() const
764 {
765 return mState.packAlignment;
766 }
767
setUnpackAlignment(GLint alignment)768 void Context::setUnpackAlignment(GLint alignment)
769 {
770 mState.unpackAlignment = alignment;
771 }
772
getUnpackAlignment() const773 GLint Context::getUnpackAlignment() const
774 {
775 return mState.unpackAlignment;
776 }
777
createBuffer()778 GLuint Context::createBuffer()
779 {
780 return mResourceManager->createBuffer();
781 }
782
createProgram()783 GLuint Context::createProgram()
784 {
785 return mResourceManager->createProgram();
786 }
787
createShader(GLenum type)788 GLuint Context::createShader(GLenum type)
789 {
790 return mResourceManager->createShader(type);
791 }
792
createTexture()793 GLuint Context::createTexture()
794 {
795 return mResourceManager->createTexture();
796 }
797
createRenderbuffer()798 GLuint Context::createRenderbuffer()
799 {
800 return mResourceManager->createRenderbuffer();
801 }
802
803 // Returns an unused framebuffer name
createFramebuffer()804 GLuint Context::createFramebuffer()
805 {
806 return mFramebufferNameSpace.allocate();
807 }
808
createFence()809 GLuint Context::createFence()
810 {
811 return mFenceNameSpace.allocate(new Fence());
812 }
813
814 // Returns an unused query name
createQuery()815 GLuint Context::createQuery()
816 {
817 return mQueryNameSpace.allocate();
818 }
819
deleteBuffer(GLuint buffer)820 void Context::deleteBuffer(GLuint buffer)
821 {
822 if(mResourceManager->getBuffer(buffer))
823 {
824 detachBuffer(buffer);
825 }
826
827 mResourceManager->deleteBuffer(buffer);
828 }
829
deleteShader(GLuint shader)830 void Context::deleteShader(GLuint shader)
831 {
832 mResourceManager->deleteShader(shader);
833 }
834
deleteProgram(GLuint program)835 void Context::deleteProgram(GLuint program)
836 {
837 mResourceManager->deleteProgram(program);
838 }
839
deleteTexture(GLuint texture)840 void Context::deleteTexture(GLuint texture)
841 {
842 if(mResourceManager->getTexture(texture))
843 {
844 detachTexture(texture);
845 }
846
847 mResourceManager->deleteTexture(texture);
848 }
849
deleteRenderbuffer(GLuint renderbuffer)850 void Context::deleteRenderbuffer(GLuint renderbuffer)
851 {
852 if(mResourceManager->getRenderbuffer(renderbuffer))
853 {
854 detachRenderbuffer(renderbuffer);
855 }
856
857 mResourceManager->deleteRenderbuffer(renderbuffer);
858 }
859
deleteFramebuffer(GLuint framebuffer)860 void Context::deleteFramebuffer(GLuint framebuffer)
861 {
862 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
863
864 if(framebufferObject)
865 {
866 detachFramebuffer(framebuffer);
867
868 delete framebufferObject;
869 }
870 }
871
deleteFence(GLuint fence)872 void Context::deleteFence(GLuint fence)
873 {
874 Fence *fenceObject = mFenceNameSpace.remove(fence);
875
876 if(fenceObject)
877 {
878 delete fenceObject;
879 }
880 }
881
deleteQuery(GLuint query)882 void Context::deleteQuery(GLuint query)
883 {
884 Query *queryObject = mQueryNameSpace.remove(query);
885
886 if(queryObject)
887 {
888 queryObject->release();
889 }
890 }
891
getBuffer(GLuint handle)892 Buffer *Context::getBuffer(GLuint handle)
893 {
894 return mResourceManager->getBuffer(handle);
895 }
896
getShader(GLuint handle)897 Shader *Context::getShader(GLuint handle)
898 {
899 return mResourceManager->getShader(handle);
900 }
901
getProgram(GLuint handle)902 Program *Context::getProgram(GLuint handle)
903 {
904 return mResourceManager->getProgram(handle);
905 }
906
getTexture(GLuint handle)907 Texture *Context::getTexture(GLuint handle)
908 {
909 return mResourceManager->getTexture(handle);
910 }
911
getRenderbuffer(GLuint handle)912 Renderbuffer *Context::getRenderbuffer(GLuint handle)
913 {
914 return mResourceManager->getRenderbuffer(handle);
915 }
916
getReadFramebuffer()917 Framebuffer *Context::getReadFramebuffer()
918 {
919 return getFramebuffer(mState.readFramebuffer);
920 }
921
getDrawFramebuffer()922 Framebuffer *Context::getDrawFramebuffer()
923 {
924 return getFramebuffer(mState.drawFramebuffer);
925 }
926
bindArrayBuffer(unsigned int buffer)927 void Context::bindArrayBuffer(unsigned int buffer)
928 {
929 mResourceManager->checkBufferAllocation(buffer);
930
931 mState.arrayBuffer = getBuffer(buffer);
932 }
933
bindElementArrayBuffer(unsigned int buffer)934 void Context::bindElementArrayBuffer(unsigned int buffer)
935 {
936 mResourceManager->checkBufferAllocation(buffer);
937
938 mState.elementArrayBuffer = getBuffer(buffer);
939 }
940
bindTexture2D(GLuint texture)941 void Context::bindTexture2D(GLuint texture)
942 {
943 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
944
945 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
946 }
947
bindTextureCubeMap(GLuint texture)948 void Context::bindTextureCubeMap(GLuint texture)
949 {
950 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
951
952 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
953 }
954
bindReadFramebuffer(GLuint framebuffer)955 void Context::bindReadFramebuffer(GLuint framebuffer)
956 {
957 if(!getFramebuffer(framebuffer))
958 {
959 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
960 }
961
962 mState.readFramebuffer = framebuffer;
963 }
964
bindDrawFramebuffer(GLuint framebuffer)965 void Context::bindDrawFramebuffer(GLuint framebuffer)
966 {
967 if(!getFramebuffer(framebuffer))
968 {
969 mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
970 }
971
972 mState.drawFramebuffer = framebuffer;
973 }
974
bindRenderbuffer(GLuint renderbuffer)975 void Context::bindRenderbuffer(GLuint renderbuffer)
976 {
977 mResourceManager->checkRenderbufferAllocation(renderbuffer);
978
979 mState.renderbuffer = getRenderbuffer(renderbuffer);
980 }
981
useProgram(GLuint program)982 void Context::useProgram(GLuint program)
983 {
984 GLuint priorProgram = mState.currentProgram;
985 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
986
987 if(priorProgram != program)
988 {
989 Program *newProgram = mResourceManager->getProgram(program);
990 Program *oldProgram = mResourceManager->getProgram(priorProgram);
991
992 if(newProgram)
993 {
994 newProgram->addRef();
995 }
996
997 if(oldProgram)
998 {
999 oldProgram->release();
1000 }
1001 }
1002 }
1003
beginQuery(GLenum target,GLuint query)1004 void Context::beginQuery(GLenum target, GLuint query)
1005 {
1006 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1007 // of zero, if the active query object name for <target> is non-zero (for the
1008 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1009 // the active query for either target is non-zero), if <id> is the name of an
1010 // existing query object whose type does not match <target>, or if <id> is the
1011 // active query object name for any query type, the error INVALID_OPERATION is
1012 // generated.
1013
1014 // Ensure no other queries are active
1015 // NOTE: If other queries than occlusion are supported, we will need to check
1016 // separately that:
1017 // a) The query ID passed is not the current active query for any target/type
1018 // b) There are no active queries for the requested target (and in the case
1019 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1020 // no query may be active for either if glBeginQuery targets either.
1021 for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1022 {
1023 if(mState.activeQuery[i])
1024 {
1025 return error(GL_INVALID_OPERATION);
1026 }
1027 }
1028
1029 QueryType qType;
1030 switch(target)
1031 {
1032 case GL_ANY_SAMPLES_PASSED:
1033 qType = QUERY_ANY_SAMPLES_PASSED;
1034 break;
1035 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1036 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1037 break;
1038 default:
1039 ASSERT(false);
1040 }
1041
1042 Query *queryObject = getQuery(query, true, target);
1043
1044 // Check that name was obtained with glGenQueries
1045 if(!queryObject)
1046 {
1047 return error(GL_INVALID_OPERATION);
1048 }
1049
1050 // Check for type mismatch
1051 if(queryObject->getType() != target)
1052 {
1053 return error(GL_INVALID_OPERATION);
1054 }
1055
1056 // Set query as active for specified target
1057 mState.activeQuery[qType] = queryObject;
1058
1059 // Begin query
1060 queryObject->begin();
1061 }
1062
endQuery(GLenum target)1063 void Context::endQuery(GLenum target)
1064 {
1065 QueryType qType;
1066
1067 switch(target)
1068 {
1069 case GL_ANY_SAMPLES_PASSED:
1070 qType = QUERY_ANY_SAMPLES_PASSED;
1071 break;
1072 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
1073 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1074 break;
1075 default:
1076 ASSERT(false);
1077 }
1078
1079 Query *queryObject = mState.activeQuery[qType];
1080
1081 if(!queryObject)
1082 {
1083 return error(GL_INVALID_OPERATION);
1084 }
1085
1086 queryObject->end();
1087
1088 mState.activeQuery[qType] = nullptr;
1089 }
1090
setFramebufferZero(Framebuffer * buffer)1091 void Context::setFramebufferZero(Framebuffer *buffer)
1092 {
1093 delete mFramebufferNameSpace.remove(0);
1094 mFramebufferNameSpace.insert(0, buffer);
1095 }
1096
setRenderbufferStorage(RenderbufferStorage * renderbuffer)1097 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1098 {
1099 Renderbuffer *renderbufferObject = mState.renderbuffer;
1100 renderbufferObject->setStorage(renderbuffer);
1101 }
1102
getFramebuffer(unsigned int handle)1103 Framebuffer *Context::getFramebuffer(unsigned int handle)
1104 {
1105 return mFramebufferNameSpace.find(handle);
1106 }
1107
getFence(unsigned int handle)1108 Fence *Context::getFence(unsigned int handle)
1109 {
1110 return mFenceNameSpace.find(handle);
1111 }
1112
getQuery(unsigned int handle,bool create,GLenum type)1113 Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1114 {
1115 if(!mQueryNameSpace.isReserved(handle))
1116 {
1117 return nullptr;
1118 }
1119 else
1120 {
1121 Query *query = mQueryNameSpace.find(handle);
1122 if(!query && create)
1123 {
1124 query = new Query(handle, type);
1125 query->addRef();
1126 mQueryNameSpace.insert(handle, query);
1127 }
1128
1129 return query;
1130 }
1131 }
1132
getArrayBuffer()1133 Buffer *Context::getArrayBuffer()
1134 {
1135 return mState.arrayBuffer;
1136 }
1137
getElementArrayBuffer()1138 Buffer *Context::getElementArrayBuffer()
1139 {
1140 return mState.elementArrayBuffer;
1141 }
1142
getCurrentProgram()1143 Program *Context::getCurrentProgram()
1144 {
1145 return mResourceManager->getProgram(mState.currentProgram);
1146 }
1147
getTexture2D(GLenum target)1148 Texture2D *Context::getTexture2D(GLenum target)
1149 {
1150 if(target == GL_TEXTURE_2D)
1151 {
1152 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1153 }
1154 else if(target == GL_PROXY_TEXTURE_2D)
1155 {
1156 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D));
1157 }
1158 else UNREACHABLE(target);
1159
1160 return nullptr;
1161 }
1162
getTextureCubeMap()1163 TextureCubeMap *Context::getTextureCubeMap()
1164 {
1165 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1166 }
1167
getSamplerTexture(unsigned int sampler,TextureType type)1168 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1169 {
1170 GLuint texid = mState.samplerTexture[type][sampler].name();
1171
1172 if(texid == 0) // Special case: 0 refers to different initial textures based on the target
1173 {
1174 switch(type)
1175 {
1176 case TEXTURE_2D: return mTexture2DZero;
1177 case PROXY_TEXTURE_2D: return mProxyTexture2DZero;
1178 case TEXTURE_CUBE: return mTextureCubeMapZero;
1179 default: UNREACHABLE(type);
1180 }
1181 }
1182
1183 return mState.samplerTexture[type][sampler];
1184 }
1185
getBooleanv(GLenum pname,GLboolean * params)1186 bool Context::getBooleanv(GLenum pname, GLboolean *params)
1187 {
1188 switch(pname)
1189 {
1190 case GL_SHADER_COMPILER: *params = GL_TRUE; break;
1191 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
1192 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
1193 case GL_COLOR_WRITEMASK:
1194 params[0] = mState.colorMaskRed;
1195 params[1] = mState.colorMaskGreen;
1196 params[2] = mState.colorMaskBlue;
1197 params[3] = mState.colorMaskAlpha;
1198 break;
1199 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break;
1200 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break;
1201 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
1202 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break;
1203 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break;
1204 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break;
1205 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break;
1206 case GL_BLEND: *params = mState.blendEnabled; break;
1207 case GL_DITHER: *params = mState.ditherEnabled; break;
1208 default:
1209 return false;
1210 }
1211
1212 return true;
1213 }
1214
getFloatv(GLenum pname,GLfloat * params)1215 bool Context::getFloatv(GLenum pname, GLfloat *params)
1216 {
1217 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1218 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1219 // GetIntegerv as its native query function. As it would require conversion in any
1220 // case, this should make no difference to the calling application.
1221 switch(pname)
1222 {
1223 case GL_LINE_WIDTH: *params = mState.lineWidth; break;
1224 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
1225 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
1226 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
1227 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
1228 case GL_ALIASED_LINE_WIDTH_RANGE:
1229 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1230 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1231 break;
1232 case GL_ALIASED_POINT_SIZE_RANGE:
1233 params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1234 params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1235 break;
1236 case GL_DEPTH_RANGE:
1237 params[0] = mState.zNear;
1238 params[1] = mState.zFar;
1239 break;
1240 case GL_COLOR_CLEAR_VALUE:
1241 params[0] = mState.colorClearValue.red;
1242 params[1] = mState.colorClearValue.green;
1243 params[2] = mState.colorClearValue.blue;
1244 params[3] = mState.colorClearValue.alpha;
1245 break;
1246 case GL_BLEND_COLOR:
1247 params[0] = mState.blendColor.red;
1248 params[1] = mState.blendColor.green;
1249 params[2] = mState.blendColor.blue;
1250 params[3] = mState.blendColor.alpha;
1251 break;
1252 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1253 *params = MAX_TEXTURE_MAX_ANISOTROPY;
1254 break;
1255 case GL_MODELVIEW_MATRIX:
1256 for(int i = 0; i < 16; i++)
1257 {
1258 params[i] = modelView.current()[i % 4][i / 4];
1259 }
1260 break;
1261 case GL_PROJECTION_MATRIX:
1262 for(int i = 0; i < 16; i++)
1263 {
1264 params[i] = projection.current()[i % 4][i / 4];
1265 }
1266 break;
1267 default:
1268 return false;
1269 }
1270
1271 return true;
1272 }
1273
getIntegerv(GLenum pname,GLint * params)1274 bool Context::getIntegerv(GLenum pname, GLint *params)
1275 {
1276 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1277 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1278 // GetIntegerv as its native query function. As it would require conversion in any
1279 // case, this should make no difference to the calling application. You may find it in
1280 // Context::getFloatv.
1281 switch(pname)
1282 {
1283 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break;
1284 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break;
1285 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = MAX_VERTEX_UNIFORM_VECTORS * 4; break; // FIXME: Verify
1286 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break;
1287 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
1288 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break;
1289 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break;
1290 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break;
1291 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = MAX_VERTEX_UNIFORM_VECTORS * 4; break; // FIXME: Verify
1292 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
1293 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
1294 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
1295 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break;
1296 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break;
1297 // case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1298 case GL_DRAW_FRAMEBUFFER_BINDING: *params = mState.drawFramebuffer; break;
1299 case GL_READ_FRAMEBUFFER_BINDING: *params = mState.readFramebuffer; break;
1300 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break;
1301 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
1302 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
1303 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
1304 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
1305 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: *params = mState.fragmentShaderDerivativeHint; break;
1306 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
1307 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break;
1308 case GL_STENCIL_REF: *params = mState.stencilRef; break;
1309 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break;
1310 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break;
1311 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
1312 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break;
1313 case GL_STENCIL_FAIL: *params = mState.stencilFail; break;
1314 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break;
1315 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break;
1316 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break;
1317 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break;
1318 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break;
1319 case GL_DEPTH_FUNC: *params = mState.depthFunc; break;
1320 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break;
1321 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break;
1322 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break;
1323 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break;
1324 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break;
1325 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break;
1326 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break;
1327 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break;
1328 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
1329 case GL_SUBPIXEL_BITS: *params = 4; break;
1330 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break;
1331 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
1332 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = 0; break;
1333 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break;
1334 case GL_MAX_SAMPLES: *params = IMPLEMENTATION_MAX_SAMPLES; break;
1335 case GL_SAMPLE_BUFFERS:
1336 case GL_SAMPLES:
1337 {
1338 Framebuffer *framebuffer = getDrawFramebuffer();
1339 int width, height, samples;
1340
1341 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1342 {
1343 switch(pname)
1344 {
1345 case GL_SAMPLE_BUFFERS:
1346 if(samples > 1)
1347 {
1348 *params = 1;
1349 }
1350 else
1351 {
1352 *params = 0;
1353 }
1354 break;
1355 case GL_SAMPLES:
1356 *params = samples;
1357 break;
1358 }
1359 }
1360 else
1361 {
1362 *params = 0;
1363 }
1364 }
1365 break;
1366 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = IMPLEMENTATION_COLOR_READ_TYPE; break;
1367 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
1368 case GL_MAX_VIEWPORT_DIMS:
1369 {
1370 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1371 params[0] = maxDimension;
1372 params[1] = maxDimension;
1373 }
1374 break;
1375 case GL_COMPRESSED_TEXTURE_FORMATS:
1376 {
1377 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1378 {
1379 params[i] = compressedTextureFormats[i];
1380 }
1381 }
1382 break;
1383 case GL_VIEWPORT:
1384 params[0] = mState.viewportX;
1385 params[1] = mState.viewportY;
1386 params[2] = mState.viewportWidth;
1387 params[3] = mState.viewportHeight;
1388 break;
1389 case GL_SCISSOR_BOX:
1390 params[0] = mState.scissorX;
1391 params[1] = mState.scissorY;
1392 params[2] = mState.scissorWidth;
1393 params[3] = mState.scissorHeight;
1394 break;
1395 case GL_CULL_FACE_MODE: *params = mState.cullMode; break;
1396 case GL_FRONT_FACE: *params = mState.frontFace; break;
1397 case GL_RED_BITS:
1398 case GL_GREEN_BITS:
1399 case GL_BLUE_BITS:
1400 case GL_ALPHA_BITS:
1401 {
1402 Framebuffer *framebuffer = getDrawFramebuffer();
1403 Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1404
1405 if(colorbuffer)
1406 {
1407 switch(pname)
1408 {
1409 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1410 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1411 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1412 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1413 }
1414 }
1415 else
1416 {
1417 *params = 0;
1418 }
1419 }
1420 break;
1421 case GL_DEPTH_BITS:
1422 {
1423 Framebuffer *framebuffer = getDrawFramebuffer();
1424 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1425
1426 if(depthbuffer)
1427 {
1428 *params = depthbuffer->getDepthSize();
1429 }
1430 else
1431 {
1432 *params = 0;
1433 }
1434 }
1435 break;
1436 case GL_STENCIL_BITS:
1437 {
1438 Framebuffer *framebuffer = getDrawFramebuffer();
1439 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1440
1441 if(stencilbuffer)
1442 {
1443 *params = stencilbuffer->getStencilSize();
1444 }
1445 else
1446 {
1447 *params = 0;
1448 }
1449 }
1450 break;
1451 case GL_TEXTURE_BINDING_2D:
1452 {
1453 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1454 {
1455 error(GL_INVALID_OPERATION);
1456 return false;
1457 }
1458
1459 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
1460 }
1461 break;
1462 case GL_TEXTURE_BINDING_CUBE_MAP:
1463 {
1464 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1465 {
1466 error(GL_INVALID_OPERATION);
1467 return false;
1468 }
1469
1470 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
1471 }
1472 break;
1473 default:
1474 return false;
1475 }
1476
1477 return true;
1478 }
1479
getQueryParameterInfo(GLenum pname,GLenum * type,unsigned int * numParams)1480 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1481 {
1482 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1483 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1484 // to the fact that it is stored internally as a float, and so would require conversion
1485 // if returned from Context::getIntegerv. Since this conversion is already implemented
1486 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1487 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1488 // application.
1489 switch(pname)
1490 {
1491 case GL_COMPRESSED_TEXTURE_FORMATS:
1492 {
1493 *type = GL_INT;
1494 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
1495 }
1496 break;
1497 case GL_SHADER_BINARY_FORMATS:
1498 {
1499 *type = GL_INT;
1500 *numParams = 0;
1501 }
1502 break;
1503 case GL_MAX_VERTEX_ATTRIBS:
1504 case GL_MAX_VERTEX_UNIFORM_VECTORS:
1505 case GL_MAX_VARYING_VECTORS:
1506 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1507 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1508 case GL_MAX_TEXTURE_IMAGE_UNITS:
1509 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1510 case GL_MAX_RENDERBUFFER_SIZE:
1511 case GL_NUM_SHADER_BINARY_FORMATS:
1512 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1513 case GL_ARRAY_BUFFER_BINDING:
1514 case GL_FRAMEBUFFER_BINDING:
1515 case GL_RENDERBUFFER_BINDING:
1516 case GL_CURRENT_PROGRAM:
1517 case GL_PACK_ALIGNMENT:
1518 case GL_UNPACK_ALIGNMENT:
1519 case GL_GENERATE_MIPMAP_HINT:
1520 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
1521 case GL_RED_BITS:
1522 case GL_GREEN_BITS:
1523 case GL_BLUE_BITS:
1524 case GL_ALPHA_BITS:
1525 case GL_DEPTH_BITS:
1526 case GL_STENCIL_BITS:
1527 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1528 case GL_CULL_FACE_MODE:
1529 case GL_FRONT_FACE:
1530 case GL_ACTIVE_TEXTURE:
1531 case GL_STENCIL_FUNC:
1532 case GL_STENCIL_VALUE_MASK:
1533 case GL_STENCIL_REF:
1534 case GL_STENCIL_FAIL:
1535 case GL_STENCIL_PASS_DEPTH_FAIL:
1536 case GL_STENCIL_PASS_DEPTH_PASS:
1537 case GL_STENCIL_BACK_FUNC:
1538 case GL_STENCIL_BACK_VALUE_MASK:
1539 case GL_STENCIL_BACK_REF:
1540 case GL_STENCIL_BACK_FAIL:
1541 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1542 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1543 case GL_DEPTH_FUNC:
1544 case GL_BLEND_SRC_RGB:
1545 case GL_BLEND_SRC_ALPHA:
1546 case GL_BLEND_DST_RGB:
1547 case GL_BLEND_DST_ALPHA:
1548 case GL_BLEND_EQUATION_RGB:
1549 case GL_BLEND_EQUATION_ALPHA:
1550 case GL_STENCIL_WRITEMASK:
1551 case GL_STENCIL_BACK_WRITEMASK:
1552 case GL_STENCIL_CLEAR_VALUE:
1553 case GL_SUBPIXEL_BITS:
1554 case GL_MAX_TEXTURE_SIZE:
1555 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1556 case GL_SAMPLE_BUFFERS:
1557 case GL_SAMPLES:
1558 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1559 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1560 case GL_TEXTURE_BINDING_2D:
1561 case GL_TEXTURE_BINDING_CUBE_MAP:
1562 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1563 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1564 case GL_MAX_ARRAY_TEXTURE_LAYERS:
1565 {
1566 *type = GL_INT;
1567 *numParams = 1;
1568 }
1569 break;
1570 case GL_MAX_SAMPLES:
1571 {
1572 *type = GL_INT;
1573 *numParams = 1;
1574 }
1575 break;
1576 case GL_MAX_VIEWPORT_DIMS:
1577 {
1578 *type = GL_INT;
1579 *numParams = 2;
1580 }
1581 break;
1582 case GL_VIEWPORT:
1583 case GL_SCISSOR_BOX:
1584 {
1585 *type = GL_INT;
1586 *numParams = 4;
1587 }
1588 break;
1589 case GL_SHADER_COMPILER:
1590 case GL_SAMPLE_COVERAGE_INVERT:
1591 case GL_DEPTH_WRITEMASK:
1592 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
1593 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
1594 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1595 case GL_SAMPLE_COVERAGE:
1596 case GL_SCISSOR_TEST:
1597 case GL_STENCIL_TEST:
1598 case GL_DEPTH_TEST:
1599 case GL_BLEND:
1600 case GL_DITHER:
1601 {
1602 *type = GL_BOOL;
1603 *numParams = 1;
1604 }
1605 break;
1606 case GL_COLOR_WRITEMASK:
1607 {
1608 *type = GL_BOOL;
1609 *numParams = 4;
1610 }
1611 break;
1612 case GL_POLYGON_OFFSET_FACTOR:
1613 case GL_POLYGON_OFFSET_UNITS:
1614 case GL_SAMPLE_COVERAGE_VALUE:
1615 case GL_DEPTH_CLEAR_VALUE:
1616 case GL_LINE_WIDTH:
1617 {
1618 *type = GL_FLOAT;
1619 *numParams = 1;
1620 }
1621 break;
1622 case GL_ALIASED_LINE_WIDTH_RANGE:
1623 case GL_ALIASED_POINT_SIZE_RANGE:
1624 case GL_DEPTH_RANGE:
1625 {
1626 *type = GL_FLOAT;
1627 *numParams = 2;
1628 }
1629 break;
1630 case GL_COLOR_CLEAR_VALUE:
1631 case GL_BLEND_COLOR:
1632 {
1633 *type = GL_FLOAT;
1634 *numParams = 4;
1635 }
1636 break;
1637 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1638 *type = GL_FLOAT;
1639 *numParams = 1;
1640 break;
1641 default:
1642 return false;
1643 }
1644
1645 return true;
1646 }
1647
1648 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
applyRenderTarget()1649 bool Context::applyRenderTarget()
1650 {
1651 Framebuffer *framebuffer = getDrawFramebuffer();
1652 int width, height, samples;
1653
1654 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
1655 {
1656 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1657 }
1658
1659 Image *renderTarget = framebuffer->getRenderTarget();
1660 device->setRenderTarget(0, renderTarget);
1661 if(renderTarget) renderTarget->release();
1662
1663 Image *depthStencil = framebuffer->getDepthStencil();
1664 device->setDepthStencilSurface(depthStencil);
1665 if(depthStencil) depthStencil->release();
1666
1667 Viewport viewport;
1668 float zNear = clamp01(mState.zNear);
1669 float zFar = clamp01(mState.zFar);
1670
1671 viewport.x0 = mState.viewportX;
1672 viewport.y0 = mState.viewportY;
1673 viewport.width = mState.viewportWidth;
1674 viewport.height = mState.viewportHeight;
1675 viewport.minZ = zNear;
1676 viewport.maxZ = zFar;
1677
1678 device->setViewport(viewport);
1679
1680 if(mState.scissorTestEnabled)
1681 {
1682 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1683 scissor.clip(0, 0, width, height);
1684
1685 device->setScissorRect(scissor);
1686 device->setScissorEnable(true);
1687 }
1688 else
1689 {
1690 device->setScissorEnable(false);
1691 }
1692
1693 Program *program = getCurrentProgram();
1694
1695 if(program)
1696 {
1697 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
1698 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
1699 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
1700 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
1701 }
1702
1703 return true;
1704 }
1705
1706 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
applyState(GLenum drawMode)1707 void Context::applyState(GLenum drawMode)
1708 {
1709 Framebuffer *framebuffer = getDrawFramebuffer();
1710
1711 if(mState.cullFaceEnabled)
1712 {
1713 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1714 }
1715 else
1716 {
1717 device->setCullMode(sw::CULL_NONE);
1718 }
1719
1720 if(mDepthStateDirty)
1721 {
1722 if(mState.depthTestEnabled)
1723 {
1724 device->setDepthBufferEnable(true);
1725 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1726 }
1727 else
1728 {
1729 device->setDepthBufferEnable(false);
1730 }
1731
1732 mDepthStateDirty = false;
1733 }
1734
1735 if(mBlendStateDirty)
1736 {
1737 if(mState.blendEnabled)
1738 {
1739 device->setAlphaBlendEnable(true);
1740 device->setSeparateAlphaBlendEnable(true);
1741
1742 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
1743
1744 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1745 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1746 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1747
1748 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1749 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1750 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1751 }
1752 else
1753 {
1754 device->setAlphaBlendEnable(false);
1755 }
1756
1757 mBlendStateDirty = false;
1758 }
1759
1760 if(mColorLogicOperatorDirty)
1761 {
1762 if(mState.colorLogicOpEnabled)
1763 {
1764 device->setColorLogicOpEnabled(true);
1765 device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation));
1766 }
1767 else
1768 {
1769 device->setColorLogicOpEnabled(false);
1770 }
1771
1772 mColorLogicOperatorDirty = false;
1773 }
1774
1775 if(mStencilStateDirty || mFrontFaceDirty)
1776 {
1777 if(mState.stencilTestEnabled && framebuffer->hasStencil())
1778 {
1779 device->setStencilEnable(true);
1780 device->setTwoSidedStencil(true);
1781
1782 if(mState.stencilWritemask != mState.stencilBackWritemask ||
1783 mState.stencilRef != mState.stencilBackRef ||
1784 mState.stencilMask != mState.stencilBackMask)
1785 {
1786 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
1787 return error(GL_INVALID_OPERATION);
1788 }
1789
1790 // get the maximum size of the stencil ref
1791 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1792 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1793
1794 if(mState.frontFace == GL_CCW)
1795 {
1796 device->setStencilWriteMask(mState.stencilWritemask);
1797 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1798
1799 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1800 device->setStencilMask(mState.stencilMask);
1801
1802 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1803 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1804 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1805
1806 device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
1807 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1808
1809 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1810 device->setStencilMaskCCW(mState.stencilBackMask);
1811
1812 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
1813 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1814 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1815 }
1816 else
1817 {
1818 device->setStencilWriteMaskCCW(mState.stencilWritemask);
1819 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1820
1821 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1822 device->setStencilMaskCCW(mState.stencilMask);
1823
1824 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1825 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1826 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1827
1828 device->setStencilWriteMask(mState.stencilBackWritemask);
1829 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1830
1831 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1832 device->setStencilMask(mState.stencilBackMask);
1833
1834 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
1835 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1836 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1837 }
1838 }
1839 else
1840 {
1841 device->setStencilEnable(false);
1842 }
1843
1844 mStencilStateDirty = false;
1845 mFrontFaceDirty = false;
1846 }
1847
1848 if(mMaskStateDirty)
1849 {
1850 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1851 device->setDepthWriteEnable(mState.depthMask);
1852
1853 mMaskStateDirty = false;
1854 }
1855
1856 if(mPolygonOffsetStateDirty)
1857 {
1858 if(mState.polygonOffsetFillEnabled)
1859 {
1860 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1861 if(depthbuffer)
1862 {
1863 device->setSlopeDepthBias(mState.polygonOffsetFactor);
1864 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1865 device->setDepthBias(depthBias);
1866 }
1867 }
1868 else
1869 {
1870 device->setSlopeDepthBias(0);
1871 device->setDepthBias(0);
1872 }
1873
1874 mPolygonOffsetStateDirty = false;
1875 }
1876
1877 if(mSampleStateDirty)
1878 {
1879 if(mState.sampleAlphaToCoverageEnabled)
1880 {
1881 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1882 }
1883 else
1884 {
1885 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1886 }
1887
1888 if(mState.sampleCoverageEnabled)
1889 {
1890 unsigned int mask = 0;
1891 if(mState.sampleCoverageValue != 0)
1892 {
1893 int width, height, samples;
1894 framebuffer->completeness(width, height, samples);
1895
1896 float threshold = 0.5f;
1897
1898 for(int i = 0; i < samples; i++)
1899 {
1900 mask <<= 1;
1901
1902 if((i + 1) * mState.sampleCoverageValue >= threshold)
1903 {
1904 threshold += 1.0f;
1905 mask |= 1;
1906 }
1907 }
1908 }
1909
1910 if(mState.sampleCoverageInvert)
1911 {
1912 mask = ~mask;
1913 }
1914
1915 device->setMultiSampleMask(mask);
1916 }
1917 else
1918 {
1919 device->setMultiSampleMask(0xFFFFFFFF);
1920 }
1921
1922 mSampleStateDirty = false;
1923 }
1924
1925 if(mDitherStateDirty)
1926 {
1927 // UNIMPLEMENTED(); // FIXME
1928
1929 mDitherStateDirty = false;
1930 }
1931 }
1932
applyVertexBuffer(GLint base,GLint first,GLsizei count)1933 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1934 {
1935 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1936
1937 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
1938 if(err != GL_NO_ERROR)
1939 {
1940 return err;
1941 }
1942
1943 Program *program = getCurrentProgram();
1944
1945 device->resetInputStreams(false);
1946
1947 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
1948 {
1949 if(program && program->getAttributeStream(i) == -1)
1950 {
1951 continue;
1952 }
1953
1954 sw::Resource *resource = attributes[i].vertexBuffer;
1955 const void *buffer = (char*)resource->data() + attributes[i].offset;
1956
1957 int stride = attributes[i].stride;
1958
1959 buffer = (char*)buffer + stride * base;
1960
1961 sw::Stream attribute(resource, buffer, stride);
1962
1963 attribute.type = attributes[i].type;
1964 attribute.count = attributes[i].count;
1965 attribute.normalized = attributes[i].normalized;
1966
1967 int stream = program ? program->getAttributeStream(i) : i;
1968 device->setInputStream(stream, attribute);
1969 }
1970
1971 return GL_NO_ERROR;
1972 }
1973
1974 // Applies the indices and element array bindings
applyIndexBuffer(const void * indices,GLsizei count,GLenum mode,GLenum type,TranslatedIndexData * indexInfo)1975 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
1976 {
1977 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
1978
1979 if(err == GL_NO_ERROR)
1980 {
1981 device->setIndexBuffer(indexInfo->indexBuffer);
1982 }
1983
1984 return err;
1985 }
1986
1987 // Applies the shaders and shader constants
applyShaders()1988 void Context::applyShaders()
1989 {
1990 Program *programObject = getCurrentProgram();
1991 if(!programObject)
1992 {
1993 device->setVertexShader(0);
1994 device->setPixelShader(0);
1995 return;
1996 }
1997 sw::VertexShader *vertexShader = programObject->getVertexShader();
1998 sw::PixelShader *pixelShader = programObject->getPixelShader();
1999
2000 device->setVertexShader(vertexShader);
2001 device->setPixelShader(pixelShader);
2002
2003 if(programObject->getSerial() != mAppliedProgramSerial)
2004 {
2005 programObject->dirtyAllUniforms();
2006 mAppliedProgramSerial = programObject->getSerial();
2007 }
2008
2009 programObject->applyUniforms();
2010 }
2011
applyTextures()2012 void Context::applyTextures()
2013 {
2014 applyTextures(sw::SAMPLER_PIXEL);
2015 //applyTextures(sw::SAMPLER_VERTEX);
2016 }
2017
applyTextures(sw::SamplerType samplerType)2018 void Context::applyTextures(sw::SamplerType samplerType)
2019 {
2020 Program *programObject = getCurrentProgram();
2021
2022 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type
2023
2024 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
2025 {
2026 int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex; // OpenGL texture image unit index
2027
2028 if(textureUnit != -1)
2029 {
2030 TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D;
2031
2032 Texture *texture = getSamplerTexture(textureUnit, textureType);
2033
2034 if(envEnable[samplerIndex] && texture->isSamplerComplete())
2035 {
2036 GLenum wrapS = texture->getWrapS();
2037 GLenum wrapT = texture->getWrapT();
2038 GLenum minFilter = texture->getMinFilter();
2039 GLenum magFilter = texture->getMagFilter();
2040 GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2041
2042 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
2043 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
2044
2045 device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
2046 device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
2047 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
2048
2049 applyTexture(samplerType, samplerIndex, texture);
2050
2051 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2052 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2053 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2054 //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2055
2056 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE);
2057 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE);
2058 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2059 //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2060
2061 //device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f));
2062 }
2063 else
2064 {
2065 applyTexture(samplerType, samplerIndex, nullptr);
2066
2067 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2068 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2069 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2070 //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2071
2072 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1);
2073 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2074 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT);
2075 //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT);
2076 }
2077 }
2078 else
2079 {
2080 applyTexture(samplerType, samplerIndex, nullptr);
2081 }
2082 }
2083 }
2084
applyTexture(sw::SamplerType type,int index,Texture * baseTexture)2085 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
2086 {
2087 Program *program = getCurrentProgram();
2088 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
2089 bool textureUsed = false;
2090
2091 if(type == sw::SAMPLER_PIXEL)
2092 {
2093 textureUsed = program ? program->getPixelShader()->usesSampler(index) : true;
2094 }
2095 else if(type == sw::SAMPLER_VERTEX)
2096 {
2097 textureUsed = program ? program->getVertexShader()->usesSampler(index) : false;
2098 }
2099 else UNREACHABLE(type);
2100
2101 sw::Resource *resource = nullptr;
2102
2103 if(baseTexture && textureUsed)
2104 {
2105 resource = baseTexture->getResource();
2106 }
2107
2108 device->setTextureResource(sampler, resource);
2109
2110 if(baseTexture && textureUsed)
2111 {
2112 int levelCount = baseTexture->getLevelCount();
2113
2114 if(baseTexture->getTarget() == GL_TEXTURE_2D)
2115 {
2116 Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2117
2118 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2119 {
2120 int surfaceLevel = mipmapLevel;
2121
2122 if(surfaceLevel < 0)
2123 {
2124 surfaceLevel = 0;
2125 }
2126 else if(surfaceLevel >= levelCount)
2127 {
2128 surfaceLevel = levelCount - 1;
2129 }
2130
2131 Image *surface = texture->getImage(surfaceLevel);
2132 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2133 }
2134 }
2135 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
2136 {
2137 for(int face = 0; face < 6; face++)
2138 {
2139 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
2140
2141 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
2142 {
2143 int surfaceLevel = mipmapLevel;
2144
2145 if(surfaceLevel < 0)
2146 {
2147 surfaceLevel = 0;
2148 }
2149 else if(surfaceLevel >= levelCount)
2150 {
2151 surfaceLevel = levelCount - 1;
2152 }
2153
2154 Image *surface = cubeTexture->getImage(face, surfaceLevel);
2155 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
2156 }
2157 }
2158 }
2159 else UNIMPLEMENTED();
2160 }
2161 else
2162 {
2163 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
2164 }
2165 }
2166
readPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei * bufSize,void * pixels)2167 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2168 GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2169 {
2170 Framebuffer *framebuffer = getReadFramebuffer();
2171 int framebufferWidth, framebufferHeight, framebufferSamples;
2172
2173 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2174 {
2175 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2176 }
2177
2178 if(getReadFramebufferName() != 0 && framebufferSamples != 0)
2179 {
2180 return error(GL_INVALID_OPERATION);
2181 }
2182
2183 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
2184
2185 // Sized query sanity check
2186 if(bufSize)
2187 {
2188 int requiredSize = outputPitch * height;
2189 if(requiredSize > *bufSize)
2190 {
2191 return error(GL_INVALID_OPERATION);
2192 }
2193 }
2194
2195 Image *renderTarget = framebuffer->getRenderTarget();
2196
2197 if(!renderTarget)
2198 {
2199 return error(GL_OUT_OF_MEMORY);
2200 }
2201
2202 sw::Rect rect = {x, y, x + width, y + height};
2203 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2204
2205 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2206 unsigned char *dest = (unsigned char*)pixels;
2207 unsigned short *dest16 = (unsigned short*)pixels;
2208 int inputPitch = (int)renderTarget->getPitch();
2209
2210 for(int j = 0; j < rect.y1 - rect.y0; j++)
2211 {
2212 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2213 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2214 {
2215 // Fast path for EXT_read_format_bgra, given an RGBA source buffer
2216 // Note that buffers with no alpha go through the slow path below
2217 memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
2218 }
2219 else
2220 {
2221 for(int i = 0; i < rect.x1 - rect.x0; i++)
2222 {
2223 float r;
2224 float g;
2225 float b;
2226 float a;
2227
2228 switch(renderTarget->getInternalFormat())
2229 {
2230 case sw::FORMAT_R5G6B5:
2231 {
2232 unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2233
2234 a = 1.0f;
2235 b = (rgb & 0x001F) * (1.0f / 0x001F);
2236 g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2237 r = (rgb & 0xF800) * (1.0f / 0xF800);
2238 }
2239 break;
2240 case sw::FORMAT_A1R5G5B5:
2241 {
2242 unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2243
2244 a = (argb & 0x8000) ? 1.0f : 0.0f;
2245 b = (argb & 0x001F) * (1.0f / 0x001F);
2246 g = (argb & 0x03E0) * (1.0f / 0x03E0);
2247 r = (argb & 0x7C00) * (1.0f / 0x7C00);
2248 }
2249 break;
2250 case sw::FORMAT_A8R8G8B8:
2251 {
2252 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2253
2254 a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2255 b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2256 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2257 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2258 }
2259 break;
2260 case sw::FORMAT_X8R8G8B8:
2261 {
2262 unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2263
2264 a = 1.0f;
2265 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2266 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2267 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2268 }
2269 break;
2270 case sw::FORMAT_A2R10G10B10:
2271 {
2272 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2273
2274 a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2275 b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2276 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2277 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2278 }
2279 break;
2280 case sw::FORMAT_A32B32G32R32F:
2281 {
2282 r = *((float*)(source + 16 * i + j * inputPitch) + 0);
2283 g = *((float*)(source + 16 * i + j * inputPitch) + 1);
2284 b = *((float*)(source + 16 * i + j * inputPitch) + 2);
2285 a = *((float*)(source + 16 * i + j * inputPitch) + 3);
2286 }
2287 break;
2288 case sw::FORMAT_A16B16G16R16F:
2289 {
2290 r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
2291 g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
2292 b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
2293 a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
2294 }
2295 break;
2296 default:
2297 UNIMPLEMENTED(); // FIXME
2298 UNREACHABLE(renderTarget->getInternalFormat());
2299 }
2300
2301 switch(format)
2302 {
2303 case GL_RGBA:
2304 switch(type)
2305 {
2306 case GL_UNSIGNED_BYTE:
2307 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
2308 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2309 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
2310 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2311 break;
2312 default: UNREACHABLE(type);
2313 }
2314 break;
2315 case GL_BGRA_EXT:
2316 switch(type)
2317 {
2318 case GL_UNSIGNED_BYTE:
2319 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
2320 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2321 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
2322 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2323 break;
2324 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2325 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2326 // this type is packed as follows:
2327 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
2328 // --------------------------------------------------------------------------------
2329 // | 4th | 3rd | 2nd | 1st component |
2330 // --------------------------------------------------------------------------------
2331 // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2332 dest16[i + j * outputPitch / sizeof(unsigned short)] =
2333 ((unsigned short)(15 * a + 0.5f) << 12)|
2334 ((unsigned short)(15 * r + 0.5f) << 8) |
2335 ((unsigned short)(15 * g + 0.5f) << 4) |
2336 ((unsigned short)(15 * b + 0.5f) << 0);
2337 break;
2338 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2339 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2340 // this type is packed as follows:
2341 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
2342 // --------------------------------------------------------------------------------
2343 // | 4th | 3rd | 2nd | 1st component |
2344 // --------------------------------------------------------------------------------
2345 // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2346 dest16[i + j * outputPitch / sizeof(unsigned short)] =
2347 ((unsigned short)( a + 0.5f) << 15) |
2348 ((unsigned short)(31 * r + 0.5f) << 10) |
2349 ((unsigned short)(31 * g + 0.5f) << 5) |
2350 ((unsigned short)(31 * b + 0.5f) << 0);
2351 break;
2352 default: UNREACHABLE(type);
2353 }
2354 break;
2355 case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
2356 switch(type)
2357 {
2358 case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE
2359 dest16[i + j * outputPitch / sizeof(unsigned short)] =
2360 ((unsigned short)(31 * b + 0.5f) << 0) |
2361 ((unsigned short)(63 * g + 0.5f) << 5) |
2362 ((unsigned short)(31 * r + 0.5f) << 11);
2363 break;
2364 default: UNREACHABLE(type);
2365 }
2366 break;
2367 default: UNREACHABLE(format);
2368 }
2369 }
2370 }
2371 }
2372
2373 renderTarget->unlock();
2374 renderTarget->release();
2375 }
2376
clear(GLbitfield mask)2377 void Context::clear(GLbitfield mask)
2378 {
2379 Framebuffer *framebuffer = getDrawFramebuffer();
2380
2381 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2382 {
2383 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2384 }
2385
2386 if(!applyRenderTarget())
2387 {
2388 return;
2389 }
2390
2391 float depth = clamp01(mState.depthClearValue);
2392 int stencil = mState.stencilClearValue & 0x000000FF;
2393
2394 if(mask & GL_COLOR_BUFFER_BIT)
2395 {
2396 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2397 (mState.colorMaskGreen ? 0x2 : 0) |
2398 (mState.colorMaskBlue ? 0x4 : 0) |
2399 (mState.colorMaskAlpha ? 0x8 : 0);
2400
2401 if(rgbaMask != 0)
2402 {
2403 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
2404 }
2405 }
2406
2407 if(mask & GL_DEPTH_BUFFER_BIT)
2408 {
2409 if(mState.depthMask != 0)
2410 {
2411 device->clearDepth(depth);
2412 }
2413 }
2414
2415 if(mask & GL_STENCIL_BUFFER_BIT)
2416 {
2417 if(mState.stencilWritemask != 0)
2418 {
2419 device->clearStencil(stencil, mState.stencilWritemask);
2420 }
2421 }
2422 }
2423
drawArrays(GLenum mode,GLint first,GLsizei count)2424 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2425 {
2426 if(!mState.currentProgram)
2427 {
2428 device->setProjectionMatrix(projection.current());
2429 device->setViewMatrix(modelView.current());
2430 device->setTextureMatrix(0, texture[0].current());
2431 device->setTextureMatrix(1, texture[1].current());
2432 device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
2433 device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
2434 device->setTexGen(0, sw::TEXGEN_NONE);
2435 device->setTexGen(1, sw::TEXGEN_NONE);
2436 }
2437
2438 PrimitiveType primitiveType;
2439 int primitiveCount;
2440
2441 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2442 return error(GL_INVALID_ENUM);
2443
2444 if(primitiveCount <= 0)
2445 {
2446 return;
2447 }
2448
2449 if(!applyRenderTarget())
2450 {
2451 return;
2452 }
2453
2454 applyState(mode);
2455
2456 GLenum err = applyVertexBuffer(0, first, count);
2457 if(err != GL_NO_ERROR)
2458 {
2459 return error(err);
2460 }
2461
2462 applyShaders();
2463 applyTextures();
2464
2465 if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false))
2466 {
2467 return error(GL_INVALID_OPERATION);
2468 }
2469
2470 if(!cullSkipsDraw(mode))
2471 {
2472 device->drawPrimitive(primitiveType, primitiveCount);
2473 }
2474 }
2475
drawElements(GLenum mode,GLsizei count,GLenum type,const void * indices)2476 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2477 {
2478 if(!mState.currentProgram)
2479 {
2480 return error(GL_INVALID_OPERATION);
2481 }
2482
2483 if(!indices && !mState.elementArrayBuffer)
2484 {
2485 return error(GL_INVALID_OPERATION);
2486 }
2487
2488 PrimitiveType primitiveType;
2489 int primitiveCount;
2490
2491 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2492 return error(GL_INVALID_ENUM);
2493
2494 if(primitiveCount <= 0)
2495 {
2496 return;
2497 }
2498
2499 if(!applyRenderTarget())
2500 {
2501 return;
2502 }
2503
2504 applyState(mode);
2505
2506 TranslatedIndexData indexInfo;
2507 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2508 if(err != GL_NO_ERROR)
2509 {
2510 return error(err);
2511 }
2512
2513 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2514 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2515 if(err != GL_NO_ERROR)
2516 {
2517 return error(err);
2518 }
2519
2520 applyShaders();
2521 applyTextures();
2522
2523 if(!getCurrentProgram()->validateSamplers(false))
2524 {
2525 return error(GL_INVALID_OPERATION);
2526 }
2527
2528 if(!cullSkipsDraw(mode))
2529 {
2530 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2531 }
2532 }
2533
finish()2534 void Context::finish()
2535 {
2536 device->finish();
2537 }
2538
flush()2539 void Context::flush()
2540 {
2541 // We don't queue anything without processing it as fast as possible
2542 }
2543
recordInvalidEnum()2544 void Context::recordInvalidEnum()
2545 {
2546 mInvalidEnum = true;
2547 }
2548
recordInvalidValue()2549 void Context::recordInvalidValue()
2550 {
2551 mInvalidValue = true;
2552 }
2553
recordInvalidOperation()2554 void Context::recordInvalidOperation()
2555 {
2556 mInvalidOperation = true;
2557 }
2558
recordOutOfMemory()2559 void Context::recordOutOfMemory()
2560 {
2561 mOutOfMemory = true;
2562 }
2563
recordInvalidFramebufferOperation()2564 void Context::recordInvalidFramebufferOperation()
2565 {
2566 mInvalidFramebufferOperation = true;
2567 }
2568
2569 // Get one of the recorded errors and clear its flag, if any.
getError()2570 GLenum Context::getError()
2571 {
2572 if(mInvalidEnum)
2573 {
2574 mInvalidEnum = false;
2575
2576 return GL_INVALID_ENUM;
2577 }
2578
2579 if(mInvalidValue)
2580 {
2581 mInvalidValue = false;
2582
2583 return GL_INVALID_VALUE;
2584 }
2585
2586 if(mInvalidOperation)
2587 {
2588 mInvalidOperation = false;
2589
2590 return GL_INVALID_OPERATION;
2591 }
2592
2593 if(mOutOfMemory)
2594 {
2595 mOutOfMemory = false;
2596
2597 return GL_OUT_OF_MEMORY;
2598 }
2599
2600 if(mInvalidFramebufferOperation)
2601 {
2602 mInvalidFramebufferOperation = false;
2603
2604 return GL_INVALID_FRAMEBUFFER_OPERATION;
2605 }
2606
2607 return GL_NO_ERROR;
2608 }
2609
getSupportedMultisampleCount(int requested)2610 int Context::getSupportedMultisampleCount(int requested)
2611 {
2612 int supported = 0;
2613
2614 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
2615 {
2616 if(supported >= requested)
2617 {
2618 return supported;
2619 }
2620
2621 supported = multisampleCount[i];
2622 }
2623
2624 return supported;
2625 }
2626
detachBuffer(GLuint buffer)2627 void Context::detachBuffer(GLuint buffer)
2628 {
2629 // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2630 // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2631
2632 if(mState.arrayBuffer.name() == buffer)
2633 {
2634 mState.arrayBuffer = nullptr;
2635 }
2636
2637 if(mState.elementArrayBuffer.name() == buffer)
2638 {
2639 mState.elementArrayBuffer = nullptr;
2640 }
2641
2642 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2643 {
2644 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
2645 {
2646 mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
2647 }
2648 }
2649 }
2650
detachTexture(GLuint texture)2651 void Context::detachTexture(GLuint texture)
2652 {
2653 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2654 // rebound to texture object zero
2655
2656 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2657 {
2658 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2659 {
2660 if(mState.samplerTexture[type][sampler].name() == texture)
2661 {
2662 mState.samplerTexture[type][sampler] = nullptr;
2663 }
2664 }
2665 }
2666
2667 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2668 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2669 // image was attached in the currently bound framebuffer.
2670
2671 Framebuffer *readFramebuffer = getReadFramebuffer();
2672 Framebuffer *drawFramebuffer = getDrawFramebuffer();
2673
2674 if(readFramebuffer)
2675 {
2676 readFramebuffer->detachTexture(texture);
2677 }
2678
2679 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2680 {
2681 drawFramebuffer->detachTexture(texture);
2682 }
2683 }
2684
detachFramebuffer(GLuint framebuffer)2685 void Context::detachFramebuffer(GLuint framebuffer)
2686 {
2687 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2688 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2689
2690 if(mState.readFramebuffer == framebuffer)
2691 {
2692 bindReadFramebuffer(0);
2693 }
2694
2695 if(mState.drawFramebuffer == framebuffer)
2696 {
2697 bindDrawFramebuffer(0);
2698 }
2699 }
2700
detachRenderbuffer(GLuint renderbuffer)2701 void Context::detachRenderbuffer(GLuint renderbuffer)
2702 {
2703 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2704 // had been executed with the target RENDERBUFFER and name of zero.
2705
2706 if(mState.renderbuffer.name() == renderbuffer)
2707 {
2708 bindRenderbuffer(0);
2709 }
2710
2711 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2712 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2713 // point to which this image was attached in the currently bound framebuffer.
2714
2715 Framebuffer *readFramebuffer = getReadFramebuffer();
2716 Framebuffer *drawFramebuffer = getDrawFramebuffer();
2717
2718 if(readFramebuffer)
2719 {
2720 readFramebuffer->detachRenderbuffer(renderbuffer);
2721 }
2722
2723 if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2724 {
2725 drawFramebuffer->detachRenderbuffer(renderbuffer);
2726 }
2727 }
2728
cullSkipsDraw(GLenum drawMode)2729 bool Context::cullSkipsDraw(GLenum drawMode)
2730 {
2731 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
2732 }
2733
isTriangleMode(GLenum drawMode)2734 bool Context::isTriangleMode(GLenum drawMode)
2735 {
2736 switch(drawMode)
2737 {
2738 case GL_TRIANGLES:
2739 case GL_TRIANGLE_FAN:
2740 case GL_TRIANGLE_STRIP:
2741 return true;
2742 case GL_POINTS:
2743 case GL_LINES:
2744 case GL_LINE_LOOP:
2745 case GL_LINE_STRIP:
2746 return false;
2747 default: UNREACHABLE(drawMode);
2748 }
2749
2750 return false;
2751 }
2752
setVertexAttrib(GLuint index,float x,float y,float z,float w)2753 void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w)
2754 {
2755 ASSERT(index < MAX_VERTEX_ATTRIBS);
2756
2757 mState.vertexAttribute[index].mCurrentValue[0] = x;
2758 mState.vertexAttribute[index].mCurrentValue[1] = y;
2759 mState.vertexAttribute[index].mCurrentValue[2] = z;
2760 mState.vertexAttribute[index].mCurrentValue[3] = w;
2761
2762 mVertexDataManager->dirtyCurrentValue(index);
2763 }
2764
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask)2765 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2766 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2767 GLbitfield mask)
2768 {
2769 Framebuffer *readFramebuffer = getReadFramebuffer();
2770 Framebuffer *drawFramebuffer = getDrawFramebuffer();
2771
2772 int readBufferWidth, readBufferHeight, readBufferSamples;
2773 int drawBufferWidth, drawBufferHeight, drawBufferSamples;
2774
2775 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
2776 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2777 {
2778 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2779 }
2780
2781 if(drawBufferSamples > 1)
2782 {
2783 return error(GL_INVALID_OPERATION);
2784 }
2785
2786 sw::SliceRect sourceRect;
2787 sw::SliceRect destRect;
2788
2789 if(srcX0 < srcX1)
2790 {
2791 sourceRect.x0 = srcX0;
2792 sourceRect.x1 = srcX1;
2793 destRect.x0 = dstX0;
2794 destRect.x1 = dstX1;
2795 }
2796 else
2797 {
2798 sourceRect.x0 = srcX1;
2799 destRect.x0 = dstX1;
2800 sourceRect.x1 = srcX0;
2801 destRect.x1 = dstX0;
2802 }
2803
2804 if(srcY0 < srcY1)
2805 {
2806 sourceRect.y0 = srcY0;
2807 destRect.y0 = dstY0;
2808 sourceRect.y1 = srcY1;
2809 destRect.y1 = dstY1;
2810 }
2811 else
2812 {
2813 sourceRect.y0 = srcY1;
2814 destRect.y0 = dstY1;
2815 sourceRect.y1 = srcY0;
2816 destRect.y1 = dstY0;
2817 }
2818
2819 sw::Rect sourceScissoredRect = sourceRect;
2820 sw::Rect destScissoredRect = destRect;
2821
2822 if(mState.scissorTestEnabled) // Only write to parts of the destination framebuffer which pass the scissor test
2823 {
2824 if(destRect.x0 < mState.scissorX)
2825 {
2826 int xDiff = mState.scissorX - destRect.x0;
2827 destScissoredRect.x0 = mState.scissorX;
2828 sourceScissoredRect.x0 += xDiff;
2829 }
2830
2831 if(destRect.x1 > mState.scissorX + mState.scissorWidth)
2832 {
2833 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
2834 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
2835 sourceScissoredRect.x1 -= xDiff;
2836 }
2837
2838 if(destRect.y0 < mState.scissorY)
2839 {
2840 int yDiff = mState.scissorY - destRect.y0;
2841 destScissoredRect.y0 = mState.scissorY;
2842 sourceScissoredRect.y0 += yDiff;
2843 }
2844
2845 if(destRect.y1 > mState.scissorY + mState.scissorHeight)
2846 {
2847 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
2848 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
2849 sourceScissoredRect.y1 -= yDiff;
2850 }
2851 }
2852
2853 sw::Rect sourceTrimmedRect = sourceScissoredRect;
2854 sw::Rect destTrimmedRect = destScissoredRect;
2855
2856 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2857 // the actual draw and read surfaces.
2858 if(sourceTrimmedRect.x0 < 0)
2859 {
2860 int xDiff = 0 - sourceTrimmedRect.x0;
2861 sourceTrimmedRect.x0 = 0;
2862 destTrimmedRect.x0 += xDiff;
2863 }
2864
2865 if(sourceTrimmedRect.x1 > readBufferWidth)
2866 {
2867 int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
2868 sourceTrimmedRect.x1 = readBufferWidth;
2869 destTrimmedRect.x1 -= xDiff;
2870 }
2871
2872 if(sourceTrimmedRect.y0 < 0)
2873 {
2874 int yDiff = 0 - sourceTrimmedRect.y0;
2875 sourceTrimmedRect.y0 = 0;
2876 destTrimmedRect.y0 += yDiff;
2877 }
2878
2879 if(sourceTrimmedRect.y1 > readBufferHeight)
2880 {
2881 int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
2882 sourceTrimmedRect.y1 = readBufferHeight;
2883 destTrimmedRect.y1 -= yDiff;
2884 }
2885
2886 if(destTrimmedRect.x0 < 0)
2887 {
2888 int xDiff = 0 - destTrimmedRect.x0;
2889 destTrimmedRect.x0 = 0;
2890 sourceTrimmedRect.x0 += xDiff;
2891 }
2892
2893 if(destTrimmedRect.x1 > drawBufferWidth)
2894 {
2895 int xDiff = destTrimmedRect.x1 - drawBufferWidth;
2896 destTrimmedRect.x1 = drawBufferWidth;
2897 sourceTrimmedRect.x1 -= xDiff;
2898 }
2899
2900 if(destTrimmedRect.y0 < 0)
2901 {
2902 int yDiff = 0 - destTrimmedRect.y0;
2903 destTrimmedRect.y0 = 0;
2904 sourceTrimmedRect.y0 += yDiff;
2905 }
2906
2907 if(destTrimmedRect.y1 > drawBufferHeight)
2908 {
2909 int yDiff = destTrimmedRect.y1 - drawBufferHeight;
2910 destTrimmedRect.y1 = drawBufferHeight;
2911 sourceTrimmedRect.y1 -= yDiff;
2912 }
2913
2914 bool partialBufferCopy = false;
2915
2916 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
2917 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
2918 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
2919 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
2920 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
2921 {
2922 partialBufferCopy = true;
2923 }
2924
2925 bool blitRenderTarget = false;
2926 bool blitDepthStencil = false;
2927
2928 if(mask & GL_COLOR_BUFFER_BIT)
2929 {
2930 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2931 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2932 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2933 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2934 if(!validReadType || !validDrawType ||
2935 readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
2936 {
2937 ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2938 return error(GL_INVALID_OPERATION);
2939 }
2940
2941 if(partialBufferCopy && readBufferSamples > 1)
2942 {
2943 return error(GL_INVALID_OPERATION);
2944 }
2945
2946 blitRenderTarget = true;
2947 }
2948
2949 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2950 {
2951 Renderbuffer *readDSBuffer = nullptr;
2952 Renderbuffer *drawDSBuffer = nullptr;
2953
2954 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2955 // both a depth and stencil buffer, it will be the same buffer.
2956
2957 if(mask & GL_DEPTH_BUFFER_BIT)
2958 {
2959 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2960 {
2961 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2962 readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
2963 {
2964 return error(GL_INVALID_OPERATION);
2965 }
2966
2967 blitDepthStencil = true;
2968 readDSBuffer = readFramebuffer->getDepthbuffer();
2969 drawDSBuffer = drawFramebuffer->getDepthbuffer();
2970 }
2971 }
2972
2973 if(mask & GL_STENCIL_BUFFER_BIT)
2974 {
2975 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2976 {
2977 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2978 readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
2979 {
2980 return error(GL_INVALID_OPERATION);
2981 }
2982
2983 blitDepthStencil = true;
2984 readDSBuffer = readFramebuffer->getStencilbuffer();
2985 drawDSBuffer = drawFramebuffer->getStencilbuffer();
2986 }
2987 }
2988
2989 if(partialBufferCopy)
2990 {
2991 ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2992 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted
2993 }
2994
2995 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
2996 (readDSBuffer && readDSBuffer->getSamples() > 1))
2997 {
2998 return error(GL_INVALID_OPERATION);
2999 }
3000 }
3001
3002 if(blitRenderTarget || blitDepthStencil)
3003 {
3004 if(blitRenderTarget)
3005 {
3006 Image *readRenderTarget = readFramebuffer->getRenderTarget();
3007 Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
3008
3009 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
3010
3011 readRenderTarget->release();
3012 drawRenderTarget->release();
3013
3014 if(!success)
3015 {
3016 ERR("BlitFramebufferANGLE failed.");
3017 return;
3018 }
3019 }
3020
3021 if(blitDepthStencil)
3022 {
3023 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false);
3024
3025 if(!success)
3026 {
3027 ERR("BlitFramebufferANGLE failed.");
3028 return;
3029 }
3030 }
3031 }
3032 }
3033
setMatrixMode(GLenum mode)3034 void Context::setMatrixMode(GLenum mode)
3035 {
3036 matrixMode = mode;
3037 }
3038
currentMatrixStack()3039 sw::MatrixStack &Context::currentMatrixStack()
3040 {
3041 switch(matrixMode)
3042 {
3043 case GL_MODELVIEW: return modelView; break;
3044 case GL_PROJECTION: return projection; break;
3045 case GL_TEXTURE: return texture[mState.activeSampler]; break;
3046 default: UNREACHABLE(matrixMode); return modelView; break;
3047 }
3048 }
3049
loadIdentity()3050 void Context::loadIdentity()
3051 {
3052 if(drawing)
3053 {
3054 return error(GL_INVALID_OPERATION);
3055 }
3056
3057 currentMatrixStack().identity();
3058 }
3059
pushMatrix()3060 void Context::pushMatrix()
3061 {
3062 //if(drawing)
3063 //{
3064 // return error(GL_INVALID_OPERATION);
3065 //}
3066
3067 if(!currentMatrixStack().push())
3068 {
3069 return error(GL_STACK_OVERFLOW);
3070 }
3071 }
3072
popMatrix()3073 void Context::popMatrix()
3074 {
3075 //if(drawing)
3076 //{
3077 // return error(GL_INVALID_OPERATION);
3078 //}
3079
3080 if(!currentMatrixStack().pop())
3081 {
3082 return error(GL_STACK_OVERFLOW);
3083 }
3084 }
3085
rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3086 void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3087 {
3088 if(drawing)
3089 {
3090 return error(GL_INVALID_OPERATION);
3091 }
3092
3093 currentMatrixStack().rotate(angle, x, y, z);
3094 }
3095
translate(GLfloat x,GLfloat y,GLfloat z)3096 void Context::translate(GLfloat x, GLfloat y, GLfloat z)
3097 {
3098 if(drawing)
3099 {
3100 return error(GL_INVALID_OPERATION);
3101 }
3102
3103 currentMatrixStack().translate(x, y, z);
3104 }
3105
scale(GLfloat x,GLfloat y,GLfloat z)3106 void Context::scale(GLfloat x, GLfloat y, GLfloat z)
3107 {
3108 if(drawing)
3109 {
3110 return error(GL_INVALID_OPERATION);
3111 }
3112
3113 currentMatrixStack().scale(x, y, z);
3114 }
3115
multiply(const GLdouble * m)3116 void Context::multiply(const GLdouble *m)
3117 {
3118 if(drawing)
3119 {
3120 return error(GL_INVALID_OPERATION);
3121 }
3122
3123 currentMatrixStack().multiply(m);
3124 }
3125
multiply(const GLfloat * m)3126 void Context::multiply(const GLfloat *m)
3127 {
3128 if(drawing)
3129 {
3130 return error(GL_INVALID_OPERATION);
3131 }
3132
3133 currentMatrixStack().multiply(m);
3134 }
3135
frustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar)3136 void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3137 {
3138 if(drawing)
3139 {
3140 return error(GL_INVALID_OPERATION);
3141 }
3142
3143 currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
3144 }
3145
ortho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble zNear,GLdouble zFar)3146 void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
3147 {
3148 if(drawing)
3149 {
3150 return error(GL_INVALID_OPERATION);
3151 }
3152
3153 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
3154 }
3155
setLightingEnabled(bool enable)3156 void Context::setLightingEnabled(bool enable)
3157 {
3158 if(drawing)
3159 {
3160 return error(GL_INVALID_OPERATION);
3161 }
3162
3163 device->setLightingEnable(enable);
3164 }
3165
setFogEnabled(bool enable)3166 void Context::setFogEnabled(bool enable)
3167 {
3168 if(drawing)
3169 {
3170 return error(GL_INVALID_OPERATION);
3171 }
3172
3173 device->setFogEnable(enable);
3174 }
3175
setAlphaTestEnabled(bool enable)3176 void Context::setAlphaTestEnabled(bool enable)
3177 {
3178 if(drawing)
3179 {
3180 return error(GL_INVALID_OPERATION);
3181 }
3182
3183 device->setAlphaTestEnable(enable);
3184 }
3185
alphaFunc(GLenum func,GLclampf ref)3186 void Context::alphaFunc(GLenum func, GLclampf ref)
3187 {
3188 if(drawing)
3189 {
3190 return error(GL_INVALID_OPERATION);
3191 }
3192
3193 switch(func)
3194 {
3195 case GL_NEVER: device->setAlphaCompare(sw::ALPHA_NEVER); break;
3196 case GL_LESS: device->setAlphaCompare(sw::ALPHA_LESS); break;
3197 case GL_EQUAL: device->setAlphaCompare(sw::ALPHA_EQUAL); break;
3198 case GL_LEQUAL: device->setAlphaCompare(sw::ALPHA_LESSEQUAL); break;
3199 case GL_GREATER: device->setAlphaCompare(sw::ALPHA_GREATER); break;
3200 case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL); break;
3201 case GL_GEQUAL: device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break;
3202 case GL_ALWAYS: device->setAlphaCompare(sw::ALPHA_ALWAYS); break;
3203 default: UNREACHABLE(func);
3204 }
3205
3206 device->setAlphaReference(gl::clamp01(ref));
3207 }
3208
setTexture2DEnabled(bool enable)3209 void Context::setTexture2DEnabled(bool enable)
3210 {
3211 if(drawing)
3212 {
3213 return error(GL_INVALID_OPERATION);
3214 }
3215
3216 envEnable[mState.activeSampler] = enable;
3217 }
3218
setShadeModel(GLenum mode)3219 void Context::setShadeModel(GLenum mode)
3220 {
3221 //if(drawing)
3222 //{
3223 // return error(GL_INVALID_OPERATION);
3224 //}
3225
3226 switch(mode)
3227 {
3228 case GL_FLAT: device->setShadingMode(sw::SHADING_FLAT); break;
3229 case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
3230 default: return error(GL_INVALID_ENUM);
3231 }
3232 }
3233
setLightEnabled(int index,bool enable)3234 void Context::setLightEnabled(int index, bool enable)
3235 {
3236 device->setLightEnable(index, enable);
3237 }
3238
setNormalizeNormalsEnabled(bool enable)3239 void Context::setNormalizeNormalsEnabled(bool enable)
3240 {
3241 device->setNormalizeNormals(enable);
3242 }
3243
genLists(GLsizei range)3244 GLuint Context::genLists(GLsizei range)
3245 {
3246 if(drawing)
3247 {
3248 return error(GL_INVALID_OPERATION, 0);
3249 }
3250
3251 int firstIndex = std::max(1u, firstFreeIndex);
3252 for(; true; firstIndex++)
3253 {
3254 int empty = 0;
3255 for(; empty < range; empty++)
3256 {
3257 if(displayList[firstIndex + empty] != 0)
3258 {
3259 break;
3260 }
3261 }
3262
3263 if(empty == range)
3264 {
3265 for(int i = firstIndex; i < firstIndex + range; i++)
3266 {
3267 displayList[i] = new DisplayList();
3268 }
3269
3270 if(firstIndex == firstFreeIndex)
3271 {
3272 firstFreeIndex = firstIndex + range;
3273 }
3274
3275 return firstIndex;
3276 }
3277 }
3278
3279 return 0;
3280 }
3281
newList(GLuint list,GLenum mode)3282 void Context::newList(GLuint list, GLenum mode)
3283 {
3284 if(drawing || listIndex != 0)
3285 {
3286 return error(GL_INVALID_OPERATION);
3287 }
3288
3289 ASSERT(!this->list);
3290 this->list = new DisplayList();
3291
3292 listIndex = list;
3293 listMode = mode;
3294 }
3295
endList()3296 void Context::endList()
3297 {
3298 if(drawing || listIndex == 0)
3299 {
3300 return error(GL_INVALID_OPERATION);
3301 }
3302
3303 ASSERT(list);
3304 delete displayList[listIndex];
3305 displayList[listIndex] = list;
3306 list = 0;
3307
3308 listIndex = 0;
3309 listMode = 0;
3310 }
3311
callList(GLuint list)3312 void Context::callList(GLuint list)
3313 {
3314 // As per GL specifications, if the list does not exist, it is ignored
3315 if(displayList[list])
3316 {
3317 displayList[list]->call();
3318 }
3319 }
3320
deleteList(GLuint list)3321 void Context::deleteList(GLuint list)
3322 {
3323 delete displayList[list];
3324 displayList[list] = 0;
3325 displayList.erase(list);
3326 firstFreeIndex = std::min(firstFreeIndex , list);
3327 }
3328
listCommand(Command * command)3329 void Context::listCommand(Command *command)
3330 {
3331 ASSERT(list);
3332 list->list.push_back(command);
3333
3334 if(listMode == GL_COMPILE_AND_EXECUTE)
3335 {
3336 listMode = 0;
3337 command->call();
3338 listMode = GL_COMPILE_AND_EXECUTE;
3339 }
3340 }
3341
glVertexAttribArray(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)3342 void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
3343 {
3344 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
3345 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
3346 index, size, type, normalized, stride, ptr);
3347
3348 gl::Context *context = gl::getContext();
3349
3350 if(context)
3351 {
3352 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
3353 context->setVertexAttribArrayEnabled(index, ptr != 0);
3354 }
3355 }
3356
captureAttribs()3357 void Context::captureAttribs()
3358 {
3359 memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute));
3360 }
3361
captureDrawArrays(GLenum mode,GLint first,GLsizei count)3362 void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count)
3363 {
3364 ASSERT(first == 0); // FIXME: UNIMPLEMENTED!
3365
3366 for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3367 {
3368 GLint size = mState.vertexAttribute[i].mSize;
3369 GLenum type = mState.vertexAttribute[i].mType;
3370 GLboolean normalized = mState.vertexAttribute[i].mNormalized;
3371 GLsizei stride = mState.vertexAttribute[i].mStride;
3372 const GLvoid *pointer = mState.vertexAttribute[i].mPointer;
3373
3374 size_t length = count * mState.vertexAttribute[i].stride();
3375
3376 if(mState.vertexAttribute[i].mArrayEnabled)
3377 {
3378 ASSERT(pointer); // FIXME: Add to condition?
3379 const int padding = 1024; // For SIMD processing of vertices // FIXME: Still necessary?
3380 void *buffer = new unsigned char[length + padding];
3381 memcpy(buffer, pointer, length);
3382
3383 listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer));
3384 }
3385 else
3386 {
3387 listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0));
3388 }
3389 }
3390 }
3391
restoreAttribs()3392 void Context::restoreAttribs()
3393 {
3394 memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute));
3395 }
3396
clientActiveTexture(GLenum texture)3397 void Context::clientActiveTexture(GLenum texture)
3398 {
3399 clientTexture = texture;
3400 }
3401
getClientActiveTexture() const3402 GLenum Context::getClientActiveTexture() const
3403 {
3404 return clientTexture;
3405 }
3406
getActiveTexture() const3407 unsigned int Context::getActiveTexture() const
3408 {
3409 return mState.activeSampler;
3410 }
3411
begin(GLenum mode)3412 void Context::begin(GLenum mode)
3413 {
3414 if(drawing)
3415 {
3416 return error(GL_INVALID_OPERATION);
3417 }
3418
3419 drawing = true;
3420 drawMode = mode;
3421
3422 vertex.clear();
3423 }
3424
position(GLfloat x,GLfloat y,GLfloat z,GLfloat w)3425 void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3426 {
3427 InVertex v;
3428
3429 v.P.x = x;
3430 v.P.y = y;
3431 v.P.z = z;
3432 v.P.w = w;
3433 v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0];
3434 v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1];
3435 v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2];
3436 v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3];
3437 v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0];
3438 v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1];
3439 v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2];
3440 v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3];
3441 v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0];
3442 v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1];
3443 v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2];
3444 v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3];
3445 v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0];
3446 v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1];
3447 v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2];
3448 v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3];
3449
3450 vertex.push_back(v);
3451 }
3452
end()3453 void Context::end()
3454 {
3455 if(!drawing)
3456 {
3457 return error(GL_INVALID_OPERATION);
3458 }
3459
3460 device->setProjectionMatrix(projection.current());
3461 device->setViewMatrix(modelView.current());
3462 device->setTextureMatrix(0, texture[0].current());
3463 device->setTextureMatrix(1, texture[1].current());
3464 device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false);
3465 device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false);
3466
3467 captureAttribs();
3468
3469 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3470 {
3471 mState.vertexAttribute[i].mArrayEnabled = false;
3472 }
3473
3474 setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P);
3475 setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N);
3476 setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C);
3477 setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0);
3478 setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1);
3479
3480 mState.vertexAttribute[sw::Position].mArrayEnabled = true;
3481 mState.vertexAttribute[sw::Normal].mArrayEnabled = true;
3482 mState.vertexAttribute[sw::Color0].mArrayEnabled = true;
3483 mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true;
3484 mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true;
3485
3486 applyState(drawMode);
3487
3488 GLenum err = applyVertexBuffer(0, 0, vertex.size());
3489 if(err != GL_NO_ERROR)
3490 {
3491 return error(err);
3492 }
3493
3494 applyTextures();
3495
3496 switch(drawMode)
3497 {
3498 case GL_POINTS:
3499 UNIMPLEMENTED();
3500 break;
3501 case GL_LINES:
3502 UNIMPLEMENTED();
3503 break;
3504 case GL_LINE_STRIP:
3505 UNIMPLEMENTED();
3506 break;
3507 case GL_LINE_LOOP:
3508 UNIMPLEMENTED();
3509 break;
3510 case GL_TRIANGLES:
3511 UNIMPLEMENTED();
3512 break;
3513 case GL_TRIANGLE_STRIP:
3514 device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2);
3515 break;
3516 case GL_TRIANGLE_FAN:
3517 UNIMPLEMENTED();
3518 break;
3519 case GL_QUADS:
3520 UNIMPLEMENTED();
3521 break;
3522 case GL_QUAD_STRIP:
3523 UNIMPLEMENTED();
3524 break;
3525 case GL_POLYGON:
3526 UNIMPLEMENTED();
3527 break;
3528 default:
3529 UNREACHABLE(drawMode);
3530 }
3531
3532 restoreAttribs();
3533
3534 drawing = false;
3535 }
3536
setColorLogicOpEnabled(bool colorLogicOpEnabled)3537 void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled)
3538 {
3539 if(mState.colorLogicOpEnabled != colorLogicOpEnabled)
3540 {
3541 mState.colorLogicOpEnabled = colorLogicOpEnabled;
3542 mColorLogicOperatorDirty = true;
3543 }
3544 }
3545
isColorLogicOpEnabled()3546 bool Context::isColorLogicOpEnabled()
3547 {
3548 return mState.colorLogicOpEnabled;
3549 }
3550
setLogicalOperation(GLenum logicalOperation)3551 void Context::setLogicalOperation(GLenum logicalOperation)
3552 {
3553 if(mState.logicalOperation != logicalOperation)
3554 {
3555 mState.logicalOperation = logicalOperation;
3556 mColorLogicOperatorDirty = true;
3557 }
3558 }
3559
setColorMaterialEnabled(bool enable)3560 void Context::setColorMaterialEnabled(bool enable)
3561 {
3562 device->setColorVertexEnable(enable);
3563 }
3564
setColorMaterialMode(GLenum mode)3565 void Context::setColorMaterialMode(GLenum mode)
3566 {
3567 switch(mode)
3568 {
3569 case GL_EMISSION:
3570 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3571 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3572 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3573 device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1);
3574 break;
3575 case GL_AMBIENT:
3576 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3577 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3578 device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3579 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3580 break;
3581 case GL_DIFFUSE:
3582 device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3583 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3584 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3585 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3586 break;
3587 case GL_SPECULAR:
3588 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
3589 device->setSpecularMaterialSource(sw::MATERIAL_COLOR1);
3590 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
3591 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3592 break;
3593 case GL_AMBIENT_AND_DIFFUSE:
3594 device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1);
3595 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
3596 device->setAmbientMaterialSource(sw::MATERIAL_COLOR1);
3597 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
3598 break;
3599 default:
3600 UNREACHABLE(mode);
3601 }
3602 }
3603
getDevice()3604 Device *Context::getDevice()
3605 {
3606 return device;
3607 }
3608
3609 }
3610