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