148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*-------------------------------------------------------------------------
248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite
348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * -----------------------------
448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2015-2016 The Khronos Group Inc.
648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License.
948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at
1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software
1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and
1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License.
1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
1984322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*!
2048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file
2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief
2284322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/
2348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/**
2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file  gl4cMultiBindTests.cpp
2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief Implements conformance tests for "Multi Bind" functionality.
2784322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/
2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gl4cMultiBindTests.hpp"
3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDefs.hpp"
3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluStrUtil.hpp"
3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp"
3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp"
3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp"
3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <string>
3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define DEBUG_ENBALE_MESSAGE_CALLBACK 0
4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include <iomanip>
4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosusing namespace glw;
4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace gl4cts
4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace MultiBind
5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Debuging procedure. Logs parameters.
5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param source   As specified in GL spec.
5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type     As specified in GL spec.
5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id       As specified in GL spec.
5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param severity As specified in GL spec.
5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param ignored
6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param message  As specified in GL spec.
6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param info     Pointer to instance of deqp::Context used by test.
6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */
6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */,
6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							 const GLchar* message, void* info)
6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context* ctx = (deqp::Context*)info;
6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar* source_str   = "Unknown";
6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar* type_str	 = "Unknown";
7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar* severity_str = "Unknown";
7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (source)
7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_API:
7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "API";
7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_APPLICATION:
7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "APP";
7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_OTHER:
8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "OTR";
8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_SHADER_COMPILER:
8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "COM";
8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_THIRD_PARTY:
8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "3RD";
8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		source_str = "WS";
9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (type)
9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "DEPRECATED_BEHAVIOR";
10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_ERROR:
10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "ERROR";
10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_MARKER:
10548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "MARKER";
10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_OTHER:
10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "OTHER";
10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_PERFORMANCE:
11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "PERFORMANCE";
11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_POP_GROUP:
11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "POP_GROUP";
11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_PORTABILITY:
11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "PORTABILITY";
11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_PUSH_GROUP:
12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "PUSH_GROUP";
12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		type_str = "UNDEFINED_BEHAVIOR";
12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (severity)
13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SEVERITY_HIGH:
13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		severity_str = "H";
13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SEVERITY_LOW:
13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		severity_str = "L";
13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SEVERITY_MEDIUM:
13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		severity_str = "M";
13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_DEBUG_SEVERITY_NOTIFICATION:
14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		severity_str = "N";
14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								   << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								   << ": " << message << tcu::TestLog::EndMessage;
15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Represents buffer instance
15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Provides basic buffer functionality
15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass Buffer
15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic:
16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public methods */
16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Ctr & Dtr */
16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer();
16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	~Buffer();
16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Init & Release */
16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Init(deqp::Context& context);
16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void InitData(deqp::Context& context, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size,
16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  const glw::GLvoid* data);
17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Release();
17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Bind() const;
17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void BindBase(glw::GLuint index) const;
17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public static routines */
17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target);
18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index);
18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size,
18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 const glw::GLvoid* data);
18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size,
18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						glw::GLvoid* data);
19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public fields */
19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint m_id;
19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public constants */
19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const glw::GLuint m_invalid_id;
19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosprivate:
19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private enums */
19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private fields */
20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context* m_context;
20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLenum	m_target;
20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Represents framebuffer
20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Provides basic functionality
20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass Framebuffer
20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic:
21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public methods */
21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Ctr & Dtr */
21348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Framebuffer(deqp::Context& context);
21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	~Framebuffer();
21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Init & Release */
21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Release();
21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public static routines */
22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment,
22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height);
22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id);
22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public fields */
22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint m_id;
22948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public constants */
23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const glw::GLuint m_invalid_id;
23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosprivate:
23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private fields */
23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context& m_context;
23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Represents shader instance.
23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Provides basic functionality for shaders.
24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass Shader
24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic:
24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public methods */
24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Ctr & Dtr */
24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader(deqp::Context& context);
24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	~Shader();
24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Init & Realese */
25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Init(glw::GLenum stage, const std::string& source);
25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Release();
25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public static routines */
25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Compile(const glw::Functions& gl, glw::GLuint id);
25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id);
25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source);
26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public fields */
26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint m_id;
26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public constants */
26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const glw::GLuint m_invalid_id;
26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosprivate:
26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private fields */
26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context& m_context;
27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Represents program instance.
27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Provides basic functionality
27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass Program
27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic:
27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public methods */
27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Ctr & Dtr */
28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program(deqp::Context& context);
28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	~Program();
28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Init & Release */
28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader,
28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			  const std::string& tesselation_control_shader, const std::string& tesselation_evaluation_shader,
28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			  const std::string& vertex_shader);
28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Release();
28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Use() const;
29148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public static routines */
29348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
29448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id);
29548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Create(const glw::Functions& gl, glw::GLuint& out_id);
29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Link(const glw::Functions& gl, glw::GLuint id);
29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Use(const glw::Functions& gl, glw::GLuint id);
30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public fields */
30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint m_id;
30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_compute;
30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_fragment;
30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_geometry;
30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_tess_ctrl;
30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_tess_eval;
31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Shader m_vertex;
31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public constants */
31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const glw::GLuint m_invalid_id;
31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosprivate:
31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private fields */
31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context& m_context;
31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Represents texture instance
32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosclass Texture
32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulospublic:
32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public methods */
32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Ctr & Dtr */
32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture();
32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	~Texture();
32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Init & Release */
33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Init(deqp::Context& context);
33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void InitBuffer(deqp::Context& context, glw::GLenum internal_format, glw::GLuint buffer_id);
33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void InitStorage(deqp::Context& context, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format,
33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error = false);
33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	void Release();
33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public static routines */
34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Functionality */
34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target);
34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level,
34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth,
34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								glw::GLsizei image_size, const glw::GLvoid* data);
34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format,
35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						glw::GLenum type, glw::GLvoid* out_data);
35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname,
35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								  glw::GLint* param);
35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format,
35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type,
35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  const glw::GLvoid* data);
35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format,
36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error);
36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static void SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y,
36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format,
36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						 glw::GLenum type, const glw::GLvoid* pixels);
36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public fields */
36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	glw::GLuint m_id;
36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Public constants */
37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const glw::GLuint m_invalid_id;
37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosprivate:
37448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Private fields */
37548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	deqp::Context* m_context;
37648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Buffer constants */
37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint Buffer::m_invalid_id = -1;
38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
38248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
38448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosBuffer::Buffer() : m_id(m_invalid_id), m_context(0), m_target(GL_ARRAY_BUFFER)
38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor
38948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
39048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
39148087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosBuffer::~Buffer()
39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context = 0;
39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize buffer instance
39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Init(deqp::Context& context)
40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
40448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
40548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
40648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context = &context;
40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize buffer instance with some data
41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Buffer target
41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param usage  Buffer usage enum
41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param size   <size> parameter
41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data   <data> parameter
41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::InitData(deqp::Context& context, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size,
41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  const glw::GLvoid* data)
41948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
42048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Init(context);
42148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_target = target;
42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context->getRenderContext().getFunctions();
42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Generate(gl, m_id);
42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Bind(gl, m_id, m_target);
42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Data(gl, m_target, usage, size, data);
42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Release buffer instance
43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
43448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Release()
43548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
43648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id != m_id)
43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const Functions& gl = m_context->getRenderContext().getFunctions();
43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteBuffers(1, &m_id);
44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_id = m_invalid_id;
44248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Binds buffer to its target
44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Bind() const
44948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
45048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == m_id)
45148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return;
45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context->getRenderContext().getFunctions();
45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Bind(gl, m_id, m_target);
45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Binds indexed buffer
46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index <index> parameter
46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::BindBase(glw::GLuint index) const
46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == m_id)
46748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return;
46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context->getRenderContext().getFunctions();
47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	BindBase(gl, m_id, m_target, index);
47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Bind buffer to given target
47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id     Id of buffer
48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Buffer target
48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target)
48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBuffer(target, id);
48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Binds indexed buffer
48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id     Id of buffer
49248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Buffer target
49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index  <index> parameter
49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index)
49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBufferBase(target, index, id);
49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Allocate memory for buffer and sends initial content
50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Buffer target
50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param usage  Buffer usage enum
50648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param size   <size> parameter
50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data   <data> parameter
50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size,
51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  const glw::GLvoid* data)
51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bufferData(target, size, data, usage);
51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData");
51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
51548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
51648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate buffer
51748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_id Id of buffer
52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::Generate(const glw::Functions& gl, glw::GLuint& out_id)
52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint id = m_invalid_id;
52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genBuffers(1, &id);
52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == id)
52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Got invalid id");
53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	out_id = id;
53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Update range of buffer
53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Buffer target
54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param offset Offset in buffer
54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param size   <size> parameter
54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data   <data> parameter
54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Buffer::SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size,
54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					 glw::GLvoid* data)
54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bufferSubData(target, offset, size, data);
54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData");
54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Framebuffer constants */
55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint Framebuffer::m_invalid_id = -1;
55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
55848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFramebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to done here */
56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor
56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
56648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFramebuffer::~Framebuffer()
56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Release texture instance
57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Framebuffer::Release()
57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id != m_id)
57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const Functions& gl = m_context.getRenderContext().getFunctions();
57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteFramebuffers(1, &m_id);
58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_id = m_invalid_id;
58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Attach texture to specified attachment
58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl         GL functions
58848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target     Framebuffer target
58948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param attachment Attachment
59048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture_id Texture id
59148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param level      Level of mipmap
59248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width      Texture width
59348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height     Texture height
59448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
59548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Framebuffer::AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment,
59648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height)
59748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
59848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.framebufferTexture(target, attachment, texture_id, level);
59948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
60048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
60148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.viewport(0 /* x */, 0 /* y */, width, height);
60248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
60348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
60448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
60548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Binds framebuffer to DRAW_FRAMEBUFFER
60648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
60748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
60848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Framebuffer target
60948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id     ID of framebuffer
61048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
61148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Framebuffer::Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id)
61248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
61348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindFramebuffer(target, id);
61448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
61548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
61648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
61748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate framebuffer
61848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
61948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
62048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Framebuffer::Generate(const glw::Functions& gl, glw::GLuint& out_id)
62148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
62248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint id = m_invalid_id;
62348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
62448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genFramebuffers(1, &id);
62548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
62648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
62748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == id)
62848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
62948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid id");
63048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
63148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
63248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	out_id = id;
63348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
63448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
63548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Program constants */
63648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint Program::m_invalid_id = 0;
63748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
63848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
63948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
64048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
64148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
64248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosProgram::Program(deqp::Context& context)
64348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: m_id(m_invalid_id)
64448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_compute(context)
64548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_fragment(context)
64648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_geometry(context)
64748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_tess_ctrl(context)
64848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_tess_eval(context)
64948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_vertex(context)
65048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	, m_context(context)
65148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
65248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done here */
65348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
65448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
65548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor
65648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
65748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
65848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosProgram::~Program()
65948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
66048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
66148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
66248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
66348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize program instance
66448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
66548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param compute_shader                Compute shader source code
66648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param fragment_shader               Fragment shader source code
66748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param geometry_shader               Geometry shader source code
66848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tesselation_control_shader    Tesselation control shader source code
66948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tesselation_evaluation_shader Tesselation evaluation shader source code
67048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param vertex_shader                 Vertex shader source code
67148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
67248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Init(const std::string& compute_shader, const std::string& fragment_shader,
67348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				   const std::string& geometry_shader, const std::string& tesselation_control_shader,
67448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				   const std::string& tesselation_evaluation_shader, const std::string& vertex_shader)
67548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
67648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Delete previous program */
67748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
67848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
67948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* GL entry points */
68048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
68148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
68248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Initialize shaders */
68348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_compute.Init(GL_COMPUTE_SHADER, compute_shader);
68448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_fragment.Init(GL_FRAGMENT_SHADER, fragment_shader);
68548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_geometry.Init(GL_GEOMETRY_SHADER, geometry_shader);
68648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_tess_ctrl.Init(GL_TESS_CONTROL_SHADER, tesselation_control_shader);
68748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_tess_eval.Init(GL_TESS_EVALUATION_SHADER, tesselation_evaluation_shader);
68848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_vertex.Init(GL_VERTEX_SHADER, vertex_shader);
68948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
69048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Create program, set up transform feedback and attach shaders */
69148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Create(gl, m_id);
69248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_compute.m_id);
69348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_fragment.m_id);
69448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_geometry.m_id);
69548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_tess_ctrl.m_id);
69648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_tess_eval.m_id);
69748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Attach(gl, m_id, m_vertex.m_id);
69848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
69948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Link program */
70048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Link(gl, m_id);
70148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
70248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
70348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Release program instance
70448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
70548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
70648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Release()
70748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
70848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
70948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
71048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id != m_id)
71148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
71248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Use(gl, m_invalid_id);
71348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
71448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteProgram(m_id);
71548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_id = m_invalid_id;
71648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
71748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
71848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_compute.Release();
71948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_fragment.Release();
72048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_geometry.Release();
72148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_tess_ctrl.Release();
72248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_tess_eval.Release();
72348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_vertex.Release();
72448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
72548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
72648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set program as active
72748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
72848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
72948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Use() const
73048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
73148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
73248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
73348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Use(gl, m_id);
73448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
73548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
73648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Attach shader to program
73748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
73848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl         GL functions
73948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param program_id Id of program
74048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param shader_id  Id of shader
74148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
74248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id)
74348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
74448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Sanity checks */
74548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id))
74648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
74748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return;
74848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
74948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
75048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.attachShader(program_id, shader_id);
75148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
75248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
75348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
75448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Create program instance
75548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
75648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
75748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_id Id of program
75848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
75948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Create(const glw::Functions& gl, glw::GLuint& out_id)
76048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
76148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLuint id = gl.createProgram();
76248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
76348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
76448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == id)
76548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
76648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Failed to create program");
76748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
76848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
76948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	out_id = id;
77048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
77148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
77248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Link program
77348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
77448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl GL functions
77548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id Id of program
77648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
77748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Link(const glw::Functions& gl, glw::GLuint id)
77848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
77948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint status = GL_FALSE;
78048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
78148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.linkProgram(id);
78248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
78348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
78448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get link status */
78548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getProgramiv(id, GL_LINK_STATUS, &status);
78648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
78748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
78848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Log link error */
78948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (GL_TRUE != status)
79048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
79148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLint  length = 0;
79248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::string message;
79348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
79448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get error log length */
79548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length);
79648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
79748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
79848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		message.resize(length, 0);
79948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
80048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get error log */
80148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getProgramInfoLog(id, length, 0, &message[0]);
80248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
80348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
80448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL(message.c_str());
80548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
80648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
80748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
80848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Use program
80948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
81048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl GL functions
81148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id Id of program
81248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
81348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Program::Use(const glw::Functions& gl, glw::GLuint id)
81448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
81548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.useProgram(id);
81648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
81748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
81848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
81948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Shader's constants */
82048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint Shader::m_invalid_id = 0;
82148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
82248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
82348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
82448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
82548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
82648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosShader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
82748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
82848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done here */
82948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
83048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
83148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor
83248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
83348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
83448087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosShader::~Shader()
83548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
83648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
83748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
83848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
83948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize shader instance
84048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
84148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param stage  Shader stage
84248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param source Source code
84348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
84448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Shader::Init(glw::GLenum stage, const std::string& source)
84548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
84648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == source.empty())
84748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
84848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* No source == no shader */
84948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return;
85048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
85148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
85248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Delete any previous shader */
85348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
85448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
85548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Create, set source and compile */
85648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
85748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
85848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Create(gl, stage, m_id);
85948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Source(gl, m_id, source);
86048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
86148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Compile(gl, m_id);
86248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
86348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
86448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Release shader instance
86548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
86648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
86748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Shader::Release()
86848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
86948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id != m_id)
87048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
87148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const Functions& gl = m_context.getRenderContext().getFunctions();
87248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
87348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteShader(m_id);
87448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_id = m_invalid_id;
87548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
87648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
87748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
87848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Compile shader
87948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
88048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl GL functions
88148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id Shader id
88248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
88348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Shader::Compile(const glw::Functions& gl, glw::GLuint id)
88448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
88548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint status = GL_FALSE;
88648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
88748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Compile */
88848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.compileShader(id);
88948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
89048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
89148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get compilation status */
89248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getShaderiv(id, GL_COMPILE_STATUS, &status);
89348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
89448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
89548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Log compilation error */
89648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (GL_TRUE != status)
89748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
89848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		glw::GLint  length = 0;
89948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::string message;
90048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
90148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Error log length */
90248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length);
90348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
90448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
90548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare storage */
90648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		message.resize(length, 0);
90748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
90848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get error log */
90948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getShaderInfoLog(id, length, 0, &message[0]);
91048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
91148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
91248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL(message.c_str());
91348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
91448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
91548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
91648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Create shader
91748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
91848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
91948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param stage  Shader stage
92048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_id Shader id
92148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
92248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Shader::Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id)
92348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
92448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLuint id = gl.createShader(stage);
92548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
92648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
92748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == id)
92848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
92948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Failed to create shader");
93048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
93148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
93248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	out_id = id;
93348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
93448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
93548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set shader's source code
93648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
93748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
93848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id     Shader id
93948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param source Shader source code
94048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
94148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Shader::Source(const glw::Functions& gl, glw::GLuint id, const std::string& source)
94248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
94348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar* code = source.c_str();
94448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
94548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */);
94648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
94748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
94848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
94948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Texture static fields */
95048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst GLuint Texture::m_invalid_id = -1;
95148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
95248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
95348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
95448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
95548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosTexture::Texture() : m_id(m_invalid_id), m_context(0)
95648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
95748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to done here */
95848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
95948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
96048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Destructor
96148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
96248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
96348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosTexture::~Texture()
96448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
96548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
96648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
96748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
96848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize texture instance
96948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
97048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
97148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
97248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Init(deqp::Context& context)
97348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
97448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Release();
97548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
97648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context = &context;
97748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
97848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
97948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize texture instance as texture buffer
98048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
98148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context         Test context
98248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Internal format of texture
98348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param buufer_id       ID of buffer that will be used as storage
98448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
98548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::InitBuffer(deqp::Context& context, glw::GLenum internal_format, glw::GLuint buffer_id)
98648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
98748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Init(context);
98848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
98948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context->getRenderContext().getFunctions();
99048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
99148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Generate(gl, m_id);
99248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Bind(gl, m_id, GL_TEXTURE_BUFFER);
99348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer::Bind(gl, buffer_id, GL_TEXTURE_BUFFER);
99448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
99548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id);
99648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer");
99748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
99848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
99948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initialize texture instance with storage
100048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
100148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context         Test context
100248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target          Texture target
100348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param levels          Number of levels
100448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Internal format of texture
100548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width           Width of texture
100648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height          Height of texture
100748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param depth           Depth of texture
100848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
100948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::InitStorage(deqp::Context& context, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format,
101048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error)
101148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
101248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Init(context);
101348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
101448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context->getRenderContext().getFunctions();
101548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
101648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Generate(gl, m_id);
101748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Bind(gl, m_id, target);
101848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Storage(gl, target, levels, internal_format, width, height, depth, allow_error);
101948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
102048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
102148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Release texture instance
102248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
102348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context CTS context.
102448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
102548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Release()
102648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
102748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id != m_id)
102848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
102948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const Functions& gl = m_context->getRenderContext().getFunctions();
103048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteTextures(1, &m_id);
103248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_id = m_invalid_id;
103348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
103448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
103548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
103648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Bind texture to target
103748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
103848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl       GL functions
103948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param id       Id of texture
104048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param tex_type Type of texture
104148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
104248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target)
104348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
104448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTexture(target, id);
104548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
104648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
104748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
104848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set contents of compressed texture
104948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
105048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl              GL functions
105148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target          Texture target
105248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param level           Mipmap level
105348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Format of data
105448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width           Width of texture
105548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height          Height of texture
105648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param depth           Depth of texture
105748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param image_size      Size of data
105848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data            Buffer with image data
105948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
106048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level,
106148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth,
106248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  glw::GLsizei image_size, const glw::GLvoid* data)
106348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
106448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (target)
106548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
106648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D:
106748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage1D(target, level, internal_format, width, 0 /* border */, image_size, data);
106848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage1D");
106948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
107048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D_ARRAY:
107148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D:
107248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_RECTANGLE:
107348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(target, level, internal_format, width, height, 0 /* border */, image_size, data);
107448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D");
107548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
107648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP:
107748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */,
107848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
107948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */,
108048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
108148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */,
108248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
108348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */,
108448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
108548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */,
108648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
108748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */,
108848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								image_size, data);
108948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D");
109048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
109148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_3D:
109248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_ARRAY:
109348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.compressedTexImage3D(target, level, internal_format, width, height, depth, 0 /* border */, image_size, data);
109448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage3D");
109548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
109648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
109748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invliad enum");
109848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
109948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
110048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
110148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
110248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate texture instance
110348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
110448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
110548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_id Id of texture
110648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
110748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Generate(const glw::Functions& gl, glw::GLuint& out_id)
110848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
110948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint id = m_invalid_id;
111048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
111148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genTextures(1, &id);
111248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
111348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
111448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (m_invalid_id == id)
111548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
111648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid id");
111748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
111848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
111948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	out_id = id;
112048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
112148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
112248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get texture data
112348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
112448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl       GL functions
112548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target   Texture target
112648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param format   Format of data
112748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type     Type of data
112848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param out_data Buffer for data
112948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
113048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format,
113148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  glw::GLenum type, glw::GLvoid* out_data)
113248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
113348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getTexImage(target, level, format, type, out_data);
113448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
113548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
113648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
113748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Generate texture instance
113848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
113948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl     GL functions
114048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target Texture target
114148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param level  Mipmap level
114248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname  Parameter to query
114348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param param  Result of query
114448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
114548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname,
114648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos								glw::GLint* param)
114748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
114848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getTexLevelParameteriv(target, level, pname, param);
114948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
115048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
115148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
115248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set contents of texture
115348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
115448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl              GL functions
115548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target          Texture target
115648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param level           Mipmap level
115748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Format of data
115848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width           Width of texture
115948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height          Height of texture
116048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param depth           Depth of texture
116148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param format          Format of data
116248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type            Type of data
116348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param data            Buffer with image data
116448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
116548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format,
116648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type,
116748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					const glw::GLvoid* data)
116848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
116948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (target)
117048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
117148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D:
117248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage1D(target, level, internal_format, width, 0 /* border */, format, type, data);
117348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage1D");
117448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
117548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D_ARRAY:
117648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D:
117748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_RECTANGLE:
117848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(target, level, internal_format, width, height, 0 /* border */, format, type, data);
117948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
118048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
118148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP:
118248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */, format,
118348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
118448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */, format,
118548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
118648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */, format,
118748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
118848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */, format,
118948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
119048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */, format,
119148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
119248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */, format,
119348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  type, data);
119448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
119548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
119648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_3D:
119748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_ARRAY:
119848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texImage3D(target, level, internal_format, width, height, depth, 0 /* border */, format, type, data);
119948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage3D");
120048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
120148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
120248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invliad enum");
120348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
120448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
120548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
120648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
120748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Allocate storage for texture
120848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
120948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl              GL functions
121048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target          Texture target
121148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param levels          Number of levels
121248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param internal_format Internal format of texture
121348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width           Width of texture
121448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height          Height of texture
121548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param depth           Depth of texture
121648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
121748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format,
121848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					  glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error)
121948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
122048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (target)
122148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
122248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D:
122348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage1D(target, levels, internal_format, width);
122448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (!allow_error)
122548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
122648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D");
122748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
122848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
122948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D_ARRAY:
123048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D:
123148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_RECTANGLE:
123248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP:
123348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage2D(target, levels, internal_format, width, height);
123448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (!allow_error)
123548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
123648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
123748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
123848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
123948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_MULTISAMPLE:
124048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage2DMultisample(target, levels, internal_format, width, height, GL_FALSE);
124148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (!allow_error)
124248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
124348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2DMultisample");
124448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
124548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
124648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
124748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage3DMultisample(target, levels, internal_format, width, height, depth, GL_FALSE);
124848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (!allow_error)
124948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
125048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3DMultisample");
125148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
125248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
125348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_3D:
125448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_ARRAY:
125548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP_ARRAY:
125648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage3D(target, levels, internal_format, width, height, depth);
125748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (!allow_error)
125848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
125948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
126048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
126148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
126248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
126348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invliad enum");
126448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
126548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
126648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
126748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
126848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Set contents of texture
126948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
127048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param gl              GL functions
127148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target          Texture target
127248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param level           Mipmap level
127348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param x               X offset
127448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param y               Y offset
127548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param z               Z offset
127648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param width           Width of texture
127748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param height          Height of texture
127848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param depth           Depth of texture
127948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param format          Format of data
128048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param type            Type of data
128148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pixels          Buffer with image data
128248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
128348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid Texture::SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y,
128448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					   glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format,
128548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					   glw::GLenum type, const glw::GLvoid* pixels)
128648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
128748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	switch (target)
128848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
128948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D:
129048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage1D(target, level, x, width, format, type, pixels);
129148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D");
129248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
129348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_1D_ARRAY:
129448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D:
129548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_RECTANGLE:
129648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
129748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
129848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
129948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP:
130048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, x, y, width, height, format, type, pixels);
130148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, x, y, width, height, format, type, pixels);
130248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, x, y, width, height, format, type, pixels);
130348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, x, y, width, height, format, type, pixels);
130448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, x, y, width, height, format, type, pixels);
130548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, x, y, width, height, format, type, pixels);
130648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
130748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
130848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_3D:
130948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_2D_ARRAY:
131048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	case GL_TEXTURE_CUBE_MAP_ARRAY:
131148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels);
131248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
131348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
131448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	default:
131548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invliad enum");
131648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		break;
131748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
131848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
131948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
132048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Gather info about buffer target */
132148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstruct bufferTargetInfo
132248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
132348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum m_target;
132448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum m_pname_alignment;
132548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum m_pname_binding;
132648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum m_pname_max;
132748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum m_pname_max_size;
132848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
132948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
133048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Gather info about texture target */
133148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstruct textureTargetInfo
133248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
133348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum		  m_target;
133448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLenum		  m_pname_binding;
133548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar* m_name;
133648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
133748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
133848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Collects information about buffers */
133948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic const bufferTargetInfo s_buffer_infos[] = {
134048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_ATOMIC_COUNTER_BUFFER, 0, GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
134148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	  GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE },
134248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
134348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GL_TRANSFORM_FEEDBACK_BUFFER, 0, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_BUFFERS,
134448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
134548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	},
134648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_UNIFORM_BUFFER, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS,
134748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	  GL_MAX_UNIFORM_BLOCK_SIZE },
134848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_SHADER_STORAGE_BUFFER, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, GL_SHADER_STORAGE_BUFFER_BINDING,
134948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	  GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_SHADER_STORAGE_BLOCK_SIZE },
135048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
135148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
135248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic const size_t s_n_buffer_tragets = sizeof(s_buffer_infos) / sizeof(s_buffer_infos[0]);
135348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
135448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Collects information about textures */
135548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic const textureTargetInfo s_texture_infos[] = {
135648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1D" },
135748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1D_ARRAY" },
135848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2D" },
135948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2D_ARRAY" },
136048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D, "3D" },
136148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_BUFFER, GL_TEXTURE_BINDING_BUFFER, "BUFFER" },
136248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP, "CUBE" },
136348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, "CUBE_ARRAY" },
136448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE, "RECTANGLE" },
136548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BINDING_2D_MULTISAMPLE, "2D_MS" },
136648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{ GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, "2D_MS_ARRAY" }
136748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos};
136848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
136948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosstatic const size_t s_n_texture_tragets = sizeof(s_texture_infos) / sizeof(s_texture_infos[0]);
137048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
137148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Macro, verifies generated error, logs error message and throws failure
137248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
137348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_error Expected error value
137448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param error_message  Message logged if generated error is not the expected one
137548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
137648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#define CHECK_ERROR(expected_error, error_message)                                                      \
137748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{                                                                                                   \
137848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLenum generated_error = gl.getError();                                                         \
137948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos                                                                                                        \
138048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (expected_error != generated_error)                                                          \
138148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{                                                                                               \
138248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			m_context.getTestContext().getLog()                                                         \
138348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				<< tcu::TestLog::Message << "File: " << __FILE__ << ", line: " << __LINE__              \
138448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				<< ". Got wrong error: " << glu::getErrorStr(generated_error)                           \
138548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				<< ", expected: " << glu::getErrorStr(expected_error) << ", message: " << error_message \
138648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				<< tcu::TestLog::EndMessage;                                                            \
138748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Invalid error generated");                                                        \
138848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}                                                                                               \
138948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
139048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
139148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Prototypes */
139248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string);
139348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
139448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Checks binding
139548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
139648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context        Test contex
139748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname          Pname of binding
139848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index          Index of binding
139948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param target_name    Name of target
140048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_value Expected value of binding
140148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
140248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid checkBinding(deqp::Context& context, GLenum pname, GLuint index, const std::string& target_name,
140348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				  GLint expected_value)
140448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
140548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = context.getRenderContext().getFunctions();
140648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
140748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint binding = -1;
140848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
140948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegeri_v(pname, index, &binding);
141048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegeri_v");
141148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
141248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (binding != expected_value)
141348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
141448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding
141548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										  << ", expected: " << expected_value << ". Target: " << target_name
141648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										  << " at index: " << index << tcu::TestLog::EndMessage;
141748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid binding");
141848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
141948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
142048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
142148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Checks bindings for given texture unit
142248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
142348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context        Test contex
142448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param pname          Binding pname of <expected_value>
142548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index          Index of texture unit
142648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_value Expected value of binding at <pname> target
142748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
142848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid checkTextureBinding(deqp::Context& context, GLenum pname, GLuint index, GLint expected_value)
142948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
143048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = context.getRenderContext().getFunctions();
143148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
143248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < s_n_texture_tragets; ++i)
143348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
143448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum  pname_binding = s_texture_infos[i].m_pname_binding;
143548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* target_name   = s_texture_infos[i].m_name;
143648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
143748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint binding = -1;
143848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint value   = 0;
143948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
144048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegeri_v(pname_binding, index, &binding);
144148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegeri_v");
144248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
144348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (pname_binding == pname)
144448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
144548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			value = (GLint)expected_value;
144648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
144748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
144848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (binding != value)
144948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
145048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding
145148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  << ", expected: " << expected_value << ". Target: " << target_name
145248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos											  << " at index: " << index << tcu::TestLog::EndMessage;
145348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			TCU_FAIL("Invalid binding");
145448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
145548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
145648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
145748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
145848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Checks binding
145948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
146048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context        Test context
146148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index          Index of binding
146248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param expected_value Expected value of binding
146348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
146448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid checkVertexAttribBinding(deqp::Context& context, GLuint index, GLint expected_value)
146548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
146648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = context.getRenderContext().getFunctions();
146748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
146848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint binding = -1;
146948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
147048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &binding);
147148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetVertexAttribiv");
147248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
147348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (binding != expected_value)
147448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
147548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding
147648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										  << ", expected: " << expected_value << ". Target: Vertex attribute"
147748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										  << " at index: " << index << tcu::TestLog::EndMessage;
147848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid binding");
147948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
148048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
148148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
148248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Fills MS texture with specified value
148348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
148448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context        Test context
148548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param texture_id     Index of binding
148648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param value          Value for texture
148748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param is_array       Selects if array target should be used
148848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
148948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid fillMSTexture(deqp::Context& context, GLuint texture_id, GLuint value, bool is_array)
149048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
149148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
149248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 430 core\n"
149348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
149448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
149548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
149648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (location = 0) writeonly uniform IMAGE uni_image;\n"
149748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
149848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (location = 1) uniform uint uni_value;\n"
149948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
150048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
150148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
150248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    const POINT;\n"
150348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
150448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    imageStore(uni_image, point, 0, uvec4(uni_value, 0, 0, 0));\n"
150548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
150648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
150748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
150848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* array_image   = "uimage2DMSArray";
150948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* array_point   = "ivec3 point = ivec3(gl_WorkGroupID.x, gl_WorkGroupID.y, 0)";
151048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* regular_image = "uimage2DMS";
151148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* regular_point = "ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y)";
151248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
151348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
151448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl		  = context.getRenderContext().getFunctions();
151548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar*	image	= (true == is_array) ? array_image : regular_image;
151648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLchar*	point	= (true == is_array) ? array_point : regular_point;
151748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t			 position = 0;
151848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::string		 source   = cs;
151948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
152048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
152148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("IMAGE", position, image, source);
152248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("POINT", position, point, source);
152348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
152448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
152548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(context);
152648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(source.c_str(), "", "", "", "", "");
152748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
152848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
152948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
153048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == is_array)
153148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
153248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_TRUE /* layered */, 0 /* layer */,
153348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							GL_WRITE_ONLY, GL_R32UI);
153448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
153548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
153648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
153748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
153848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							GL_WRITE_ONLY, GL_R32UI);
153948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
154048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
154148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
154248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
154348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.uniform1i(0 /* location */, 0 /* image unit*/);
154448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
154548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
154648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.uniform1ui(1 /* location */, value /* uni_value */);
154748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1ui");
154848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
154948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
155048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(6, 6, 1);
155148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
155248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
155348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
155448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get texture binding pname for given index
155548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
155648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index Index of texture target
155748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
155848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Pname
155948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
156048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLenum getBinding(GLuint index)
156148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
156248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (index < s_n_texture_tragets)
156348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
156448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return s_texture_infos[index].m_pname_binding;
156548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
156648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
156748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
156848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return GL_TEXTURE_BINDING_2D;
156948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
157048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
157148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
157248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Get texture target for given index
157348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
157448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param index Index of texture target
157548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
157648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return Target
157748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
157848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGLenum getTarget(GLuint index)
157948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
158048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (index < s_n_texture_tragets)
158148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
158248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return s_texture_infos[index].m_target;
158348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
158448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
158548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
158648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		return GL_TEXTURE_2D;
158748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
158848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
158948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
159048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
159148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
159248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param token           Token string
159348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param search_position Position at which find will start, it is updated to position at which replaced text ends
159448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param text            String that will be used as replacement for <token>
159548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param string          String to work on
159648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
159748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
159848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
159948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const size_t text_length	= strlen(text);
160048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const size_t token_length   = strlen(token);
160148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const size_t token_position = string.find(token, search_position);
160248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
160348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	string.replace(token_position, token_length, text, text_length);
160448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
160548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	search_position = token_position + text_length;
160648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
160748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
160848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
160948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
161048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
161148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
161248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosErrorsBindBuffersTest::ErrorsBindBuffersTest(deqp::Context& context)
161348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "errors_bind_buffers", "Verifies that proper errors are generated by buffer binding routines")
161448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
161548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
161648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
161748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
161848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
161948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
162048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
162148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
162248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult ErrorsBindBuffersTest::iterate()
162348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
162448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
162548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
162648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
162748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
162848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
162948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
163048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
163148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_ENUM when <target> is not valid; */
163248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
163348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLintptr buffer_size = 16;
163448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLsizei  count		  = 1;
163548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLuint   first		  = 0;
163648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLintptr offset	  = 4;
163748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLintptr size		  = buffer_size - offset;
163848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
163948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Buffer buffer;
164048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
164148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer.InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
164248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
164348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(GL_ARRAY_BUFFER, first, count, &buffer.m_id);
164448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_ENUM, "BindBuffersBase with invalid <target>");
164548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
164648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(GL_ARRAY_BUFFER, first, count, &buffer.m_id, &offset, &size);
164748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_ENUM, "BindBuffersRange with invalid <target>");
164848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
164948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
165048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < s_n_buffer_tragets; ++i)
165148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
165248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		static const GLsizei n_buffers = 4;
165348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
165448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_alignment = s_buffer_infos[i].m_pname_alignment;
165548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_max	   = s_buffer_infos[i].m_pname_max;
165648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   target		   = s_buffer_infos[i].m_target;
165748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const std::string& target_name	 = glu::getBufferTargetStr(target).toString();
165848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
165948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr buffer_size	  = 16;
166048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLsizei  count			  = n_buffers;
166148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint   first			  = 0;
166248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint   invalid_id		  = 1; /* Start with 1, as 0 is not valid name */
166348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr offset			  = 4; /* ATOMIC and XFB require alignment of 4 */
166448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint	offset_alignment = 1;
166548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint	max_buffers	  = 0;
166648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr size			  = buffer_size - offset;
166748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t   validated_index  = n_buffers - 1;
166848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
166948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get alignment */
167048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (0 != pname_alignment)
167148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
167248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.getIntegerv(pname_alignment, &offset_alignment);
167348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
167448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
167548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer_size += offset_alignment;
167648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			offset = offset_alignment;
167748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			size   = buffer_size - offset;
167848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
167948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
168048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get max */
168148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegerv(pname_max, &max_buffers);
168248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
168348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
168448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Select count so <first + count> does not exceed max.
168548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * Validated index shall be in the specified range.
168648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
168748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (n_buffers > max_buffers)
168848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
168948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			count			= max_buffers;
169048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			validated_index = max_buffers - 1;
169148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
169248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
169348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Storage */
169448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Buffer   buffer[n_buffers];
169548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint   buffer_ids[n_buffers];
169648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr offsets[n_buffers];
169748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr sizes[n_buffers];
169848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
169948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare buffers */
170048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (size_t j = 0; j < n_buffers; ++j)
170148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
170248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
170348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
170448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer_ids[j] = buffer[j].m_id;
170548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			offsets[j]	= offset;
170648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sizes[j]	  = size;
170748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
170848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
170948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION when <first> + <count> is greater than allowed limit; */
171048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
171148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLsizei t_count = n_buffers;
171248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint  t_first = 0;
171348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
171448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Select first so <first + count> exceeds max, avoid negative first */
171548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (n_buffers <= max_buffers)
171648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
171748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_first = max_buffers - n_buffers + 1;
171848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
171948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			else
172048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
172148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_count = max_buffers + 1;
172248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				/* first = 0; */
172348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
172448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
172548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
172648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersBase(target, t_first, t_count, buffer_ids);
172748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION,
172848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						"BindBuffersBase with invalid <first> + <count>, target: " << target_name);
172948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
173048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersRange(target, t_first, t_count, buffer_ids, offsets, sizes);
173148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION,
173248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						"BindBuffersRange with invalid <first> + <count>, target: " << target_name);
173348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
173448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
173548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION if any value in <buffers> is not zero or the name of
173648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * existing buffer;
173748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
173848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
173948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint t_buffer_ids[n_buffers];
174048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
174148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_buffer_ids, buffer_ids, sizeof(buffer_ids));
174248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
174348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Find invalid id */
174448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			while (1)
174548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
174648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (GL_TRUE != gl.isBuffer(invalid_id))
174748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
174848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					break;
174948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				}
175048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
175148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				invalid_id += 1;
175248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
175348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
175448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
175548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_buffer_ids[validated_index] = invalid_id;
175648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
175748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
175848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersBase(target, first, count, t_buffer_ids);
175948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersBase with invalid buffer id, target: " << target_name);
176048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
176148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersRange(target, first, count, t_buffer_ids, offsets, sizes);
176248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersRange with invalid buffer id, target: " << target_name);
176348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
176448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
176548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_VALUE if any value in <offsets> is less than zero; */
176648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
176748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLintptr t_offsets[n_buffers];
176848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLintptr t_sizes[n_buffers];
176948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
177048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_offsets, offsets, sizeof(offsets));
177148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_sizes, sizes, sizeof(sizes));
177248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
177348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
177448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_offsets[validated_index] = -1;
177548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_sizes[validated_index]   = -1;
177648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
177748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
177848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersRange(target, first, count, buffer_ids, t_offsets, sizes);
177948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with negative offset, target: " << target_name);
178048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
178148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
178248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersRange(target, first, count, buffer_ids, offsets, t_sizes);
178348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with negative size, target: " << target_name);
178448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
178548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
178648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_VALUE if any pair of <offsets> and <sizes> exceeds limits. */
178748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
178848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLintptr t_offsets[n_buffers];
178948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLintptr t_sizes[n_buffers];
179048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
179148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_offsets, offsets, sizeof(offsets));
179248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_sizes, sizes, sizeof(sizes));
179348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
179448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
179548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_offsets[validated_index] -= 1;	 /* Not aligned by required value */
179648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_sizes[validated_index] = size - 1; /* Not aligned by required value */
179748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
179848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
179948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindBuffersRange(target, first, count, buffer_ids, t_offsets, sizes);
180048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with invalid <offset>, target: " << target_name);
180148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
180248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
180348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRANSFORM_FEEDBACK_BUFFER == target)
180448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
180548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				gl.bindBuffersRange(target, first, count, buffer_ids, offsets, t_sizes);
180648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with invalid <size>, target: " << target_name);
180748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
180848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
180948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
181048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
181148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
181248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
181348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
181448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
181548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
181648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
181748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
181848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
181948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
182048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
182148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
182248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosErrorsBindTexturesTest::ErrorsBindTexturesTest(deqp::Context& context)
182348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "errors_bind_textures", "Verifies that proper errors are generated by texture binding routines")
182448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
182548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
182648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
182748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
182848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
182948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
183048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
183148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
183248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult ErrorsBindTexturesTest::iterate()
183348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
183448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  depth		= 8;
183548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  height		= 8;
183648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei n_textures = 4;
183748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  width		= 8;
183848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
183948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
184048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
184148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
184248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
184348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
184448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
184548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
184648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLsizei count			= n_textures;
184748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  first			= 0;
184848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  invalid_id		= 1; /* Start with 1, as 0 is not valid name */
184948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint   max_textures	= 0;
185048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t  validated_index = n_textures - 1;
185148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
185248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
185348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_textures);
185448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
185548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
185648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Select count so <first + count> does not exceed max.
185748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * Validated index shall be in the specified range.
185848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
185948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (n_textures > max_textures)
186048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
186148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		count			= max_textures;
186248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		validated_index = max_textures - 1;
186348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
186448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
186548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
186648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture texture[n_textures];
186748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  texture_ids[n_textures];
186848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
186948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare textures */
187048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[0].InitStorage(m_context, GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, width, height, depth);
187148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[1].InitStorage(m_context, GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_RGBA8, width, height, depth);
187248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[2].InitStorage(m_context, GL_TEXTURE_1D_ARRAY, 1 /* levels */, GL_RGBA8, width, height, depth);
187348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[3].InitStorage(m_context, GL_TEXTURE_3D, 1 /* levels */, GL_RGBA8, width, height, depth);
187448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
187548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < n_textures; ++i)
187648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
187748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
187848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
187948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
188048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_OPERATION when <first> + <count> exceed limits; */
188148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
188248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLsizei t_count = n_textures;
188348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint  t_first = 0;
188448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
188548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Select first so <first + count> exceeds max, avoid negative first */
188648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (n_textures <= max_textures)
188748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
188848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_first = max_textures - n_textures + 1;
188948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
189048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
189148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
189248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_count = max_textures + 1;
189348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* first = 0; */
189448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
189548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
189648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
189748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindTextures(t_first, t_count, texture_ids);
189848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid <first> + <count>");
189948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
190048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
190148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_OPERATION if any value in <buffers> is not zero or the name of
190248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * existing buffer;
190348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
190448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
190548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint t_texture_ids[n_textures];
190648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
190748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		memcpy(t_texture_ids, texture_ids, sizeof(texture_ids));
190848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
190948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
191048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
191148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
191248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isTexture(invalid_id))
191348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
191448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
191548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
191648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
191748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
191848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
191948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
192048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Invalidate the entry */
192148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[validated_index] = invalid_id;
192248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
192348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
192448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindTextures(first, count, t_texture_ids);
192548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid texture id");
192648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
192748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
192848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
192948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
193048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
193148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
193248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
193348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
193448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
193548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
193648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
193748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
193848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
193948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosErrorsBindSamplersTest::ErrorsBindSamplersTest(deqp::Context& context)
194048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "errors_bind_samplers", "Verifies that proper errors are generated by sampler binding routines")
194148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
194248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
194348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
194448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
194548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
194648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
194748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
194848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
194948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult ErrorsBindSamplersTest::iterate()
195048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
195148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei n_samplers = 4;
195248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
195348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
195448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
195548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
195648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
195748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
195848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
195948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
196048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLsizei count			= n_samplers;
196148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  first			= 0;
196248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  invalid_id		= 1; /* Start with 1, as 0 is not valid name */
196348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint   max_samplers	= 0;
196448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t  validated_index = n_samplers - 1;
196548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
196648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
196748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_samplers);
196848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
196948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
197048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Select count so <first + count> does not exceed max.
197148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * Validated index shall be in the specified range.
197248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
197348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (n_samplers > max_samplers)
197448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
197548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		count			= max_samplers;
197648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		validated_index = max_samplers - 1;
197748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
197848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
197948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
198048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint sampler_ids[n_samplers];
198148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
198248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare samplers */
198348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genSamplers(n_samplers, sampler_ids);
198448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers");
198548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
198648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
198748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
198848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION when <first> + <count> exceed limits; */
198948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
199048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLsizei t_count = n_samplers;
199148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint  t_first = 0;
199248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
199348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Select first so <first + count> exceeds max, avoid negative first */
199448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (n_samplers <= max_samplers)
199548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
199648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_first = max_samplers - n_samplers + 1;
199748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
199848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			else
199948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
200048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_count = max_samplers + 1;
200148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				/* first = 0; */
200248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
200348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
200448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
200548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindSamplers(t_first, t_count, sampler_ids);
200648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid <first> + <count>");
200748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
200848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
200948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION if any value in <buffers> is not zero or the name of
201048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * existing buffer;
201148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
201248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
201348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint t_sampler_ids[n_samplers];
201448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
201548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_sampler_ids, sampler_ids, sizeof(sampler_ids));
201648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
201748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Find invalid id */
201848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			while (1)
201948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
202048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (GL_TRUE != gl.isTexture(invalid_id))
202148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
202248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					break;
202348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				}
202448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
202548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				invalid_id += 1;
202648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
202748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
202848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
202948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_sampler_ids[validated_index] = invalid_id;
203048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
203148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
203248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindTextures(first, count, t_sampler_ids);
203348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid sampler id");
203448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
203548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
203648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
203748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
203848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteSamplers(n_samplers, sampler_ids);
203948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
204048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid error generated");
204148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
204248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
204348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Delete samplers */
204448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteSamplers(n_samplers, sampler_ids);
204548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
204648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
204748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
204848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
204948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
205048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
205148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
205248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
205348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
205448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
205548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
205648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
205748087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosErrorsBindImageTexturesTest::ErrorsBindImageTexturesTest(deqp::Context& context)
205848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "errors_bind_image_textures",
205948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			   "Verifies that proper errors are generated by image binding routines")
206048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
206148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
206248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
206348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
206448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
206548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
206648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
206748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
206848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult ErrorsBindImageTexturesTest::iterate()
206948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
207048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  depth		= 8;
207148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  height		= 8;
207248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei n_textures = 4;
207348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint  width		= 8;
207448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
207548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
207648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
207748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
207848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
207948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
208048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
208148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
208248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLsizei count			= n_textures;
208348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  first			= 0;
208448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  invalid_id		= 1; /* Start with 1, as 0 is not valid name */
208548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint   max_textures	= 0;
208648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t  validated_index = n_textures - 1;
208748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
208848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
208948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_IMAGE_UNITS, &max_textures);
209048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
209148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
209248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Select count so <first + count> does not exceed max.
209348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * Validated index shall be in the specified range.
209448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
209548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (n_textures > max_textures)
209648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
209748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		count			= max_textures;
209848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		validated_index = max_textures - 1;
209948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
210048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
210148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
210248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture texture[n_textures];
210348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint  texture_ids[n_textures];
210448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
210548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare textures */
210648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[0].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth);
210748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[1].InitStorage(m_context, GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, depth);
210848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[2].InitStorage(m_context, GL_TEXTURE_1D_ARRAY, 1, GL_RGBA8, width, height, depth);
210948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture[3].InitStorage(m_context, GL_TEXTURE_3D, 1, GL_RGBA8, width, height, depth);
211048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
211148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < n_textures; ++i)
211248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
211348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
211448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
211548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
211648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_OPERATION when <first> + <count> exceed limits; */
211748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
211848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLsizei t_count = n_textures;
211948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint  t_first = 0;
212048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
212148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Select first so <first + count> exceeds max, avoid negative first */
212248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (n_textures <= max_textures)
212348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
212448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_first = max_textures - n_textures + 1;
212548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
212648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
212748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
212848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_count = max_textures + 1;
212948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* first = 0; */
213048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
213148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
213248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
213348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTextures(t_first, t_count, texture_ids);
213448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid <first> + <count>");
213548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
213648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
213748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_OPERATION if any value in <buffers> is not zero or the name of
213848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * existing buffer;
213948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
214048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
214148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint t_texture_ids[n_textures];
214248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
214348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		memcpy(t_texture_ids, texture_ids, sizeof(texture_ids));
214448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
214548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
214648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
214748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
214848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isTexture(invalid_id))
214948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
215048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
215148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
215248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
215348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
215448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
215548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
215648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Invalidate the entry */
215748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[validated_index] = invalid_id;
215848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
215948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
216048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTextures(first, count, t_texture_ids);
216148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid texture id");
216248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
216348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
216448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_OPERATION if any entry found in <textures> has invalid internal
216548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * format at level 0;
216648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
216748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
216848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint t_texture_ids[n_textures];
216948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
217048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		memcpy(t_texture_ids, texture_ids, sizeof(texture_ids));
217148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
217248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare texture with invalid format */
217348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture t_texture;
217448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture.Init(m_context);
217548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture.Generate(gl, t_texture.m_id);
217648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture.Bind(gl, t_texture.m_id, GL_TEXTURE_2D);
217748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGB9_E5, width, 0);
217848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_VALUE, "texStorage2D has height set to 0");
217948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
218048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Invalidate the entry */
218148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[validated_index] = t_texture.m_id;
218248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
218348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
218448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTextures(first, count, t_texture_ids);
218548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid internal format");
218648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
218748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
218848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - INVALID_VALUE when any entry in <textures> has any of dimensions equal
218948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * to 0 at level 0.
219048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
219148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
219248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint t_texture_ids[n_textures];
219348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
219448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		memcpy(t_texture_ids, texture_ids, sizeof(texture_ids));
219548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
219648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare texture with invalid format */
219748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture t_texture;
219848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture.InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGB9_E5, width, 0, depth, true);
219948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
220048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Invalidate the entry */
220148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[validated_index] = t_texture.m_id;
220248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
220348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Test */
220448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindImageTextures(first, count, t_texture_ids);
220548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_VALUE, "BindImageTextures with 2D texture that has height set to 0");
220648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
220748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
220848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
220948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
221048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
221148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
221248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
221348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
221448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
221548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
221648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
221748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
221848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
221948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosErrorsBindVertexBuffersTest::ErrorsBindVertexBuffersTest(deqp::Context& context)
222048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "errors_bind_vertex_buffers",
222148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			   "Verifies that proper errors are generated by vertex buffer binding routines")
222248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
222348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
222448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
222548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
222648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
222748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
222848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
222948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
223048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult ErrorsBindVertexBuffersTest::iterate()
223148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
223248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
223348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
223448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
223548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
223648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
223748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
223848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
223948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei n_buffers = 4;
224048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei stride	= 4;
224148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
224248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLintptr buffer_size	 = 16;
224348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLsizei  count			 = n_buffers;
224448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint   first			 = 0;
224548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint   invalid_id		 = 1; /* Start with 1, as 0 is not valid name */
224648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLintptr offset			 = 4; /* ATOMIC and XFB require alignment of 4 */
224748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint	max_buffers	 = 0;
224848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t   validated_index = n_buffers - 1;
224948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
225048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
225148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers);
225248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
225348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
225448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Select count so <first + count> does not exceed max.
225548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * Validated index shall be in the specified range.
225648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
225748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (n_buffers > max_buffers)
225848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
225948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		count			= max_buffers;
226048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		validated_index = max_buffers - 1;
226148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
226248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
226348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
226448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer   buffer[n_buffers];
226548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint   buffer_ids[n_buffers];
226648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLintptr offsets[n_buffers];
226748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLsizei  strides[n_buffers];
226848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
226948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffers */
227048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t j = 0; j < n_buffers; ++j)
227148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
227248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer[j].InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
227348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
227448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[j] = buffer[j].m_id;
227548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		offsets[j]	= offset;
227648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		strides[j]	= stride;
227748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
227848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
227948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare VAO */
228048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint vao = 0;
228148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &vao);
228248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
228348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
228448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
228548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexArray(vao);
228648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays");
228748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
228848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION when <first> + <count> exceeds limits; */
228948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
229048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLsizei t_count = n_buffers;
229148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint  t_first = 0;
229248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
229348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Select first so <first + count> exceeds max, avoid negative first */
229448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (n_buffers <= max_buffers)
229548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
229648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_first = max_buffers - n_buffers + 1;
229748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
229848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			else
229948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
230048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				t_count = max_buffers + 1;
230148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				/* first = 0; */
230248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
230348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
230448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
230548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindVertexBuffers(t_first, t_count, buffer_ids, offsets, strides);
230648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid <first> + <count>");
230748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
230848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
230948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_OPERATION if any value in <buffers> is not zero or the name of
231048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * existing buffer;
231148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
231248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
231348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLuint t_buffer_ids[n_buffers];
231448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
231548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_buffer_ids, buffer_ids, sizeof(buffer_ids));
231648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
231748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Find invalid id */
231848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			while (1)
231948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
232048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				if (GL_TRUE != gl.isBuffer(invalid_id))
232148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				{
232248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos					break;
232348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				}
232448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
232548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				invalid_id += 1;
232648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
232748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
232848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
232948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_buffer_ids[validated_index] = invalid_id;
233048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
233148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
233248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindVertexBuffers(first, count, t_buffer_ids, offsets, strides);
233348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid buffer id");
233448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
233548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
233648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - INVALID_VALUE if any value in <offsets> or <strides> is less than zero. */
233748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
233848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLintptr t_offsets[n_buffers];
233948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLsizei  t_strides[n_buffers];
234048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
234148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_offsets, offsets, sizeof(offsets));
234248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			memcpy(t_strides, strides, sizeof(strides));
234348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
234448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Invalidate the entry */
234548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_offsets[validated_index] = -1;
234648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_strides[validated_index] = -1;
234748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
234848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			/* Test */
234948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindVertexBuffers(first, count, buffer_ids, t_offsets, strides);
235048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_VALUE, "BindVertexBuffers with negative offset");
235148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
235248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.bindVertexBuffers(first, count, buffer_ids, offsets, t_strides);
235348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			CHECK_ERROR(GL_INVALID_VALUE, "BindVertexBuffers with negative stride");
235448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
235548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
235648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
235748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
235848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &vao);
235948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Unexpected error generated");
236048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
236148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
236248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteVertexArrays(1, &vao);
236348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays");
236448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
236548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
236648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
236748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
236848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
236948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
237048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
237148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
237248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
237348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
237448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
237548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
237648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindBuffersBaseTest::FunctionalBindBuffersBaseTest(deqp::Context& context)
237748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_buffers_base", "Verifies that BindBuffersBase works as expected")
237848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
237948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
238048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
238148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
238248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
238348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
238448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
238548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
238648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindBuffersBaseTest::iterate()
238748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
238848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
238948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
239048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
239148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
239248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
239348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
239448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
239548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < s_n_buffer_tragets; ++i)
239648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
239748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_binding  = s_buffer_infos[i].m_pname_binding;
239848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_max	  = s_buffer_infos[i].m_pname_max;
239948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_max_size = s_buffer_infos[i].m_pname_max_size;
240048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   target		  = s_buffer_infos[i].m_target;
240148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const std::string& target_name	= glu::getBufferTargetStr(target).toString();
240248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
240348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint max_buffers = 0;
240448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint max_size	= 0;
240548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
240648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get max */
240748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegerv(pname_max, &max_buffers);
240848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
240948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
241048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get max size */
241148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegerv(pname_max_size, &max_size);
241248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
241348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
241448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr buffer_size = max_size / max_buffers;
241548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
241648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Storage */
241748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<Buffer> buffer;
241848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLuint> buffer_ids;
241948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
242048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer.resize(max_buffers);
242148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids.resize(max_buffers);
242248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
242348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare buffers */
242448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
242548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
242648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
242748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
242848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer_ids[j] = buffer[j].m_id;
242948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
243048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
243148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
243248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase to bind all buffers to tested target;
243348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
243448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
243548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0]);
243648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase");
243748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
243848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
243948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
244048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
244148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
244248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
244348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
244448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 *
244548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for first half of bindings with NULL as <buffers>
244648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * to unbind first half of bindings for tested target;
244748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
244848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for second half of bindings with NULL as <buffers>
244948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * to unbind rest of bindings;
245048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
245148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
245248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint half_index = max_buffers / 2;
245348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, half_index /* count */, 0);
245448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase");
245548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
245648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < half_index; ++j)
245748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
245848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, 0);
245948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
246048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
246148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = half_index; j < max_buffers; ++j)
246248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
246348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
246448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
246548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
246648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, half_index /* first */, max_buffers - half_index /* count */, 0);
246748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase");
246848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
246948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
247048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
247148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, 0);
247248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
247348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
247448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
247548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - change <buffers> so first entry is invalid;
247648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase to bind all buffers to tested target; It is
247748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * expected that INVALID_OPERATION will be generated;
247848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if all bindings but first were modified;
247948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
248048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
248148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
248248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint invalid_id = 1;
248348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
248448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
248548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isBuffer(invalid_id))
248648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
248748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
248848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
248948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
249048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
249148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
249248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
249348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[0] = invalid_id;
249448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
249548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0]);
249648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindBufferBase with invalid buffer id");
249748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
249848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Update buffer_ids */
249948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[0] = 0; /* 0 means unbound */
250048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
250148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
250248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
250348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
250448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
250548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
250648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
250748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - bind any buffer to first binding;
250848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for 0 as <first>, 1 as <count> and <buffers> filled
250948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * with zeros to unbind 1st binding for tested target;
251048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
251148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
251248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBufferBase(target, 0, buffer[0].m_id);
251348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
251448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, pname_binding, 0, target_name, buffer[0].m_id);
251548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
251648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLuint> t_buffer_ids;
251748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_buffer_ids.resize(max_buffers);
251848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
251948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, 1 /* count */, &t_buffer_ids[0]);
252048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase");
252148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
252248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
252348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
252448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
252548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
252648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
252748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - unbind all buffers. */
252848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, 0);
252948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
253048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
253148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
253248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
253348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
253448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
253548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
253648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
253748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
253848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
253948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
254048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
254148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
254248087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindBuffersRangeTest::FunctionalBindBuffersRangeTest(deqp::Context& context)
254348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_buffers_range", "Verifies that BindBuffersRange works as expected")
254448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
254548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
254648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
254748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
254848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
254948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
255048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
255148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
255248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindBuffersRangeTest::iterate()
255348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
255448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
255548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
255648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
255748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
255848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
255948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
256048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
256148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < s_n_buffer_tragets; ++i)
256248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
256348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_binding  = s_buffer_infos[i].m_pname_binding;
256448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_max	  = s_buffer_infos[i].m_pname_max;
256548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   pname_max_size = s_buffer_infos[i].m_pname_max_size;
256648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum	   target		  = s_buffer_infos[i].m_target;
256748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const std::string& target_name	= glu::getBufferTargetStr(target).toString();
256848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
256948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint max_buffers = 0;
257048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint max_size	= 0;
257148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
257248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get max */
257348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegerv(pname_max, &max_buffers);
257448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
257548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
257648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Get max size */
257748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.getIntegerv(pname_max_size, &max_size);
257848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
257948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
258048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLintptr buffer_size = max_size / max_buffers;
258148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
258248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Storage */
258348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<Buffer>		buffer;
258448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLuint>		buffer_ids;
258548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLintptr>   offsets;
258648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLsizeiptr> sizes;
258748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
258848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer.resize(max_buffers);
258948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids.resize(max_buffers);
259048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		offsets.resize(max_buffers);
259148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sizes.resize(max_buffers);
259248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
259348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare buffers */
259448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
259548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
259648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
259748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
259848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			buffer_ids[j] = buffer[j].m_id;
259948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			offsets[j]	= 0;
260048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sizes[j]	  = buffer_size;
260148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
260248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
260348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
260448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase to bind all buffers to tested target;
260548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
260648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
260748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0], &offsets[0], &sizes[0]);
260848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange");
260948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
261048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
261148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
261248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
261348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
261448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
261548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
261648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 *
261748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for first half of bindings with NULL as <buffers>
261848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * to unbind first half of bindings for tested target;
261948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
262048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for second half of bindings with NULL as <buffers>
262148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * to unbind rest of bindings;
262248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
262348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
262448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint half_index = max_buffers / 2;
262548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(target, 0 /* first */, half_index /* count */, 0, &offsets[0], &sizes[0]);
262648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange");
262748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
262848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < half_index; ++j)
262948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
263048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, 0);
263148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
263248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
263348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = half_index; j < max_buffers; ++j)
263448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
263548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
263648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
263748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
263848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(target, half_index /* first */, max_buffers - half_index /* count */, 0, &offsets[0],
263948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							&sizes[0]);
264048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange");
264148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
264248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
264348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
264448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, 0);
264548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
264648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
264748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
264848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - change <buffers> so first entry is invalid;
264948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase to bind all buffers to tested target; It is
265048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * expected that INVALID_OPERATION will be generated;
265148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if all bindings but first were modified;
265248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
265348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
265448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
265548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint invalid_id = 1;
265648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
265748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
265848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isBuffer(invalid_id))
265948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
266048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
266148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
266248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
266348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
266448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
266548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
266648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[0] = invalid_id;
266748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
266848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0], &offsets[0], &sizes[0]);
266948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersRange with invalid buffer id");
267048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
267148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Update buffer_ids */
267248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[0] = 0; /* 0 means unbound */
267348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
267448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
267548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
267648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
267748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
267848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
267948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/*
268048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - bind any buffer to first binding;
268148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindBufferBase for 0 as <first>, 1 as <count> and <buffers> filled
268248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * with zeros to unbind 1st binding for tested target;
268348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect if bindings were modified;
268448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
268548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBufferBase(target, 0, buffer[0].m_id);
268648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase");
268748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, pname_binding, 0, target_name, buffer[0].m_id);
268848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
268948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		std::vector<GLuint> t_buffer_ids;
269048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_buffer_ids.resize(max_buffers);
269148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
269248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersRange(target, 0 /* first */, 1 /* count */, &t_buffer_ids[0], &offsets[0], &sizes[0]);
269348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange");
269448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
269548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint j = 0; j < max_buffers; ++j)
269648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
269748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]);
269848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
269948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
270048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - unbind all buffers. */
270148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, 0);
270248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
270348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
270448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
270548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
270648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
270748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
270848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
270948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
271048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
271148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
271248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
271348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
271448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
271548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindTexturesTest::FunctionalBindTexturesTest(deqp::Context& context)
271648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_textures", "Verifies that BindTextures works as expected")
271748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
271848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
271948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
272048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
272148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
272248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
272348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
272448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
272548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindTexturesTest::iterate()
272648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
272748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint depth  = 6;
272848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 6;
272948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 6;
273048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
273148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
273248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
273348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
273448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
273548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
273648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
273748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
273848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint invalid_id   = 1; /* Start with 1, as 0 is not valid name */
273948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint  max_textures = 0;
274048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
274148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
274248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_textures);
274348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
274448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
274548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
274648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				 buffer;
274748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Texture> texture;
274848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  texture_ids;
274948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  t_texture_ids;
275048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
275148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.resize(max_textures);
275248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids.resize(max_textures);
275348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	t_texture_ids.resize(max_textures);
275448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
275548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffer */
275648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, 16 /* size */, 0 /* data */);
275748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
275848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare textures */
275948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < s_n_texture_tragets; ++i)
276048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
276148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum target = s_texture_infos[i].m_target;
276248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
276348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (GL_TEXTURE_BUFFER != target)
276448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
276548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_RGBA8, width, height, depth);
276648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
276748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
276848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
276948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitBuffer(m_context, GL_RGBA8, buffer.m_id);
277048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
277148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
277248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Unbind */
277348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::Bind(gl, 0, target);
277448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
277548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
277648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = s_n_texture_tragets; i < max_textures; ++i)
277748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
277848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth);
277948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
278048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
278148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Unbind */
278248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::Bind(gl, 0, GL_TEXTURE_2D);
278348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
278448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
278548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
278648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
278748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
278848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
278948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
279048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures to bind all textures;
279148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
279248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * set;
279348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
279448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0, max_textures, &texture_ids[0]);
279548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
279648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
279748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
279848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
279948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]);
280048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
280148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
280248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
280348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures for the first half of units with <textures> filled
280448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * with zeros, to unbind those units;
280548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
280648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * unbound;
280748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
280848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint half_index = max_textures / 2;
280948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
281048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
281148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
281248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[i] = 0;
281348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
281448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
281548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0, half_index, &t_texture_ids[0]);
281648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
281748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
281848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < half_index; ++i)
281948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
282048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkTextureBinding(m_context, getBinding(i), i, 0);
282148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
282248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
282348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = half_index; i < max_textures; ++i)
282448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
282548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]);
282648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
282748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
282848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
282948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures for the second half of units with NULL as<textures>,
283048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * to unbind those units;
283148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
283248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * unbound;
283348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
283448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(half_index, max_textures - half_index, 0);
283548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
283648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
283748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
283848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
283948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkTextureBinding(m_context, getBinding(i), i, 0);
284048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
284148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
284248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
284348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - modify <textures> so first entry is invalid;
284448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures to bind all textures; It is expected that
284548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * INVALID_OPERATION will be generated;
284648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
284748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * set;
284848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
284948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
285048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Find invalid id */
285148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	while (1)
285248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
285348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (GL_TRUE != gl.isTexture(invalid_id))
285448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
285548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
285648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
285748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
285848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		invalid_id += 1;
285948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
286048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
286148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set invalid id */
286248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids[0] = invalid_id;
286348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
286448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0, max_textures, &texture_ids[0]);
286548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid texture id");
286648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
286748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	checkTextureBinding(m_context, getBinding(0), 0, 0);
286848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 1; i < max_textures; ++i)
286948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
287048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]);
287148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
287248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
287348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - unbind all textures. */
287448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0, max_textures, 0);
287548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
287648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
287748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
287848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
287948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
288048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
288148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
288248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
288348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
288448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
288548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
288648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
288748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
288848087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindSamplersTest::FunctionalBindSamplersTest(deqp::Context& context)
288948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_samplers", "Verifies that BindSamplers works as expected")
289048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
289148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
289248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
289348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
289448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
289548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
289648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
289748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
289848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindSamplersTest::iterate()
289948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
290048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
290148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
290248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
290348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
290448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
290548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
290648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
290748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint invalid_id   = 1; /* Start with 1, as 0 is not valid name */
290848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint  max_samplers = 0;
290948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
291048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
291148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_samplers);
291248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
291348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
291448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
291548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint> sampler_ids;
291648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint> t_sampler_ids;
291748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
291848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	sampler_ids.resize(max_samplers);
291948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	t_sampler_ids.resize(max_samplers);
292048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
292148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_samplers; ++i)
292248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
292348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_sampler_ids[i] = 0;
292448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
292548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
292648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare samplers */
292748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genSamplers(max_samplers, &sampler_ids[0]);
292848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers");
292948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
293048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
293148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
293248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindSamplers to bind all samplers;
293348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper samplers were set;
293448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
293548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(0 /* first */, max_samplers /* count */, &sampler_ids[0]);
293648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers");
293748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
293848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_samplers; ++i)
293948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
294048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", sampler_ids[i]);
294148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
294248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
294348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindSamplers for first half of bindings with <samplers> filled
294448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * with zeros, to unbind those samplers;
294548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper samplers were unbound;
294648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
294748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint half_index = max_samplers / 2;
294848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
294948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(0, half_index, &t_sampler_ids[0]);
295048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers");
295148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
295248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < half_index; ++i)
295348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
295448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", 0);
295548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
295648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
295748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = half_index; i < max_samplers; ++i)
295848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
295948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", sampler_ids[i]);
296048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
296148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
296248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindSamplers for second half of bindings with NULL as <samplers>,
296348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * to unbind those samplers;
296448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper samplers were unbound;
296548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
296648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(half_index, max_samplers - half_index, 0);
296748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers");
296848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
296948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_samplers; ++i)
297048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
297148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", 0);
297248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
297348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
297448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - modify <samplers> so first entry is invalid;
297548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindSamplers to bind all samplers; It is expected that
297648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * INVALID_OPERATION will be generated;
297748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper samplers were set;
297848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
297948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
298048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
298148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
298248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
298348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isSampler(invalid_id))
298448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
298548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
298648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
298748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
298848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
298948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
299048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
299148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Prepare ids */
299248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_sampler_ids[0] = invalid_id;
299348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
299448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 1; i < max_samplers; ++i)
299548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
299648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			t_sampler_ids[i] = sampler_ids[i];
299748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
299848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
299948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Bind */
300048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(0, max_samplers, &t_sampler_ids[0]);
300148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid sampler id");
300248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
300348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Set 0 for invalid entry */
300448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_sampler_ids[0] = 0;
300548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
300648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_samplers; ++i)
300748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
300848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", t_sampler_ids[i]);
300948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
301048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
301148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - unbind all samplers. */
301248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(0, max_samplers, 0);
301348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers");
301448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
301548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
301648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
301748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteSamplers(max_samplers, &sampler_ids[0]);
301848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
301948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Invalid error generated");
302048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
302148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
302248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Delete samplers */
302348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteSamplers(max_samplers, &sampler_ids[0]);
302448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
302548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
302648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
302748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
302848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
302948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
303048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
303148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
303248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
303348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
303448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
303548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
303648087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindImageTexturesTest::FunctionalBindImageTexturesTest(deqp::Context& context)
303748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_image_textures", "Verifies that BindImageTextures works as expected")
303848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
303948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
304048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
304148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
304248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
304348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
304448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
304548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
304648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindImageTexturesTest::iterate()
304748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
304848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint depth  = 6;
304948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 6;
305048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 6;
305148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
305248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
305348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
305448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
305548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
305648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
305748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
305848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
305948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint invalid_id   = 1; /* Start with 1, as 0 is not valid name */
306048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint  max_textures = 0;
306148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
306248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
306348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_IMAGE_UNITS, &max_textures);
306448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
306548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
306648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
306748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				 buffer;
306848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Texture> texture;
306948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  texture_ids;
307048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  t_texture_ids;
307148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
307248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.resize(max_textures);
307348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids.resize(max_textures);
307448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	t_texture_ids.resize(max_textures);
307548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
307648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffer */
307748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, 16 /* size */, 0 /* data */);
307848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
307948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare textures */
308048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < (GLint)s_n_texture_tragets; ++i)
308148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
308248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLenum target = s_texture_infos[i].m_target;
308348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
308448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (i >= max_textures)
308548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
308648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
308748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
308848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
308948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (GL_TEXTURE_BUFFER != target)
309048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
309148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_RGBA8, width, height, depth);
309248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
309348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
309448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
309548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitBuffer(m_context, GL_RGBA8, buffer.m_id);
309648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
309748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
309848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Unbind */
309948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::Bind(gl, 0, target);
310048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
310148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
310248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = (GLint)s_n_texture_tragets; i < max_textures; ++i)
310348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
310448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth);
310548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
310648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
310748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Unbind */
310848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::Bind(gl, 0, GL_TEXTURE_2D);
310948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
311048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
311148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
311248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
311348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
311448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
311548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
311648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindImageTextures to bind all images;
311748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings to verify that proper images were set;
311848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
311948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(0, max_textures, &texture_ids[0]);
312048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures");
312148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
312248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
312348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
312448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]);
312548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
312648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
312748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
312848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures for the first half of units with <textures> filled
312948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * with zeros, to unbind those units;
313048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
313148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * unbound;
313248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
313348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint half_index = max_textures / 2;
313448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
313548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
313648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
313748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_texture_ids[i] = 0;
313848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
313948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
314048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(0, half_index, &t_texture_ids[0]);
314148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures");
314248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
314348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < half_index; ++i)
314448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
314548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", 0);
314648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
314748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
314848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = half_index; i < max_textures; ++i)
314948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
315048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]);
315148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
315248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
315348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
315448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures for the second half of units with NULL as<textures>,
315548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * to unbind those units;
315648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
315748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * unbound;
315848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
315948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(half_index, max_textures - half_index, 0);
316048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures");
316148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
316248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
316348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
316448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", 0);
316548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
316648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
316748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/*
316848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - modify <textures> so first entry is invalid;
316948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - execute BindTextures to bind all textures; It is expected that
317048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * INVALID_OPERATION will be generated;
317148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * - inspect bindings of all texture units to verify that proper bindings were
317248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 * set;
317348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	 */
317448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
317548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Find invalid id */
317648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	while (1)
317748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
317848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (GL_TRUE != gl.isTexture(invalid_id))
317948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
318048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
318148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
318248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
318348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		invalid_id += 1;
318448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
318548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
318648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set invalid id */
318748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids[0] = invalid_id;
318848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
318948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(0, max_textures, &texture_ids[0]);
319048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid texture id");
319148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
319248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	checkBinding(m_context, GL_IMAGE_BINDING_NAME, 0, "Image unit", 0);
319348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 1; i < max_textures; ++i)
319448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
319548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]);
319648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
319748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
319848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* - unbind all textures. */
319948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(0, max_textures, 0);
320048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures");
320148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
320248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
320348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
320448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
320548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
320648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
320748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
320848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
320948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
321048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
321148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
321248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
321348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosFunctionalBindVertexBuffersTest::FunctionalBindVertexBuffersTest(deqp::Context& context)
321448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "functional_bind_vertex_buffers", "Verifies that BindVertexBuffers works as expected")
321548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
321648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
321748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
321848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
321948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
322048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
322148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
322248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
322348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult FunctionalBindVertexBuffersTest::iterate()
322448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
322548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
322648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
322748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
322848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
322948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
323048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
323148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
323248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLintptr buffer_size = 16;
323348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLintptr offset	  = 4;
323448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLsizei  stride	  = 4;
323548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
323648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint invalid_id  = 1; /* Start with 1, as 0 is not valid name */
323748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint  max_buffers = 0;
323848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
323948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
324048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers);
324148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
324248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
324348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
324448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Buffer>   buffer;
324548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>   buffer_ids;
324648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLintptr> offsets;
324748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLsizei>  strides;
324848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>   t_buffer_ids;
324948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
325048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer.resize(max_buffers);
325148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer_ids.resize(max_buffers);
325248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	offsets.resize(max_buffers);
325348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	strides.resize(max_buffers);
325448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	t_buffer_ids.resize(max_buffers);
325548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
325648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffers */
325748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
325848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
325948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer[i].InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
326048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
326148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[i]   = buffer[i].m_id;
326248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		offsets[i]		= offset;
326348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		strides[i]		= stride;
326448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		t_buffer_ids[i] = 0;
326548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
326648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
326748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint vao = 0;
326848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &vao);
326948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
327048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
327148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
327248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexArray(vao);
327348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays");
327448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
327548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindVertexBuffers to bind all buffer;
327648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper buffers were set;
327748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
327848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]);
327948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers");
328048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
328148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_buffers; ++i)
328248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
328348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkVertexAttribBinding(m_context, i, buffer_ids[i]);
328448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
328548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
328648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindVertexBuffers for first half of bindings with <buffers> filled
328748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * with zeros, to unbind those buffers;
328848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper buffers were unbound;
328948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
329048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLint half_index = max_buffers / 2;
329148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
329248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(0, half_index, &t_buffer_ids[0], &offsets[0], &strides[0]);
329348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers");
329448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
329548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < half_index; ++i)
329648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
329748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkVertexAttribBinding(m_context, i, 0);
329848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
329948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
330048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = half_index; i < max_buffers; ++i)
330148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
330248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkVertexAttribBinding(m_context, i, buffer_ids[i]);
330348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
330448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
330548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - execute BindVertexBuffers for second half of bindings with NULL as
330648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * <buffers>, to unbind those buffers;
330748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper buffers were unbound;
330848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
330948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(half_index, max_buffers - half_index, 0, &offsets[0], &strides[0]);
331048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers");
331148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
331248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_buffers; ++i)
331348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
331448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkVertexAttribBinding(m_context, i, 0);
331548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
331648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
331748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - modify <buffers> so first entry is invalid;
331848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - execute BindVertexBuffers to bind all buffers; It is expected that
331948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * INVALID_OPERATION will be generated;
332048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 * - inspect bindings to verify that proper buffers were set;
332148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		 */
332248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
332348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Find invalid id */
332448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		while (1)
332548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
332648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			if (GL_TRUE != gl.isBuffer(invalid_id))
332748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			{
332848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos				break;
332948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			}
333048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
333148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			invalid_id += 1;
333248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
333348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
333448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[0] = invalid_id;
333548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]);
333648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid id");
333748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
333848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		checkVertexAttribBinding(m_context, 0, 0);
333948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 1; i < max_buffers; ++i)
334048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
334148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			checkVertexAttribBinding(m_context, i, buffer_ids[i]);
334248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
334348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
334448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* - unbind all buffers. */
334548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(0, max_buffers, 0, &offsets[0], &strides[0]);
334648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers");
334748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
334848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
334948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
335048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &vao);
335148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
335248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Unexpected error generated");
335348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
335448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
335548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteVertexArrays(1, &vao);
335648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays");
335748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
335848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
335948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
336048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
336148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
336248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
336348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
336448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
336548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
336648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
336748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
336848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
336948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDispatchBindBuffersBaseTest::DispatchBindBuffersBaseTest(deqp::Context& context)
337048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "dispatch_bind_buffers_base", "Tests BindBuffersBase with dispatch command")
337148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
337248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
337348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
337448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
337548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
337648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
337748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
337848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
337948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DispatchBindBuffersBaseTest::iterate()
338048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
338148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 440 core\n"
338248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
338348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
338448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
338548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "UBO_LIST\n"
338648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) buffer SSB {\n"
338748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    vec4 sum;\n"
338848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "} ssb;\n"
338948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
339048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
339148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
339248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    ssb.sum = SUM_LIST;\n"
339348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
339448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
339548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
339648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* ubo = "layout (std140, binding = XXX) uniform BXXX { vec4 data; } bXXX;";
339748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
339848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLintptr buffer_size = 4 * sizeof(GLfloat);
339948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
340048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
340148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
340248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
340348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
340448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
340548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
340648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
340748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
340848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
340948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint   max_buffers = 0;
341048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLfloat sum[4]		= { 0.0f, 0.0f, 0.0f, 0.0f };
341148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
341248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
341348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &max_buffers);
341448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
341548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
341648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* UBO */
341748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
341848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Buffer> uni_buffer;
341948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint> uni_buffer_ids;
342048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
342148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	uni_buffer.resize(max_buffers);
342248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	uni_buffer_ids.resize(max_buffers);
342348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
342448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffers */
342548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
342648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
342748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLfloat data[4] = {
342848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			(GLfloat)(i * 4 + 0), (GLfloat)(i * 4 + 1), (GLfloat)(i * 4 + 2), (GLfloat)(i * 4 + 3),
342948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		};
343048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
343148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum[0] += data[0];
343248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum[1] += data[1];
343348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum[2] += data[2];
343448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum[3] += data[3];
343548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
343648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_buffer[i].InitData(m_context, GL_UNIFORM_BUFFER, GL_DYNAMIC_COPY, buffer_size, data);
343748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
343848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_buffer_ids[i] = uni_buffer[i].m_id;
343948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
344048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
344148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBuffersBase(GL_UNIFORM_BUFFER, 0 /* first */, max_buffers /* count */, &uni_buffer_ids[0]);
344248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase");
344348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
344448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* SSBO */
344548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer ssb_buffer;
344648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */);
344748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
344848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.BindBase(0);
344948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
345048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
345148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		ubo_position = 0;
345248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		sum_position = 0;
345348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::string cs_source	= cs;
345448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
345548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
345648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t ubo_start_position = ubo_position;
345748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sum_start_position = sum_position;
345848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
345948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLchar index[16];
346048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
346148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sprintf(index, "%d", i);
346248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
346348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to ubo list */
346448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("UBO_LIST", ubo_position, "UBO\nUBO_LIST", cs_source);
346548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		ubo_position = ubo_start_position;
346648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
346748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("UBO", ubo_position, ubo, cs_source);
346848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		ubo_position = ubo_start_position;
346948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
347048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", ubo_position, index, cs_source);
347148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", ubo_position, index, cs_source);
347248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", ubo_position, index, cs_source);
347348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
347448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to sum list */
347548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SUM_LIST", sum_position, "bXXX.data + SUM_LIST", cs_source);
347648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
347748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
347848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sum_position, index, cs_source);
347948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
348048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
348148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove token for lists */
348248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken(" + SUM_LIST", sum_position, "", cs_source);
348348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("UBO_LIST", ubo_position, "", cs_source);
348448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
348548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
348648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
348748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
348848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
348948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
349048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(1, 1, 1);
349148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
349248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
349348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.memoryBarrier(GL_ALL_BARRIER_BITS);
349448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
349548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
349648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLfloat* result = (GLfloat*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
349748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
349848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
349948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (0 != memcmp(result, sum, 4 * sizeof(GLfloat)))
350048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
350148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		test_result = false;
350248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
350348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
350448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
350548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getError(); /* Ignore error */
350648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
350748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
350848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
350948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
351048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
351148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
351248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
351348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
351448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
351548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
351648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
351748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
351848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
351948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
352048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
352148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
352248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
352348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
352448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
352548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDispatchBindBuffersRangeTest::DispatchBindBuffersRangeTest(deqp::Context& context)
352648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "dispatch_bind_buffers_range", "Tests BindBuffersRange with dispatch command")
352748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
352848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
352948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
353048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
353148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
353248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
353348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
353448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
353548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DispatchBindBuffersRangeTest::iterate()
353648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
353748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 440 core\n"
353848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
353948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
354048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
354148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) uniform B0 { int data; } b0;"
354248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 1) uniform B1 { int data; } b1;"
354348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 2) uniform B2 { int data; } b2;"
354448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 3) uniform B3 { int data; } b3;"
354548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
354648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) buffer SSB {\n"
354748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    int sum;\n"
354848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "} ssb;\n"
354948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
355048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
355148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
355248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    //ssb.sum = b1.data;// + b1.data + b2.data + b3.data;\n"
355348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    ssb.sum = b0.data + b1.data + b2.data + b3.data;\n"
355448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
355548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
355648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
355748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLint  data[]	= { 0x00010001, 0x01000100 };
355848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const size_t n_buffers = 4;
355948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLint  sum		  = 0x02020202;
356048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
356148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
356248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
356348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
356448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
356548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
356648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
356748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
356848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
356948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
357048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* UBO */
357148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint offset_alignment = 0;
357248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
357348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offset_alignment);
357448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
357548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
357648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
357748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				 uni_buffer;
357848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint				 uni_buffer_ids[n_buffers];
357948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLubyte> uni_data;
358048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLintptr			 uni_offsets[n_buffers];
358148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLintptr			 uni_sizes[n_buffers];
358248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
358348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const size_t buffer_size = (n_buffers - 1) * offset_alignment + sizeof(GLint);
358448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	uni_data.resize(buffer_size);
358548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
358648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < buffer_size; ++i)
358748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
358848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_data[i] = 0xaa;
358948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
359048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
359148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < n_buffers; ++i)
359248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
359348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		void*		dst = &uni_data[i * offset_alignment];
359448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const void* src = &data[(i % 2)];
359548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
359648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		memcpy(dst, src, sizeof(GLint));
359748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
359848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
359948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	uni_buffer.InitData(m_context, GL_UNIFORM_BUFFER, GL_DYNAMIC_COPY, buffer_size, &uni_data[0]);
360048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
360148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (size_t i = 0; i < n_buffers; ++i)
360248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
360348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_buffer_ids[i] = uni_buffer.m_id;
360448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_offsets[i]	= i * offset_alignment;
360548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		uni_sizes[i]	  = sizeof(GLint);
360648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
360748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
360848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindBuffersRange(GL_UNIFORM_BUFFER, 0 /* first */, n_buffers /* count */, &uni_buffer_ids[0], &uni_offsets[0],
360948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						&uni_sizes[0]);
361048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange");
361148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
361248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* SSBO */
361348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer ssb_buffer;
361448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLint), 0 /* data */);
361548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
361648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.BindBase(0);
361748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
361848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
361948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
362048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(cs, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
362148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
362248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
362348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
362448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(1, 1, 1);
362548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
362648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
362748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.memoryBarrier(GL_ALL_BARRIER_BITS);
362848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
362948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
363048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint* result = (GLint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
363148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
363248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
363348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (0 != memcmp(result, &sum, sizeof(sum)))
363448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
363548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		test_result = false;
363648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
363748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
363848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
363948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getError(); /* Ignore error */
364048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
364148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
364248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
364348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
364448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
364548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
364648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
364748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
364848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
364948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
365048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
365148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
365248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
365348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
365448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
365548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
365648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
365748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
365848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
365948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDispatchBindTexturesTest::DispatchBindTexturesTest(deqp::Context& context)
366048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "dispatch_bind_textures", "Tests BindTextures with dispatch command")
366148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
366248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
366348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
366448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
366548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
366648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
366748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
366848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
366948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DispatchBindTexturesTest::iterate()
367048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
367148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 440 core\n"
367248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
367348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
367448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
367548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "SAMPLER_LIST\n"
367648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) buffer SSB {\n"
367748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uint sum;\n"
367848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "} ssb;\n"
367948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
368048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
368148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
368248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uvec4 sum = SUM_LIST;\n"
368348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    ssb.sum = sum.r\n;"
368448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
368548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
368648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
368748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* sampler = "layout (location = XXX) uniform SAMPLER sXXX;";
368848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
368948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* sampling[] = {
369048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"texture(sXXX, COORDS)", "texture(sXXX, COORDS)",		"texture(sXXX, COORDS)",	  "texture(sXXX, COORDS)",
369148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"texture(sXXX, COORDS)", "texelFetch(sXXX, COORDS)",	"texture(sXXX, COORDS)",	  "texture(sXXX, COORDS)",
369248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"texture(sXXX, COORDS)", "texelFetch(sXXX, COORDS, 0)", "texelFetch(sXXX, COORDS, 0)"
369348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	};
369448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
369548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* samplers[] = { "usampler1D",	 "usampler1DArray", "usampler2D",		 "usampler2DArray",
369648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										"usampler3D",	 "usamplerBuffer",  "usamplerCube",	 "usamplerCubeArray",
369748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos										"usampler2DRect", "usampler2DMS",	"usampler2DMSArray" };
369848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
369948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* coordinates[] = {
370048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"0.5f",
370148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec2(0.5f, 0.0f)",
370248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec2(0.5f, 0.5f)",
370348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec3(0.5f, 0.5f, 0.0f)",
370448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec3(0.5f, 0.5f, 0.5f)",
370548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"0",
370648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec3(0.5f, 0.5f, 0.5f)",
370748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec4(0.5f, 0.5f, 0.5f, 0.0f)",
370848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"vec2(0.5f, 0.5f)",
370948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec2(0, 0)",
371048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
371148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	};
371248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
371348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint depth  = 6;
371448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 6;
371548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 6;
371648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
371748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
371848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
371948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
372048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
372148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
372248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
372348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
372448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
372548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37265d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint  max_textures		 = 0;
37275d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint  max_image_samples = 0;
37285d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLuint sum				 = 0;
372948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
373048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
373148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &max_textures);
373248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
373348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
37345d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	/* Check if load/store from multisampled images is supported */
37355d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples);
37365d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
37375d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga
373848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Textures */
373948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
374048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Texture> texture;
374148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  texture_ids;
374248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				 texture_buffer;
374348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
374448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.resize(max_textures);
374548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids.resize(max_textures);
374648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
374748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare */
374848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
374948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
37505d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		GLenum target = getTarget(i);
37515d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		if (target >= GL_TEXTURE_2D_MULTISAMPLE && max_image_samples == 0)
37525d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga			target = GL_TEXTURE_2D;
375348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
375448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint data[width * height * depth];
375548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
375648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLuint j = 0; j < width * height * depth; ++j)
375748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
375848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[j] = i;
375948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
376048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
376148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum += i;
376248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
376348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		bool is_array = false;
376448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
376548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		switch (target)
376648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
376748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
376848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			is_array = true;
376948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Intended pass-through */
377048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
377148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_2D_MULTISAMPLE:
377248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth);
377348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			fillMSTexture(m_context, texture[i].m_id, i, is_array);
377448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
377548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
377648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_BUFFER:
377748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture_buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, sizeof(data), data);
377848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitBuffer(m_context, GL_R32UI, texture_buffer.m_id);
377948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
378048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
378148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		default:
378248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth);
378348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			Texture::Bind(gl, texture[i].m_id, target);
378448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			Texture::SubImage(gl, target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth,
378548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  GL_RED_INTEGER, GL_UNSIGNED_INT, &data);
3786a6cf3a79ce98eb2440b7623d44ab5003d9357223Iago Toral Quiroga			gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3787a6cf3a79ce98eb2440b7623d44ab5003d9357223Iago Toral Quiroga			gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
378848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
378948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
379048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
379148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Clean */
379248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::Bind(gl, 0, target);
379348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
379448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
379548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
379648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
379748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0 /* first */, max_textures /* count */, &texture_ids[0]);
379848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
379948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
380048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* SSBO */
380148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer ssb_buffer;
380248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */);
380348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
380448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.BindBase(0);
380548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
380648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
38075d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	size_t		sam_position	 = 0;
38085d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	size_t		sum_position	 = 0;
38095d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	std::string cs_source		 = cs;
38105d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint		max_target_index = (GLint)(max_image_samples > 0 ? s_n_texture_tragets : s_n_texture_tragets - 2);
381148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
381248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
381348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sam_start_position = sam_position;
381448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sum_start_position = sum_position;
381548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
381648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLchar index[16];
381748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
381848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sprintf(index, "%d", i);
381948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
382048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* coords		= 0;
382148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* sampler_type  = 0;
382248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* sampling_code = 0;
382348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
38245d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		if (i < max_target_index)
382548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
382648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			coords		  = coordinates[i];
382748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sampler_type  = samplers[i];
382848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sampling_code = sampling[i];
382948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
383048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
383148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
383248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			coords		  = coordinates[2]; /* vec2(0.5f, 0.5f) */
383348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sampler_type  = samplers[2];	/* usampler2D */
383448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			sampling_code = sampling[2];	/* texture(sXXX, COORDS) */
383548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
383648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
383748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to ubo list */
383848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLER_LIST", sam_position, "SAMPLER\nSAMPLER_LIST", cs_source);
383948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sam_position = sam_start_position;
384048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
384148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLER", sam_position, sampler, cs_source);
384248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sam_position = sam_start_position;
384348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
384448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sam_position, index, cs_source);
384548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLER", sam_position, sampler_type, cs_source);
384648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sam_position, index, cs_source);
384748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
384848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to sum list */
384948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SUM_LIST", sum_position, "SAMPLING + SUM_LIST", cs_source);
385048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
385148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
385248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLING", sum_position, sampling_code, cs_source);
385348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
385448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
385548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sum_position, index, cs_source);
385648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("COORDS", sum_position, coords, cs_source);
385748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
385848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
385948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove token for lists */
386048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken(" + SUM_LIST", sum_position, "", cs_source);
386148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("SAMPLER_LIST", sam_position, "", cs_source);
386248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
386348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
386448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
386548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
386648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
386748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
386848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set samplers */
386948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
387048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
387148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.uniform1i(i, i);
387248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
387348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
387448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
387548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(1, 1, 1);
387648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
387748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
387848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.memoryBarrier(GL_ALL_BARRIER_BITS);
387948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
388048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
388148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
388248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
388348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
388448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (0 != memcmp(result, &sum, sizeof(sum)))
388548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
388648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		test_result = false;
388748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
388848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
388948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
389048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getError(); /* Ignore error */
389148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
389248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
389348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
389448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
389548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
389648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
389748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
389848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
389948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
390048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
390148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
390248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
390348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
390448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
390548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
390648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
390748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
390848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
390948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
391048087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDispatchBindImageTexturesTest::DispatchBindImageTexturesTest(deqp::Context& context)
391148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "dispatch_bind_image_textures", "Tests BindImageTextures with dispatch command")
391248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
391348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
391448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
391548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
391648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
391748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
391848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
391948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
392048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DispatchBindImageTexturesTest::iterate()
392148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
392248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 440 core\n"
392348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
392448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
392548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
392648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "IMAGE_LIST\n"
392748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) buffer SSB {\n"
392848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uint sum;\n"
392948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "} ssb;\n"
393048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
393148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
393248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
393348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uvec4 sum = SUM_LIST;\n"
393448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    ssb.sum = sum.r\n;"
393548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
393648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
393748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
393848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* image = "layout (location = XXX, r32ui) readonly uniform IMAGE iXXX;";
393948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
394048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* loading[] = {
394148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)",	"imageLoad(iXXX, COORDS)",   "imageLoad(iXXX, COORDS)",
394248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)",	"imageLoad(iXXX, COORDS)",   "imageLoad(iXXX, COORDS)",
394348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS, 0)", "imageLoad(iXXX, COORDS, 0)"
394448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	};
394548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
394648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* images[] = { "uimage1D",	 "uimage1DArray", "uimage2D",		 "uimage2DArray",
394748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									  "uimage3D",	 "uimageBuffer",  "uimageCube",	 "uimageCubeArray",
394848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos									  "uimage2DRect", "uimage2DMS",	"uimage2DMSArray" };
394948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
395048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* coordinates[] = {
395148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"0",
395248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec2(0, 0)",
395348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec2(0, 0)",
395448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
395548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
395648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"0",
395748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
395848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
395948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec2(0, 0)",
396048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec2(0, 0)",
396148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		"ivec3(0, 0, 0)",
396248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	};
396348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
396448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint depth  = 6;
396548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 6;
396648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 6;
396748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
396848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
396948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
397048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
397148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
397248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
397348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
397448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
397548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
397648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
39775d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint  max_textures		 = 0;
39785d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint  max_image_samples = 0;
39795d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLuint sum				 = 0;
398048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
398148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
3982ac14f1d762f135dd63d8e78d74ef2df35af315a7Iago Toral Quiroga	gl.getIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &max_textures);
398348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
398448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
39855d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	/* Check if load/store from multisampled images is supported */
39865d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples);
39875d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
39885d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga
398948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Textures */
399048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
399148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Texture> texture;
399248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  texture_ids;
399348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				 texture_buffer;
399448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
399548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.resize(max_textures);
399648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids.resize(max_textures);
399748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
399848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare */
399948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
400048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
40015d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		GLenum target = getTarget(i);
40025d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		if (target >= GL_TEXTURE_2D_MULTISAMPLE && max_image_samples == 0)
40035d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga			target = GL_TEXTURE_2D;
400448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
400548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLuint data[width * height * depth];
400648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
400748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLuint j = 0; j < width * height * depth; ++j)
400848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
400948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[j] = i;
401048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
401148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
401248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum += i;
401348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
401448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		bool is_array = false;
401548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
401648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		switch (target)
401748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
401848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
401948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			is_array = true;
402048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Intended pass-through */
402148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
402248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_2D_MULTISAMPLE:
402348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth);
402448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			fillMSTexture(m_context, texture[i].m_id, i, is_array);
402548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
402648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
402748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		case GL_TEXTURE_BUFFER:
402848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture_buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, sizeof(data), data);
402948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitBuffer(m_context, GL_R32UI, texture_buffer.m_id);
403048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
403148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
403248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		default:
403348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth);
403448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			Texture::Bind(gl, texture[i].m_id, target);
403548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			Texture::SubImage(gl, target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth,
403648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  GL_RED_INTEGER, GL_UNSIGNED_INT, &data);
403748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
403848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
403948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
404048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Clean */
404148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::Bind(gl, 0, target);
404248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
404348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
404448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
404548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
404648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindImageTextures(0 /* first */, max_textures /* count */, &texture_ids[0]);
404748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures");
404848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
404948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* SSBO */
405048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer ssb_buffer;
405148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */);
405248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
405348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.BindBase(0);
405448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
405548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
40565d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	size_t		load_position	= 0;
40575d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	size_t		sum_position	 = 0;
40585d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	std::string cs_source		 = cs;
40595d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga	GLint		max_target_index = (GLint)(max_image_samples > 0 ? s_n_texture_tragets : s_n_texture_tragets - 2);
406048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
406148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
406248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t load_start_position = load_position;
406348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sum_start_position  = sum_position;
406448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
406548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLchar index[16];
406648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
406748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sprintf(index, "%d", i);
406848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
406948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* coords	   = 0;
407048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* image_type   = 0;
407148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const GLchar* loading_code = 0;
407248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
40735d8b103d5e04a0e5dc5aa790f7bb498b80c4e0cdIago Toral Quiroga		if (i < max_target_index)
407448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
407548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			coords		 = coordinates[i];
407648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			image_type   = images[i];
407748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			loading_code = loading[i];
407848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
407948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		else
408048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
408148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			coords		 = coordinates[2]; /* vec2(0.5f, 0.5f) */
408248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			image_type   = images[2];	  /* usampler2D */
408348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			loading_code = loading[2];	 /* texture(sXXX, COORDS) */
408448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
408548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
408648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to ubo list */
408748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("IMAGE_LIST", load_position, "IMAGE\nIMAGE_LIST", cs_source);
408848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		load_position = load_start_position;
408948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
409048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("IMAGE", load_position, image, cs_source);
409148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		load_position = load_start_position;
409248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
409348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", load_position, index, cs_source);
409448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("IMAGE", load_position, image_type, cs_source);
409548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", load_position, index, cs_source);
409648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
409748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to sum list */
409848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SUM_LIST", sum_position, "LOADING + SUM_LIST", cs_source);
409948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
410048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
410148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("LOADING", sum_position, loading_code, cs_source);
410248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
410348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
410448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sum_position, index, cs_source);
410548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("COORDS", sum_position, coords, cs_source);
410648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
410748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
410848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove token for lists */
410948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken(" + SUM_LIST", sum_position, "", cs_source);
411048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("IMAGE_LIST", load_position, "", cs_source);
411148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
411248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
411348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
411448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
411548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
411648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
411748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set images */
411848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
411948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
412048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.uniform1i(i, i);
412148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
412248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
412348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
412448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.dispatchCompute(1, 1, 1);
412548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
412648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
412748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.memoryBarrier(GL_ALL_BARRIER_BITS);
412848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
412948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
413048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
413148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
413248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
413348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (0 != memcmp(result, &sum, sizeof(sum)))
413448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
413548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		test_result = false;
413648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
413748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
413848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
413948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getError(); /* Ignore error */
414048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
414148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
414248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
414348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
414448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
414548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
414648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
414748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
414848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
414948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
415048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
415148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
415248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
415348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
415448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
415548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
415648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
415748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
415848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
415948087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDispatchBindSamplersTest::DispatchBindSamplersTest(deqp::Context& context)
416048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "dispatch_bind_samplers", "Tests BindSamplers with dispatch command")
416148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
416248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
416348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
416448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
416548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
416648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
416748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
416848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
416948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DispatchBindSamplersTest::iterate()
417048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
417148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* cs = "#version 440 core\n"
417248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
417348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
417448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
417548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "SAMPLER_LIST\n"
417648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout (std140, binding = 0) buffer SSB {\n"
417748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uint sum;\n"
417848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "} ssb;\n"
417948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
418048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
418148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
418248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    uvec4 sum = SUM_LIST;\n"
418348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    ssb.sum = sum.r\n;"
418448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
418548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
418648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
418748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* sampler = "layout (location = XXX) uniform usampler2D sXXX;";
418848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
418948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* sampling = "texture(sXXX, vec2(1.5f, 0.5f))";
419048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
419148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint depth  = 1;
419248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 8;
419348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 8;
419448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
419548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
419648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
419748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
419848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
419948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
420048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
420148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
420248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
420348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
420448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint max_textures = 0;
420548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
420648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
420748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &max_textures);
420848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
420948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
421048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Textures */
421148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
421248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  sampler_ids;
421348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<Texture> texture;
421448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>  texture_ids;
421548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
421648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	sampler_ids.resize(max_textures);
421748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.resize(max_textures);
421848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture_ids.resize(max_textures);
421948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
422048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint data[width * height * depth];
422148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
422248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLuint j = 0; j < width * height; ++j)
422348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
422448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		data[j] = 0;
422548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
422648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
422748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
422848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const size_t last_line_offset		   = (height - 1) * width;
422948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		const size_t last_pixel_in_line_offset = width - 1;
423048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
423148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLuint j = 0; j < width; ++j)
423248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
423348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[j]					   = 1;
423448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[j + last_line_offset] = 1;
423548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
423648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
423748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLuint j = 0; j < height; ++j)
423848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
423948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			const size_t line_offset = j * width;
424048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
424148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[line_offset]							  = 1;
424248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			data[line_offset + last_pixel_in_line_offset] = 1;
424348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
424448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
424548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
424648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare */
424748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
424848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
424948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_R32UI, width, height, depth);
425048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::Bind(gl, texture[i].m_id, GL_TEXTURE_2D);
425148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth,
425248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos						  GL_RED_INTEGER, GL_UNSIGNED_INT, &data);
425348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
425448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		texture_ids[i] = texture[i].m_id;
425548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
425648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
425748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Clean */
425848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::Bind(gl, 0, GL_TEXTURE_2D);
425948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
426048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Execute the test */
426148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.bindTextures(0 /* first */, max_textures /* count */, &texture_ids[0]);
426248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures");
426348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
426448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* SSBO */
426548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer ssb_buffer;
426648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */);
426748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
426848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	ssb_buffer.BindBase(0);
426948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
427048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
427148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		sam_position = 0;
427248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		sum_position = 0;
427348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::string cs_source	= cs;
427448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
427548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
427648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
427748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sam_start_position = sam_position;
427848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sum_start_position = sum_position;
427948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
428048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLchar index[16];
428148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
428248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sprintf(index, "%d", i);
428348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
428448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to ubo list */
428548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLER_LIST", sam_position, "SAMPLER\nSAMPLER_LIST", cs_source);
428648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sam_position = sam_start_position;
428748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
428848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLER", sam_position, sampler, cs_source);
428948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sam_position = sam_start_position;
429048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
429148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sam_position, index, cs_source);
429248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sam_position, index, cs_source);
429348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
429448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to sum list */
429548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SUM_LIST", sum_position, "SAMPLING + SUM_LIST", cs_source);
429648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
429748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
429848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SAMPLING", sum_position, sampling, cs_source);
429948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
430048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
430148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sum_position, index, cs_source);
430248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
430348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
430448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove token for lists */
430548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken(" + SUM_LIST", sum_position, "", cs_source);
430648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("SAMPLER_LIST", sam_position, "", cs_source);
430748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
430848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
430948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */);
431048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
431148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
431248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
431348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set texture units */
431448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_textures; ++i)
431548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
431648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.uniform1i(i, i);
431748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
431848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
431948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
432048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare samplers */
432148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genSamplers(max_textures, &sampler_ids[0]);
432248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers");
432348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
432448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
432548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
432648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindSamplers(0 /* first */, max_textures /* count */, &sampler_ids[0]);
432748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers");
432848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
432948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_textures; ++i)
433048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
433148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
433248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
433348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
433448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "SamplerParameteri");
433548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
433648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
433748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.dispatchCompute(1, 1, 1);
433848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
433948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
434048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.memoryBarrier(GL_ALL_BARRIER_BITS);
434148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
434248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
434348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
434448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
434548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteSamplers(max_textures, &sampler_ids[0]);
434648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
434748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Unexpected error generated");
434848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
434948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
435048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove samplers */
435148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteSamplers(max_textures, &sampler_ids[0]);
435248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
435348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Verify results */
435448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
435548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
435648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
435748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (0 != memcmp(result, &max_textures, sizeof(max_textures)))
435848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
435948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		test_result = false;
436048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
436148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
436248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
436348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getError(); /* Ignore error */
436448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
436548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
436648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
436748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
436848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
436948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
437048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
437148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
437248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
437348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
437448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
437548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
437648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
437748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
437848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
437948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor
438048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
438148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context
438248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
438348087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosDrawBindVertexBuffersTest::DrawBindVertexBuffersTest(deqp::Context& context)
438448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCase(context, "draw_bind_vertex_buffers", "Tests BindVertexBuffers command with drawArrays")
438548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
438648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Nothing to be done */
438748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
438848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
438948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Execute test
439048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
439148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return tcu::TestNode::STOP
439248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
439348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult DrawBindVertexBuffersTest::iterate()
439448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
439548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* vs = "#version 440 core\n"
439648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
439748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "ATTRIBUTE_LIST\n"
439848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
439948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "out vec4 vs_gs_sum;\n"
440048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
440148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
440248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
440348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    vs_gs_sum = SUM_LIST;\n"
440448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
440548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
440648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
440748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* gs = "#version 440 core\n"
440848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
440948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout(points)                           in;\n"
441048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "layout(triangle_strip, max_vertices = 4) out;\n"
441148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
441248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "in  vec4 vs_gs_sum[];\n"
441348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "out vec4 gs_fs_sum;\n"
441448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
441548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
441648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
441748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gs_fs_sum   = vs_gs_sum[0];\n"
441848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gl_Position = vec4(-1, -1, 0, 1);\n"
441948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    EmitVertex();\n"
442048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gs_fs_sum   = vs_gs_sum[0];\n"
442148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gl_Position = vec4(-1, 1, 0, 1);\n"
442248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    EmitVertex();\n"
442348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gs_fs_sum   = vs_gs_sum[0];\n"
442448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gl_Position = vec4(1, -1, 0, 1);\n"
442548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    EmitVertex();\n"
442648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gs_fs_sum   = vs_gs_sum[0];\n"
442748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    gl_Position = vec4(1, 1, 0, 1);\n"
442848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    EmitVertex();\n"
442948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
443048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
443148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
443248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* fs = "#version 440 core\n"
443348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
443448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "in  vec4 gs_fs_sum;\n"
443548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "out vec4 fs_out;\n"
443648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n"
443748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "void main()\n"
443848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "{\n"
443948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "    fs_out = gs_fs_sum;\n"
444048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "}\n"
444148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							  "\n";
444248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
444348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLchar* attribute = "layout (location = XXX) in vec4 aXXX;";
444448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
444548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint height = 8;
444648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLuint width  = 8;
444748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
444848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const Functions& gl = m_context.getRenderContext().getFunctions();
444948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
445048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	bool test_result = true;
445148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
445248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#if DEBUG_ENBALE_MESSAGE_CALLBACK
445348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.debugMessageCallback(debug_proc, &m_context);
445448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
445548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */
445648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
445748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	static const GLintptr attribute_size = 4 * sizeof(GLfloat);
445848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
445948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLint  max_buffers = 0;
446048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint vao		   = 0;
446148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
446248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Get max */
446348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers);
446448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
446548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
446648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Storage */
446748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Buffer				  buffer;
446848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLuint>   buffer_ids;
446948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLfloat>  data;
447048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLintptr> offsets;
447148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::vector<GLsizei>  strides;
447248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
447348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer_ids.resize(max_buffers);
447448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	data.resize(max_buffers * 4);
447548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	offsets.resize(max_buffers);
447648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	strides.resize(max_buffers);
447748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
447848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare data */
447948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	const GLfloat value = 1.0f / (GLfloat)max_buffers;
448048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
448148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
448248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
448348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		data[i * 4 + 0] = value;
448448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		data[i * 4 + 1] = value;
448548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		data[i * 4 + 2] = value;
448648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		data[i * 4 + 3] = value;
448748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
448848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
448948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare buffer */
449048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	buffer.InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, data.size() * sizeof(GLfloat), &data[0]);
449148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
449248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
449348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
449448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		buffer_ids[i] = buffer.m_id;
449548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		offsets[i]	= i * attribute_size;
449648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		strides[i]	= attribute_size;
449748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
449848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
449948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare FBO */
450048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Framebuffer framebuffer(m_context);
450148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture		texture;
450248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
450348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	texture.InitStorage(m_context, GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, width, height, 1 /* depth */);
450448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
450548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* */
450648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Framebuffer::Generate(gl, framebuffer.m_id);
450748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Framebuffer::Bind(gl, GL_DRAW_FRAMEBUFFER, framebuffer.m_id);
450848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Framebuffer::AttachTexture(gl, GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.m_id, 0 /* level */, width,
450948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos							   height);
451048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
451148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Prepare program */
451248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		attr_position = 0;
451348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	size_t		sum_position  = 0;
451448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	std::string vs_source	 = vs;
451548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLint i = 0; i < max_buffers; ++i)
451648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
451748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t attr_start_position = attr_position;
451848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		size_t sum_start_position  = sum_position;
451948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
452048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLchar index[16];
452148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
452248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sprintf(index, "%d", i);
452348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
452448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to ubo list */
452548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("ATTRIBUTE_LIST", attr_position, "ATTRIBUTE\nATTRIBUTE_LIST", vs_source);
452648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		attr_position = attr_start_position;
452748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
452848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("ATTRIBUTE", attr_position, attribute, vs_source);
452948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		attr_position = attr_start_position;
453048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
453148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", attr_position, index, vs_source);
453248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", attr_position, index, vs_source);
453348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
453448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* Add entry to sum list */
453548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("SUM_LIST", sum_position, "aXXX + SUM_LIST", vs_source);
453648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		sum_position = sum_start_position;
453748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
453848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		replaceToken("XXX", sum_position, index, vs_source);
453948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
454048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
454148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Remove token for lists */
454248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken(" + SUM_LIST", sum_position, "", vs_source);
454348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	replaceToken("ATTRIBUTE_LIST", attr_position, "", vs_source);
454448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
454548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Program program(m_context);
454648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Init("" /* cs */, fs, gs, "" /* tcs */, "" /* tes */, vs_source.c_str());
454748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
454848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	program.Use();
454948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
455048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.genVertexArrays(1, &vao);
455148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
455248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
455348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	try
455448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
455548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexArray(vao);
455648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays");
455748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
455848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_buffers; ++i)
455948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
456048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.enableVertexAttribArray(i);
456148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray");
456248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
456348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
456448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* */
456548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]);
456648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers");
456748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
456848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		/* */
456948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
457048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
457148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
457248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		for (GLint i = 0; i < max_buffers; ++i)
457348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
457448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			gl.disableVertexAttribArray(i);
457548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray");
457648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
457748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
457848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	catch (const std::exception&)
457948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
458048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		gl.deleteVertexArrays(1, &vao);
458148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
458248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		TCU_FAIL("Unexpected error generated");
458348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
458448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
458548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	gl.deleteVertexArrays(1, &vao);
458648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays");
458748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
458848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Verify results */
458948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	GLuint pixels[width * height];
459048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLuint i = 0; i < width * height; ++i)
459148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
459248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		pixels[i] = 0;
459348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
459448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
459548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D);
459648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
459748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
459848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
459948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Unbind */
460048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	Texture::Bind(gl, 0, GL_TEXTURE_2D);
460148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
460248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Verify */
460348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	for (GLuint i = 0; i < width * height; ++i)
460448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
460548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		if (0xffffffff != pixels[i])
460648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		{
460748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)pixels[i]
460848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos												<< " at offset: " << i << tcu::TestLog::EndMessage;
460948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
461048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			test_result = false;
461148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
461248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos			break;
461348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		}
461448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
461548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
461648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Set result */
461748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	if (true == test_result)
461848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
461948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
462048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
462148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	else
462248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	{
462348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos		m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
462448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	}
462548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
462648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Done */
462748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	return tcu::TestNode::STOP;
462848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
462948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} /* MultiBind */
463048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
463148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor.
463248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
463348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *  @param context Rendering context.
463448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
463548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosMultiBindTests::MultiBindTests(deqp::Context& context)
463648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	: TestCaseGroup(context, "multi_bind", "Verifies \"multi bind\" functionality")
463748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
463848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	/* Left blank on purpose */
463948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
464048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
464148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes a multi_bind test group.
464248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos *
464348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/
464448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid MultiBindTests::init(void)
464548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{
464648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DispatchBindTexturesTest(m_context));
464748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
464848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::ErrorsBindBuffersTest(m_context));
464948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::ErrorsBindTexturesTest(m_context));
465048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::ErrorsBindSamplersTest(m_context));
465148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::ErrorsBindImageTexturesTest(m_context));
465248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::ErrorsBindVertexBuffersTest(m_context));
465348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindBuffersBaseTest(m_context));
465448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindBuffersRangeTest(m_context));
465548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindTexturesTest(m_context));
465648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindSamplersTest(m_context));
465748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindImageTexturesTest(m_context));
465848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::FunctionalBindVertexBuffersTest(m_context));
465948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DispatchBindBuffersBaseTest(m_context));
466048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DispatchBindBuffersRangeTest(m_context));
466148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
466248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DispatchBindImageTexturesTest(m_context));
466348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DispatchBindSamplersTest(m_context));
466448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos	addChild(new MultiBind::DrawBindVertexBuffersTest(m_context));
466548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}
466648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos
466748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} /* gl4cts namespace */
4668