Home | History | Annotate | Download | only in simplereference
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES Utilities
      3  * ------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief GL Rendering Context.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "sglrGLContext.hpp"
     25 #include "sglrShaderProgram.hpp"
     26 #include "gluPixelTransfer.hpp"
     27 #include "gluTexture.hpp"
     28 #include "gluCallLogWrapper.hpp"
     29 #include "gluStrUtil.hpp"
     30 #include "glwFunctions.hpp"
     31 #include "glwEnums.hpp"
     32 
     33 namespace sglr
     34 {
     35 
     36 using std::vector;
     37 using std::string;
     38 using tcu::TestLog;
     39 using tcu::Vec4;
     40 using tcu::TextureFormat;
     41 
     42 GLContext::GLContext (const glu::RenderContext& context, tcu::TestLog& log, deUint32 logFlags, const tcu::IVec4& baseViewport)
     43 	: Context					(context.getType())
     44 	, m_context					(context)
     45 	, m_log						(log)
     46 	, m_logFlags				(logFlags)
     47 	, m_baseViewport			(baseViewport)
     48 	, m_curViewport				(0, 0, m_baseViewport.z(), m_baseViewport.w())
     49 	, m_curScissor				(0, 0, m_baseViewport.z(), m_baseViewport.w())
     50 	, m_readFramebufferBinding	(0)
     51 	, m_drawFramebufferBinding	(0)
     52 	, m_wrapper					(DE_NULL)
     53 {
     54 	const glw::Functions& gl = m_context.getFunctions();
     55 
     56 	// Logging?
     57 	m_wrapper = new glu::CallLogWrapper(gl, log);
     58 	m_wrapper->enableLogging((logFlags & GLCONTEXT_LOG_CALLS) != 0);
     59 
     60 	// Setup base viewport. This offset is active when default framebuffer is active.
     61 	// \note Calls related to setting up base viewport are not included in log.
     62 	gl.viewport(baseViewport.x(), baseViewport.y(), baseViewport.z(), baseViewport.w());
     63 }
     64 
     65 GLContext::~GLContext (void)
     66 {
     67 	const glw::Functions& gl = m_context.getFunctions();
     68 
     69 	// Clean up all still alive objects
     70 	for (std::set<deUint32>::const_iterator i = m_allocatedFbos.begin();
     71 		 i != m_allocatedFbos.end(); i++)
     72 	{
     73 		deUint32 fbo = *i;
     74 		gl.deleteFramebuffers(1, &fbo);
     75 	}
     76 
     77 	for (std::set<deUint32>::const_iterator i = m_allocatedRbos.begin();
     78 		 i != m_allocatedRbos.end(); i++)
     79 	{
     80 		deUint32 rbo = *i;
     81 		gl.deleteRenderbuffers(1, &rbo);
     82 	}
     83 
     84 	for (std::set<deUint32>::const_iterator i = m_allocatedTextures.begin();
     85 		 i != m_allocatedTextures.end(); i++)
     86 	{
     87 		deUint32 tex = *i;
     88 		gl.deleteTextures(1, &tex);
     89 	}
     90 
     91 	for (std::set<deUint32>::const_iterator i = m_allocatedBuffers.begin();
     92 		 i != m_allocatedBuffers.end(); i++)
     93 	{
     94 		deUint32 buf = *i;
     95 		gl.deleteBuffers(1, &buf);
     96 	}
     97 
     98 	for (std::set<deUint32>::const_iterator i = m_allocatedVaos.begin();
     99 		 i != m_allocatedVaos.end(); i++)
    100 	{
    101 		deUint32 vao = *i;
    102 		gl.deleteVertexArrays(1, &vao);
    103 	}
    104 
    105 	for (std::vector<glu::ShaderProgram*>::iterator i = m_programs.begin();
    106 		i != m_programs.end(); i++)
    107 	{
    108 		delete *i;
    109 	}
    110 
    111 	gl.useProgram(0);
    112 
    113 	delete m_wrapper;
    114 }
    115 
    116 void GLContext::enableLogging (deUint32 logFlags)
    117 {
    118 	m_logFlags = logFlags;
    119 	m_wrapper->enableLogging((logFlags & GLCONTEXT_LOG_CALLS) != 0);
    120 }
    121 
    122 tcu::IVec2 GLContext::getDrawOffset (void) const
    123 {
    124 	if (m_drawFramebufferBinding)
    125 		return tcu::IVec2(0, 0);
    126 	else
    127 		return tcu::IVec2(m_baseViewport.x(), m_baseViewport.y());
    128 }
    129 
    130 tcu::IVec2 GLContext::getReadOffset (void) const
    131 {
    132 	if (m_readFramebufferBinding)
    133 		return tcu::IVec2(0, 0);
    134 	else
    135 		return tcu::IVec2(m_baseViewport.x(), m_baseViewport.y());
    136 }
    137 
    138 int GLContext::getWidth (void) const
    139 {
    140 	return m_baseViewport.z();
    141 }
    142 
    143 int GLContext::getHeight (void) const
    144 {
    145 	return m_baseViewport.w();
    146 }
    147 
    148 void GLContext::activeTexture (deUint32 texture)
    149 {
    150 	m_wrapper->glActiveTexture(texture);
    151 }
    152 
    153 void GLContext::texParameteri (deUint32 target, deUint32 pname, int value)
    154 {
    155 	m_wrapper->glTexParameteri(target, pname, value);
    156 }
    157 
    158 deUint32 GLContext::checkFramebufferStatus(deUint32 target)
    159 {
    160 	return m_wrapper->glCheckFramebufferStatus(target);
    161 }
    162 
    163 void GLContext::viewport (int x, int y, int width, int height)
    164 {
    165 	m_curViewport = tcu::IVec4(x, y, width, height);
    166 	tcu::IVec2 offset = getDrawOffset();
    167 
    168 	// \note For clarity don't add the offset to log
    169 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    170 		m_log << TestLog::Message << "glViewport(" << x << ", " << y << ", " << width << ", " << height << ");" << TestLog::EndMessage;
    171 	m_context.getFunctions().viewport(x+offset.x(), y+offset.y(), width, height);
    172 }
    173 
    174 void GLContext::bindTexture (deUint32 target, deUint32 texture)
    175 {
    176 	m_allocatedTextures.insert(texture);
    177 	m_wrapper->glBindTexture(target, texture);
    178 }
    179 
    180 void GLContext::genTextures (int numTextures, deUint32* textures)
    181 {
    182 	m_wrapper->glGenTextures(numTextures, textures);
    183 	if (numTextures > 0)
    184 		m_allocatedTextures.insert(textures, textures+numTextures);
    185 }
    186 
    187 void GLContext::deleteTextures (int numTextures, const deUint32* textures)
    188 {
    189 	for (int i = 0; i < numTextures; i++)
    190 		m_allocatedTextures.erase(textures[i]);
    191 	m_wrapper->glDeleteTextures(numTextures, textures);
    192 }
    193 
    194 void GLContext::bindFramebuffer (deUint32 target, deUint32 framebuffer)
    195 {
    196 	// \todo [2011-10-13 pyry] This is a bit of a hack since test cases assumes 0 default fbo.
    197 	deUint32 defaultFbo = m_context.getDefaultFramebuffer();
    198 	TCU_CHECK(framebuffer == 0 || framebuffer != defaultFbo);
    199 
    200 	bool isValidTarget = target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER;
    201 
    202 	if (isValidTarget && framebuffer != 0)
    203 		m_allocatedFbos.insert(framebuffer);
    204 
    205 	// Update bindings.
    206 	if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER)
    207 		m_readFramebufferBinding = framebuffer;
    208 
    209 	if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER)
    210 		m_drawFramebufferBinding = framebuffer;
    211 
    212 	if (framebuffer == 0) // Redirect 0 to platform-defined default framebuffer.
    213 		m_wrapper->glBindFramebuffer(target, defaultFbo);
    214 	else
    215 		m_wrapper->glBindFramebuffer(target, framebuffer);
    216 
    217 	// Update viewport and scissor if we updated draw framebuffer binding \note Not logged for clarity
    218 	if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER)
    219 	{
    220 		tcu::IVec2 offset = getDrawOffset();
    221 		m_context.getFunctions().viewport(m_curViewport.x()+offset.x(), m_curViewport.y()+offset.y(), m_curViewport.z(), m_curViewport.w());
    222 		m_context.getFunctions().scissor(m_curScissor.x()+offset.x(), m_curScissor.y()+offset.y(), m_curScissor.z(), m_curScissor.w());
    223 	}
    224 }
    225 
    226 void GLContext::genFramebuffers (int numFramebuffers, deUint32* framebuffers)
    227 {
    228 	m_wrapper->glGenFramebuffers(numFramebuffers, framebuffers);
    229 	if (numFramebuffers > 0)
    230 		m_allocatedFbos.insert(framebuffers, framebuffers+numFramebuffers);
    231 }
    232 
    233 void GLContext::deleteFramebuffers (int numFramebuffers, const deUint32* framebuffers)
    234 {
    235 	for (int i = 0; i < numFramebuffers; i++)
    236 		m_allocatedFbos.erase(framebuffers[i]);
    237 	m_wrapper->glDeleteFramebuffers(numFramebuffers, framebuffers);
    238 }
    239 
    240 void GLContext::bindRenderbuffer (deUint32 target, deUint32 renderbuffer)
    241 {
    242 	m_allocatedRbos.insert(renderbuffer);
    243 	m_wrapper->glBindRenderbuffer(target, renderbuffer);
    244 }
    245 
    246 void GLContext::genRenderbuffers (int numRenderbuffers, deUint32* renderbuffers)
    247 {
    248 	m_wrapper->glGenRenderbuffers(numRenderbuffers, renderbuffers);
    249 	if (numRenderbuffers > 0)
    250 		m_allocatedRbos.insert(renderbuffers, renderbuffers+numRenderbuffers);
    251 }
    252 
    253 void GLContext::deleteRenderbuffers (int numRenderbuffers, const deUint32* renderbuffers)
    254 {
    255 	for (int i = 0; i < numRenderbuffers; i++)
    256 		m_allocatedRbos.erase(renderbuffers[i]);
    257 	m_wrapper->glDeleteRenderbuffers(numRenderbuffers, renderbuffers);
    258 }
    259 
    260 void GLContext::pixelStorei (deUint32 pname, int param)
    261 {
    262 	m_wrapper->glPixelStorei(pname, param);
    263 }
    264 
    265 void GLContext::texImage1D (deUint32 target, int level, deUint32 internalFormat, int width, int border, deUint32 format, deUint32 type, const void* data)
    266 {
    267 	m_wrapper->glTexImage1D(target, level, internalFormat, width, border, format, type, data);
    268 }
    269 
    270 void GLContext::texImage2D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int border, deUint32 format, deUint32 type, const void* data)
    271 {
    272 	m_wrapper->glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
    273 }
    274 
    275 void GLContext::texImage3D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int depth, int border, deUint32 format, deUint32 type, const void* data)
    276 {
    277 	m_wrapper->glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
    278 }
    279 
    280 void GLContext::texSubImage1D (deUint32 target, int level, int xoffset, int width, deUint32 format, deUint32 type, const void* data)
    281 {
    282 	m_wrapper->glTexSubImage1D(target, level, xoffset, width, format, type, data);
    283 }
    284 
    285 void GLContext::texSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int width, int height, deUint32 format, deUint32 type, const void* data)
    286 {
    287 	m_wrapper->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data);
    288 }
    289 
    290 void GLContext::texSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, deUint32 format, deUint32 type, const void* data)
    291 {
    292 	m_wrapper->glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data);
    293 }
    294 
    295 void GLContext::copyTexImage1D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int border)
    296 {
    297 	// Don't log offset.
    298 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    299 		m_log << TestLog::Message << "glCopyTexImage1D("
    300 								  << glu::getTextureTargetStr(target) << ", "
    301 								  << level << ", "
    302 								  << glu::getTextureFormatStr(internalFormat) << ", "
    303 								  << x << ", " << y << ", "
    304 								  << width << ", " << border << ")"
    305 			  << TestLog::EndMessage;
    306 
    307 	tcu::IVec2 offset = getReadOffset();
    308 	m_context.getFunctions().copyTexImage1D(target, level, internalFormat, offset.x()+x, offset.y()+y, width, border);
    309 }
    310 
    311 void GLContext::copyTexImage2D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int height, int border)
    312 {
    313 	// Don't log offset.
    314 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    315 		m_log << TestLog::Message << "glCopyTexImage2D("
    316 								  << glu::getTextureTargetStr(target) << ", "
    317 								  << level << ", "
    318 								  << glu::getTextureFormatStr(internalFormat) << ", "
    319 								  << x << ", " << y << ", "
    320 								  << width << ", " << height
    321 								  << ", " << border << ")"
    322 			  << TestLog::EndMessage;
    323 
    324 	tcu::IVec2 offset = getReadOffset();
    325 	m_context.getFunctions().copyTexImage2D(target, level, internalFormat, offset.x()+x, offset.y()+y, width, height, border);
    326 }
    327 
    328 void GLContext::copyTexSubImage1D (deUint32 target, int level, int xoffset, int x, int y, int width)
    329 {
    330 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    331 		m_log << TestLog::Message << "glCopyTexSubImage1D("
    332 								  << glu::getTextureTargetStr(target) << ", "
    333 								  << level << ", "
    334 								  << xoffset << ", "
    335 								  << x << ", " << y << ", "
    336 								  << width << ")"
    337 			  << TestLog::EndMessage;
    338 
    339 	tcu::IVec2 offset = getReadOffset();
    340 	m_context.getFunctions().copyTexSubImage1D(target, level, xoffset, offset.x()+x, offset.y()+y, width);
    341 }
    342 
    343 void GLContext::copyTexSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int x, int y, int width, int height)
    344 {
    345 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    346 		m_log << TestLog::Message << "glCopyTexSubImage2D("
    347 								  << glu::getTextureTargetStr(target) << ", "
    348 								  << level
    349 								  << ", " << xoffset << ", " << yoffset << ", "
    350 								  << x << ", " << y << ", "
    351 								  << width << ", " << height << ")"
    352 			  << TestLog::EndMessage;
    353 
    354 	tcu::IVec2 offset = getReadOffset();
    355 	m_context.getFunctions().copyTexSubImage2D(target, level, xoffset, yoffset, offset.x()+x, offset.y()+y, width, height);
    356 }
    357 
    358 void GLContext::copyTexSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height)
    359 {
    360 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    361 		m_log << TestLog::Message << "glCopyTexSubImage3D("
    362 								  << glu::getTextureTargetStr(target) << ", "
    363 								  << level
    364 								  << ", " << xoffset << ", " << yoffset << ", " << zoffset << ", "
    365 								  << x << ", " << y << ", "
    366 								  << width << ", " << height << ")"
    367 			  << TestLog::EndMessage;
    368 
    369 	tcu::IVec2 offset = getReadOffset();
    370 	m_context.getFunctions().copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, offset.x()+x, offset.y()+y, width, height);
    371 }
    372 
    373 void GLContext::texStorage2D (deUint32 target, int levels, deUint32 internalFormat, int width, int height)
    374 {
    375 	m_wrapper->glTexStorage2D(target, levels, internalFormat, width, height);
    376 }
    377 
    378 void GLContext::texStorage3D (deUint32 target, int levels, deUint32 internalFormat, int width, int height, int depth)
    379 {
    380 	m_wrapper->glTexStorage3D(target, levels, internalFormat, width, height, depth);
    381 }
    382 
    383 void GLContext::framebufferTexture2D (deUint32 target, deUint32 attachment, deUint32 textarget, deUint32 texture, int level)
    384 {
    385 	m_wrapper->glFramebufferTexture2D(target, attachment, textarget, texture, level);
    386 }
    387 
    388 void GLContext::framebufferTextureLayer (deUint32 target, deUint32 attachment, deUint32 texture, int level, int layer)
    389 {
    390 	m_wrapper->glFramebufferTextureLayer(target, attachment, texture, level, layer);
    391 }
    392 
    393 void GLContext::framebufferRenderbuffer (deUint32 target, deUint32 attachment, deUint32 renderbuffertarget, deUint32 renderbuffer)
    394 {
    395 	m_wrapper->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
    396 }
    397 
    398 void GLContext::getFramebufferAttachmentParameteriv (deUint32 target, deUint32 attachment, deUint32 pname, int* params)
    399 {
    400 	m_wrapper->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
    401 }
    402 
    403 void GLContext::renderbufferStorage (deUint32 target, deUint32 internalformat, int width, int height)
    404 {
    405 	m_wrapper->glRenderbufferStorage(target, internalformat, width, height);
    406 }
    407 
    408 void GLContext::renderbufferStorageMultisample (deUint32 target, int samples, deUint32 internalFormat, int width, int height)
    409 {
    410 	m_wrapper->glRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
    411 }
    412 
    413 void GLContext::bindBuffer (deUint32 target, deUint32 buffer)
    414 {
    415 	m_allocatedBuffers.insert(buffer);
    416 	m_wrapper->glBindBuffer(target, buffer);
    417 }
    418 
    419 void GLContext::genBuffers (int numBuffers, deUint32* buffers)
    420 {
    421 	m_wrapper->glGenBuffers(numBuffers, buffers);
    422 	if (numBuffers > 0)
    423 		m_allocatedBuffers.insert(buffers, buffers+numBuffers);
    424 }
    425 
    426 void GLContext::deleteBuffers (int numBuffers, const deUint32* buffers)
    427 {
    428 	m_wrapper->glDeleteBuffers(numBuffers, buffers);
    429 	for (int i = 0; i < numBuffers; i++)
    430 		m_allocatedBuffers.erase(buffers[i]);
    431 }
    432 
    433 void GLContext::bufferData (deUint32 target, deIntptr size, const void* data, deUint32 usage)
    434 {
    435 	m_wrapper->glBufferData(target, (glw::GLsizeiptr)size, data, usage);
    436 }
    437 
    438 void GLContext::bufferSubData (deUint32 target, deIntptr offset, deIntptr size, const void* data)
    439 {
    440 	m_wrapper->glBufferSubData(target, (glw::GLintptr)offset, (glw::GLsizeiptr)size, data);
    441 }
    442 
    443 void GLContext::clearColor (float red, float green, float blue, float alpha)
    444 {
    445 	m_wrapper->glClearColor(red, green, blue, alpha);
    446 }
    447 
    448 void GLContext::clearDepthf (float depth)
    449 {
    450 	m_wrapper->glClearDepthf(depth);
    451 }
    452 
    453 void GLContext::clearStencil (int stencil)
    454 {
    455 	m_wrapper->glClearStencil(stencil);
    456 }
    457 
    458 void GLContext::clear (deUint32 buffers)
    459 {
    460 	m_wrapper->glClear(buffers);
    461 }
    462 
    463 void GLContext::clearBufferiv (deUint32 buffer, int drawbuffer, const int* value)
    464 {
    465 	m_wrapper->glClearBufferiv(buffer, drawbuffer, value);
    466 }
    467 
    468 void GLContext::clearBufferfv (deUint32 buffer, int drawbuffer, const float* value)
    469 {
    470 	m_wrapper->glClearBufferfv(buffer, drawbuffer, value);
    471 }
    472 
    473 void GLContext::clearBufferuiv (deUint32 buffer, int drawbuffer, const deUint32* value)
    474 {
    475 	m_wrapper->glClearBufferuiv(buffer, drawbuffer, value);
    476 }
    477 
    478 void GLContext::clearBufferfi (deUint32 buffer, int drawbuffer, float depth, int stencil)
    479 {
    480 	m_wrapper->glClearBufferfi(buffer, drawbuffer, depth, stencil);
    481 }
    482 
    483 void GLContext::scissor (int x, int y, int width, int height)
    484 {
    485 	m_curScissor = tcu::IVec4(x, y, width, height);
    486 
    487 	// \note For clarity don't add the offset to log
    488 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    489 		m_log << TestLog::Message << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ");" << TestLog::EndMessage;
    490 
    491 	tcu::IVec2 offset = getDrawOffset();
    492 	m_context.getFunctions().scissor(offset.x()+x, offset.y()+y, width, height);
    493 }
    494 
    495 void GLContext::enable (deUint32 cap)
    496 {
    497 	m_wrapper->glEnable(cap);
    498 }
    499 
    500 void GLContext::disable (deUint32 cap)
    501 {
    502 	m_wrapper->glDisable(cap);
    503 }
    504 
    505 void GLContext::stencilFunc (deUint32 func, int ref, deUint32 mask)
    506 {
    507 	m_wrapper->glStencilFunc(func, ref, mask);
    508 }
    509 
    510 void GLContext::stencilOp (deUint32 sfail, deUint32 dpfail, deUint32 dppass)
    511 {
    512 	m_wrapper->glStencilOp(sfail, dpfail, dppass);
    513 }
    514 
    515 void GLContext::depthFunc (deUint32 func)
    516 {
    517 	m_wrapper->glDepthFunc(func);
    518 }
    519 
    520 void GLContext::depthRangef (float n, float f)
    521 {
    522 	m_wrapper->glDepthRangef(n, f);
    523 }
    524 
    525 void GLContext::depthRange (double n, double f)
    526 {
    527 	m_wrapper->glDepthRange(n, f);
    528 }
    529 
    530 void GLContext::polygonOffset (float factor, float units)
    531 {
    532 	m_wrapper->glPolygonOffset(factor, units);
    533 }
    534 
    535 void GLContext::provokingVertex (deUint32 convention)
    536 {
    537 	m_wrapper->glProvokingVertex(convention);
    538 }
    539 
    540 void GLContext::primitiveRestartIndex (deUint32 index)
    541 {
    542 	m_wrapper->glPrimitiveRestartIndex(index);
    543 }
    544 
    545 void GLContext::stencilFuncSeparate (deUint32 face, deUint32 func, int ref, deUint32 mask)
    546 {
    547 	m_wrapper->glStencilFuncSeparate(face, func, ref, mask);
    548 }
    549 
    550 void GLContext::stencilOpSeparate (deUint32 face, deUint32 sfail, deUint32 dpfail, deUint32 dppass)
    551 {
    552 	m_wrapper->glStencilOpSeparate(face, sfail, dpfail, dppass);
    553 }
    554 
    555 void GLContext::blendEquation (deUint32 mode)
    556 {
    557 	m_wrapper->glBlendEquation(mode);
    558 }
    559 
    560 void GLContext::blendEquationSeparate (deUint32 modeRGB, deUint32 modeAlpha)
    561 {
    562 	m_wrapper->glBlendEquationSeparate(modeRGB, modeAlpha);
    563 }
    564 
    565 void GLContext::blendFunc (deUint32 src, deUint32 dst)
    566 {
    567 	m_wrapper->glBlendFunc(src, dst);
    568 }
    569 
    570 void GLContext::blendFuncSeparate (deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
    571 {
    572 	m_wrapper->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
    573 }
    574 
    575 void GLContext::blendColor (float red, float green, float blue, float alpha)
    576 {
    577 	m_wrapper->glBlendColor(red, green, blue, alpha);
    578 }
    579 
    580 void GLContext::colorMask (deBool r, deBool g, deBool b, deBool a)
    581 {
    582 	m_wrapper->glColorMask((glw::GLboolean)r, (glw::GLboolean)g, (glw::GLboolean)b, (glw::GLboolean)a);
    583 }
    584 
    585 void GLContext::depthMask (deBool mask)
    586 {
    587 	m_wrapper->glDepthMask((glw::GLboolean)mask);
    588 }
    589 
    590 void GLContext::stencilMask (deUint32 mask)
    591 {
    592 	m_wrapper->glStencilMask(mask);
    593 }
    594 
    595 void GLContext::stencilMaskSeparate (deUint32 face, deUint32 mask)
    596 {
    597 	m_wrapper->glStencilMaskSeparate(face, mask);
    598 }
    599 
    600 void GLContext::blitFramebuffer (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, deUint32 mask, deUint32 filter)
    601 {
    602 	tcu::IVec2	drawOffset	= getDrawOffset();
    603 	tcu::IVec2	readOffset	= getReadOffset();
    604 
    605 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    606 		m_log << TestLog::Message << "glBlitFramebuffer("
    607 								  << srcX0 << ", " << srcY0 << ", " << srcX1 << ", " << srcY1 << ", "
    608 								  << dstX0 << ", " << dstY0 << ", " << dstX1 << ", " << dstY1 << ", "
    609 								  << glu::getBufferMaskStr(mask) << ", "
    610 								  << glu::getTextureFilterStr(filter) << ")"
    611 			  << TestLog::EndMessage;
    612 
    613 	m_context.getFunctions().blitFramebuffer(readOffset.x()+srcX0, readOffset.y()+srcY0, readOffset.x()+srcX1, readOffset.y()+srcY1,
    614 											 drawOffset.x()+dstX0, drawOffset.y()+dstY0, drawOffset.x()+dstX1, drawOffset.y()+dstY1,
    615 											 mask, filter);
    616 }
    617 
    618 void GLContext::invalidateSubFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments, int x, int y, int width, int height)
    619 {
    620 	tcu::IVec2 drawOffset = getDrawOffset();
    621 
    622 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    623 		m_log << TestLog::Message << "glInvalidateSubFramebuffer("
    624 								  << glu::getFramebufferTargetStr(target) << ", " << numAttachments << ", "
    625 								  << glu::getInvalidateAttachmentStr(attachments, numAttachments) << ", "
    626 								  << x << ", " << y << ", " << width << ", " << height << ")"
    627 			  << TestLog::EndMessage;
    628 
    629 	m_context.getFunctions().invalidateSubFramebuffer(target, numAttachments, attachments, x+drawOffset.x(), y+drawOffset.y(), width, height);
    630 }
    631 
    632 void GLContext::invalidateFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments)
    633 {
    634 	m_wrapper->glInvalidateFramebuffer(target, numAttachments, attachments);
    635 }
    636 
    637 void GLContext::bindVertexArray (deUint32 array)
    638 {
    639 	m_wrapper->glBindVertexArray(array);
    640 }
    641 
    642 void GLContext::genVertexArrays (int numArrays, deUint32* vertexArrays)
    643 {
    644 	m_wrapper->glGenVertexArrays(numArrays, vertexArrays);
    645 	if (numArrays > 0)
    646 		m_allocatedVaos.insert(vertexArrays, vertexArrays+numArrays);
    647 }
    648 
    649 void GLContext::deleteVertexArrays (int numArrays, const deUint32* vertexArrays)
    650 {
    651 	for (int i = 0; i < numArrays; i++)
    652 		m_allocatedVaos.erase(vertexArrays[i]);
    653 	m_wrapper->glDeleteVertexArrays(numArrays, vertexArrays);
    654 }
    655 
    656 void GLContext::vertexAttribPointer (deUint32 index, int size, deUint32 type, deBool normalized, int stride, const void *pointer)
    657 {
    658 	m_wrapper->glVertexAttribPointer(index, size, type, (glw::GLboolean)normalized, stride, pointer);
    659 }
    660 
    661 void GLContext::vertexAttribIPointer (deUint32 index, int size, deUint32 type, int stride, const void *pointer)
    662 {
    663 	m_wrapper->glVertexAttribIPointer(index, size, type, stride, pointer);
    664 }
    665 
    666 void GLContext::enableVertexAttribArray (deUint32 index)
    667 {
    668 	m_wrapper->glEnableVertexAttribArray(index);
    669 }
    670 
    671 void GLContext::disableVertexAttribArray (deUint32 index)
    672 {
    673 	m_wrapper->glDisableVertexAttribArray(index);
    674 }
    675 
    676 void GLContext::vertexAttribDivisor (deUint32 index, deUint32 divisor)
    677 {
    678 	m_wrapper->glVertexAttribDivisor(index, divisor);
    679 }
    680 
    681 void GLContext::vertexAttrib1f (deUint32 index, float x)
    682 {
    683 	m_wrapper->glVertexAttrib1f(index, x);
    684 }
    685 
    686 void GLContext::vertexAttrib2f (deUint32 index, float x, float y)
    687 {
    688 	m_wrapper->glVertexAttrib2f(index, x, y);
    689 }
    690 
    691 void GLContext::vertexAttrib3f (deUint32 index, float x, float y, float z)
    692 {
    693 	m_wrapper->glVertexAttrib3f(index, x, y, z);
    694 }
    695 
    696 void GLContext::vertexAttrib4f (deUint32 index, float x, float y, float z, float w)
    697 {
    698 	m_wrapper->glVertexAttrib4f(index, x, y, z, w);
    699 }
    700 
    701 void GLContext::vertexAttribI4i (deUint32 index, deInt32 x, deInt32 y, deInt32 z, deInt32 w)
    702 {
    703 	m_wrapper->glVertexAttribI4i(index, x, y, z, w);
    704 }
    705 
    706 void GLContext::vertexAttribI4ui (deUint32 index, deUint32 x, deUint32 y, deUint32 z, deUint32 w)
    707 {
    708 	m_wrapper->glVertexAttribI4ui(index, x, y, z, w);
    709 }
    710 
    711 deInt32 GLContext::getAttribLocation (deUint32 program, const char *name)
    712 {
    713 	return m_wrapper->glGetAttribLocation(program, name);
    714 }
    715 
    716 void GLContext::uniform1f (deInt32 location, float v0)
    717 {
    718 	m_wrapper->glUniform1f(location, v0);
    719 }
    720 
    721 void GLContext::uniform1i (deInt32 location, deInt32 v0)
    722 {
    723 	m_wrapper->glUniform1i(location, v0);
    724 }
    725 
    726 void GLContext::uniform1fv (deInt32 location, deInt32 count, const float* value)
    727 {
    728 	m_wrapper->glUniform1fv(location, count, value);
    729 }
    730 
    731 void GLContext::uniform2fv (deInt32 location, deInt32 count, const float* value)
    732 {
    733 	m_wrapper->glUniform2fv(location, count, value);
    734 }
    735 
    736 void GLContext::uniform3fv (deInt32 location, deInt32 count, const float* value)
    737 {
    738 	m_wrapper->glUniform3fv(location, count, value);
    739 }
    740 
    741 void GLContext::uniform4fv (deInt32 location, deInt32 count, const float* value)
    742 {
    743 	m_wrapper->glUniform4fv(location, count, value);
    744 }
    745 
    746 void GLContext::uniform1iv (deInt32 location, deInt32 count, const deInt32* value)
    747 {
    748 	m_wrapper->glUniform1iv(location, count, value);
    749 }
    750 
    751 void GLContext::uniform2iv (deInt32 location, deInt32 count, const deInt32* value)
    752 {
    753 	m_wrapper->glUniform2iv(location, count, value);
    754 }
    755 
    756 void GLContext::uniform3iv (deInt32 location, deInt32 count, const deInt32* value)
    757 {
    758 	m_wrapper->glUniform3iv(location, count, value);
    759 }
    760 
    761 void GLContext::uniform4iv (deInt32 location, deInt32 count, const deInt32* value)
    762 {
    763 	m_wrapper->glUniform4iv(location, count, value);
    764 }
    765 
    766 void GLContext::uniformMatrix3fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
    767 {
    768 	m_wrapper->glUniformMatrix3fv(location, count, (glw::GLboolean)transpose, value);
    769 }
    770 
    771 void GLContext::uniformMatrix4fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
    772 {
    773 	m_wrapper->glUniformMatrix4fv(location, count, (glw::GLboolean)transpose, value);
    774 }
    775 deInt32 GLContext::getUniformLocation (deUint32 program, const char *name)
    776 {
    777 	return m_wrapper->glGetUniformLocation(program, name);
    778 }
    779 
    780 void GLContext::lineWidth (float w)
    781 {
    782 	m_wrapper->glLineWidth(w);
    783 }
    784 
    785 void GLContext::drawArrays (deUint32 mode, int first, int count)
    786 {
    787 	m_wrapper->glDrawArrays(mode, first, count);
    788 }
    789 
    790 void GLContext::drawArraysInstanced (deUint32 mode, int first, int count, int instanceCount)
    791 {
    792 	m_wrapper->glDrawArraysInstanced(mode, first, count, instanceCount);
    793 }
    794 
    795 void GLContext::drawElements (deUint32 mode, int count, deUint32 type, const void *indices)
    796 {
    797 	m_wrapper->glDrawElements(mode, count, type, indices);
    798 }
    799 
    800 void GLContext::drawElementsInstanced (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount)
    801 {
    802 	m_wrapper->glDrawElementsInstanced(mode, count, type, indices, instanceCount);
    803 }
    804 
    805 void GLContext::drawElementsBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int baseVertex)
    806 {
    807 	m_wrapper->glDrawElementsBaseVertex(mode, count, type, indices, baseVertex);
    808 }
    809 
    810 void GLContext::drawElementsInstancedBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount, int baseVertex)
    811 {
    812 	m_wrapper->glDrawElementsInstancedBaseVertex(mode, count, type, indices, instanceCount, baseVertex);
    813 }
    814 
    815 void GLContext::drawRangeElements (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices)
    816 {
    817 	m_wrapper->glDrawRangeElements(mode, start, end, count, type, indices);
    818 }
    819 
    820 void GLContext::drawRangeElementsBaseVertex (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices, int baseVertex)
    821 {
    822 	m_wrapper->glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, baseVertex);
    823 }
    824 
    825 void GLContext::drawArraysIndirect (deUint32 mode, const void *indirect)
    826 {
    827 	m_wrapper->glDrawArraysIndirect(mode, indirect);
    828 }
    829 
    830 void GLContext::drawElementsIndirect (deUint32 mode, deUint32 type, const void *indirect)
    831 {
    832 	m_wrapper->glDrawElementsIndirect(mode, type, indirect);
    833 }
    834 
    835 void GLContext::multiDrawArrays (deUint32 mode, const int* first, const int* count, int primCount)
    836 {
    837 	m_wrapper->glMultiDrawArrays(mode, first, count, primCount);
    838 }
    839 
    840 void GLContext::multiDrawElements (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount)
    841 {
    842 	m_wrapper->glMultiDrawElements(mode, count, type, indices, primCount);
    843 }
    844 
    845 void GLContext::multiDrawElementsBaseVertex (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount, const int* baseVertex)
    846 {
    847 	m_wrapper->glMultiDrawElementsBaseVertex(mode, count, type, indices, primCount, baseVertex);
    848 }
    849 
    850 deUint32 GLContext::createProgram (ShaderProgram* shader)
    851 {
    852 	m_programs.reserve(m_programs.size()+1);
    853 
    854 	glu::ShaderProgram* program = DE_NULL;
    855 
    856 	if (!shader->m_hasGeometryShader)
    857 		program = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(shader->m_vertSrc, shader->m_fragSrc));
    858 	else
    859 		program = new glu::ShaderProgram(m_context,
    860 										 glu::ProgramSources() << glu::VertexSource(shader->m_vertSrc)
    861 															   << glu::FragmentSource(shader->m_fragSrc)
    862 															   << glu::GeometrySource(shader->m_geomSrc));
    863 
    864 	if (!program->isOk())
    865 	{
    866 		m_log << *program;
    867 		delete program;
    868 		TCU_FAIL("Compile failed");
    869 	}
    870 
    871 	if ((m_logFlags & GLCONTEXT_LOG_PROGRAMS) != 0)
    872 		m_log << *program;
    873 
    874 	m_programs.push_back(program);
    875 	return program->getProgram();
    876 }
    877 
    878 void GLContext::deleteProgram (deUint32 program)
    879 {
    880 	for (std::vector<glu::ShaderProgram*>::iterator i = m_programs.begin(); i != m_programs.end(); i++)
    881 	{
    882 		if ((*i)->getProgram() == program)
    883 		{
    884 			delete *i;
    885 			m_programs.erase(i);
    886 			return;
    887 		}
    888 	}
    889 
    890 	DE_FATAL("invalid delete");
    891 }
    892 
    893 void GLContext::useProgram (deUint32 program)
    894 {
    895 	m_wrapper->glUseProgram(program);
    896 }
    897 
    898 void GLContext::readPixels (int x, int y, int width, int height, deUint32 format, deUint32 type, void* data)
    899 {
    900 	// Don't log offset.
    901 	if ((m_logFlags & GLCONTEXT_LOG_CALLS) != 0)
    902 		m_log << TestLog::Message << "glReadPixels("
    903 								  << x << ", " << y << ", " << width << ", " << height << ", "
    904 								  << glu::getTextureFormatStr(format) << ", "
    905 								  << glu::getTypeStr(type) << ", " << data << ")"
    906 			  << TestLog::EndMessage;
    907 
    908 	tcu::IVec2 offset = getReadOffset();
    909 	m_context.getFunctions().readPixels(x+offset.x(), y+offset.y(), width, height, format, type, data);
    910 }
    911 
    912 deUint32 GLContext::getError (void)
    913 {
    914 	return m_wrapper->glGetError();
    915 }
    916 
    917 void GLContext::finish (void)
    918 {
    919 	m_wrapper->glFinish();
    920 }
    921 
    922 void GLContext::getIntegerv (deUint32 pname, int* params)
    923 {
    924 	m_wrapper->glGetIntegerv(pname, params);
    925 }
    926 
    927 const char* GLContext::getString (deUint32 pname)
    928 {
    929 	return (const char*)m_wrapper->glGetString(pname);
    930 }
    931 
    932 } // sglr
    933