1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES Utilities
3e5c31af7Sopenharmony_ci * ------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Texture classes.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "gluTexture.hpp"
25e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp"
26e5c31af7Sopenharmony_ci#include "deFilePath.hpp"
27e5c31af7Sopenharmony_ci#include "tcuImageIO.hpp"
28e5c31af7Sopenharmony_ci#include "tcuSurface.hpp"
29e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
32e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_ciusing std::vector;
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_cinamespace glu
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_cistatic inline int computePixelStore (const tcu::TextureFormat& format)
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_ci	int pixelSize = format.getPixelSize();
44e5c31af7Sopenharmony_ci	if (deIsPowerOfTwo32(pixelSize))
45e5c31af7Sopenharmony_ci		return de::min(pixelSize, 8);
46e5c31af7Sopenharmony_ci	else
47e5c31af7Sopenharmony_ci		return 1;
48e5c31af7Sopenharmony_ci}
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ci// Texture1D
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ciTexture1D::Texture1D (const RenderContext& context, deUint32 format, deUint32 dataType, int width)
53e5c31af7Sopenharmony_ci	: m_context			(context)
54e5c31af7Sopenharmony_ci	, m_format			(format)
55e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), width)
56e5c31af7Sopenharmony_ci	, m_glTexture		(0)
57e5c31af7Sopenharmony_ci{
58e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
59e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
60e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
61e5c31af7Sopenharmony_ci}
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ciTexture1D::Texture1D (const RenderContext& context, deUint32 sizedFormat, int width)
64e5c31af7Sopenharmony_ci	: m_context			(context)
65e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
66e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), width)
67e5c31af7Sopenharmony_ci	, m_glTexture		(0)
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
70e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
71e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ciTexture1D::~Texture1D (void)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci	if (m_glTexture)
77e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
78e5c31af7Sopenharmony_ci}
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_civoid Texture1D::upload (void)
81e5c31af7Sopenharmony_ci{
82e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
85e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_1D, m_glTexture);
86e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
87e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
92e5c31af7Sopenharmony_ci	{
93e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
94e5c31af7Sopenharmony_ci			continue; // Don't upload.
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
97e5c31af7Sopenharmony_ci		gl.texImage1D(GL_TEXTURE_1D, levelNdx, m_format, access.getWidth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
98e5c31af7Sopenharmony_ci	}
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
101e5c31af7Sopenharmony_ci}
102e5c31af7Sopenharmony_ci
103e5c31af7Sopenharmony_ci// Texture2D
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ciTexture2D::Texture2D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height)
106e5c31af7Sopenharmony_ci	: m_context			(context)
107e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
108e5c31af7Sopenharmony_ci	, m_format			(format)
109e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), width, height, isES2Context(context.getType()))
110e5c31af7Sopenharmony_ci	, m_glTexture		(0)
111e5c31af7Sopenharmony_ci{
112e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
113e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
114e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
115e5c31af7Sopenharmony_ci}
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ciTexture2D::Texture2D (const RenderContext& context, deUint32 sizedFormat, int width, int height)
118e5c31af7Sopenharmony_ci	: m_context			(context)
119e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
120e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
121e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), width, height, isES2Context(context.getType()))
122e5c31af7Sopenharmony_ci	, m_glTexture		(0)
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
125e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
126e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
127e5c31af7Sopenharmony_ci}
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ciTexture2D::Texture2D (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
130e5c31af7Sopenharmony_ci	: m_context			(context)
131e5c31af7Sopenharmony_ci	, m_isCompressed	(true)
132e5c31af7Sopenharmony_ci	, m_format			(getGLFormat(levels[0].getFormat()))
133e5c31af7Sopenharmony_ci	, m_refTexture		(getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), isES2Context(context.getType()))
134e5c31af7Sopenharmony_ci	, m_glTexture		(0)
135e5c31af7Sopenharmony_ci{
136e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ci	if (!contextInfo.isCompressedTextureFormatSupported(m_format))
139e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Compressed texture format not supported");
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
142e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci	try
145e5c31af7Sopenharmony_ci	{
146e5c31af7Sopenharmony_ci		loadCompressed(numLevels, levels, decompressionParams);
147e5c31af7Sopenharmony_ci	}
148e5c31af7Sopenharmony_ci	catch (const std::exception&)
149e5c31af7Sopenharmony_ci	{
150e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &m_glTexture);
151e5c31af7Sopenharmony_ci		throw;
152e5c31af7Sopenharmony_ci	}
153e5c31af7Sopenharmony_ci}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ciTexture2D::~Texture2D (void)
156e5c31af7Sopenharmony_ci{
157e5c31af7Sopenharmony_ci	if (m_glTexture)
158e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
159e5c31af7Sopenharmony_ci}
160e5c31af7Sopenharmony_ci
161e5c31af7Sopenharmony_civoid Texture2D::upload (void)
162e5c31af7Sopenharmony_ci{
163e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ci	DE_ASSERT(!m_isCompressed);
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
168e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
169e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
170e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
175e5c31af7Sopenharmony_ci	{
176e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
177e5c31af7Sopenharmony_ci			continue; // Don't upload.
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
180e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
181e5c31af7Sopenharmony_ci		gl.texImage2D(GL_TEXTURE_2D, levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
182e5c31af7Sopenharmony_ci	}
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
185e5c31af7Sopenharmony_ci}
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_civoid Texture2D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
188e5c31af7Sopenharmony_ci{
189e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getFunctions();
190e5c31af7Sopenharmony_ci	deUint32				compressedFormat	= getGLFormat(levels[0].getFormat());
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
193e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
196e5c31af7Sopenharmony_ci	{
197e5c31af7Sopenharmony_ci		const tcu::CompressedTexture& level = levels[levelNdx];
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci		// Decompress to reference texture.
200e5c31af7Sopenharmony_ci		m_refTexture.allocLevel(levelNdx);
201e5c31af7Sopenharmony_ci		tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
202e5c31af7Sopenharmony_ci		TCU_CHECK(level.getWidth()	== refLevelAccess.getWidth() &&
203e5c31af7Sopenharmony_ci				  level.getHeight()	== refLevelAccess.getHeight());
204e5c31af7Sopenharmony_ci		level.decompress(refLevelAccess, decompressionParams);
205e5c31af7Sopenharmony_ci
206e5c31af7Sopenharmony_ci		// Upload to GL texture in compressed form.
207e5c31af7Sopenharmony_ci		gl.compressedTexImage2D(GL_TEXTURE_2D, levelNdx, compressedFormat,
208e5c31af7Sopenharmony_ci								level.getWidth(), level.getHeight(), 0 /* border */, level.getDataSize(), level.getData());
209e5c31af7Sopenharmony_ci	}
210e5c31af7Sopenharmony_ci
211e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
212e5c31af7Sopenharmony_ci}
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ciTexture2D* Texture2D::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const char* const* levelFileNames)
215e5c31af7Sopenharmony_ci{
216e5c31af7Sopenharmony_ci	DE_ASSERT(numLevels > 0);
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_ci	std::string ext = de::FilePath(levelFileNames[0]).getFileExtension();
219e5c31af7Sopenharmony_ci
220e5c31af7Sopenharmony_ci	if (ext == "png")
221e5c31af7Sopenharmony_ci	{
222e5c31af7Sopenharmony_ci		// Uncompressed texture.
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci		tcu::TextureLevel level;
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci		// Load level 0.
227e5c31af7Sopenharmony_ci		tcu::ImageIO::loadPNG(level, archive, levelFileNames[0]);
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci		TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
230e5c31af7Sopenharmony_ci						   level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci		bool		isRGBA		= level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
233e5c31af7Sopenharmony_ci		Texture2D*	texture		= new Texture2D(context, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, level.getWidth(), level.getHeight());
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci		try
236e5c31af7Sopenharmony_ci		{
237e5c31af7Sopenharmony_ci			// Fill level 0.
238e5c31af7Sopenharmony_ci			texture->getRefTexture().allocLevel(0);
239e5c31af7Sopenharmony_ci			tcu::copy(texture->getRefTexture().getLevel(0), level.getAccess());
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci			// Fill remaining levels.
242e5c31af7Sopenharmony_ci			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
243e5c31af7Sopenharmony_ci			{
244e5c31af7Sopenharmony_ci				tcu::ImageIO::loadPNG(level, archive, levelFileNames[levelNdx]);
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci				texture->getRefTexture().allocLevel(levelNdx);
247e5c31af7Sopenharmony_ci				tcu::copy(texture->getRefTexture().getLevel(levelNdx), level.getAccess());
248e5c31af7Sopenharmony_ci			}
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci			// Upload data.
251e5c31af7Sopenharmony_ci			texture->upload();
252e5c31af7Sopenharmony_ci		}
253e5c31af7Sopenharmony_ci		catch (const std::exception&)
254e5c31af7Sopenharmony_ci		{
255e5c31af7Sopenharmony_ci			delete texture;
256e5c31af7Sopenharmony_ci			throw;
257e5c31af7Sopenharmony_ci		}
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_ci		return texture;
260e5c31af7Sopenharmony_ci	}
261e5c31af7Sopenharmony_ci	else if (ext == "pkm")
262e5c31af7Sopenharmony_ci	{
263e5c31af7Sopenharmony_ci		// Compressed texture.
264e5c31af7Sopenharmony_ci		vector<tcu::CompressedTexture> levels(numLevels);
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < numLevels; ndx++)
267e5c31af7Sopenharmony_ci			tcu::ImageIO::loadPKM(levels[ndx], archive, levelFileNames[ndx]);
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_ci		return new Texture2D(context, contextInfo, numLevels, &levels[0]);
270e5c31af7Sopenharmony_ci	}
271e5c31af7Sopenharmony_ci	else
272e5c31af7Sopenharmony_ci		TCU_FAIL("Unsupported file format");
273e5c31af7Sopenharmony_ci}
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ciTexture2D* Texture2D::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const std::vector<std::string>& filenames)
276e5c31af7Sopenharmony_ci{
277e5c31af7Sopenharmony_ci	TCU_CHECK(numLevels == (int)filenames.size());
278e5c31af7Sopenharmony_ci
279e5c31af7Sopenharmony_ci	std::vector<const char*> charPtrs(filenames.size());
280e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)filenames.size(); ndx++)
281e5c31af7Sopenharmony_ci		charPtrs[ndx] = filenames[ndx].c_str();
282e5c31af7Sopenharmony_ci
283e5c31af7Sopenharmony_ci	return Texture2D::create(context, contextInfo, archive, numLevels, &charPtrs[0]);
284e5c31af7Sopenharmony_ci}
285e5c31af7Sopenharmony_ci
286e5c31af7Sopenharmony_ci// ImmutableTexture2D
287e5c31af7Sopenharmony_ci
288e5c31af7Sopenharmony_ciImmutableTexture2D::ImmutableTexture2D (const RenderContext& context, deUint32 sizedFormat, int width, int height)
289e5c31af7Sopenharmony_ci	: Texture2D(context, sizedFormat, width, height)
290e5c31af7Sopenharmony_ci{
291e5c31af7Sopenharmony_ci}
292e5c31af7Sopenharmony_ci
293e5c31af7Sopenharmony_civoid ImmutableTexture2D::upload (void)
294e5c31af7Sopenharmony_ci{
295e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci	DE_ASSERT(!m_isCompressed);
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
300e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
301e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
302e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ci	gl.texStorage2D(GL_TEXTURE_2D, m_refTexture.getNumLevels(), m_format, m_refTexture.getWidth(), m_refTexture.getHeight());
307e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
308e5c31af7Sopenharmony_ci	{
309e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
310e5c31af7Sopenharmony_ci			continue; // Don't upload.
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
313e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
314e5c31af7Sopenharmony_ci		gl.texSubImage2D(GL_TEXTURE_2D, levelNdx, 0, 0, access.getWidth(), access.getHeight(),  transferFormat.format, transferFormat.dataType, access.getDataPtr());
315e5c31af7Sopenharmony_ci	}
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
318e5c31af7Sopenharmony_ci}
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci// TextureCube
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_ciTextureCube::TextureCube (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
323e5c31af7Sopenharmony_ci	: m_context			(context)
324e5c31af7Sopenharmony_ci	, m_isCompressed	(true)
325e5c31af7Sopenharmony_ci	, m_format			(getGLFormat(levels[0].getFormat()))
326e5c31af7Sopenharmony_ci	, m_refTexture		(getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), isES2Context(context.getType()))
327e5c31af7Sopenharmony_ci	, m_glTexture		(0)
328e5c31af7Sopenharmony_ci{
329e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci	TCU_CHECK_INTERNAL(levels[0].getWidth() == levels[0].getHeight());
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_ci	if (!contextInfo.isCompressedTextureFormatSupported(m_format))
334e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
335e5c31af7Sopenharmony_ci
336e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
337e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ci	try
340e5c31af7Sopenharmony_ci	{
341e5c31af7Sopenharmony_ci		loadCompressed(numLevels, levels, decompressionParams);
342e5c31af7Sopenharmony_ci	}
343e5c31af7Sopenharmony_ci	catch (const std::exception&)
344e5c31af7Sopenharmony_ci	{
345e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &m_glTexture);
346e5c31af7Sopenharmony_ci		throw;
347e5c31af7Sopenharmony_ci	}
348e5c31af7Sopenharmony_ci}
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ciTextureCube::TextureCube (const RenderContext& context, deUint32 format, deUint32 dataType, int size)
351e5c31af7Sopenharmony_ci	: m_context			(context)
352e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
353e5c31af7Sopenharmony_ci	, m_format			(format)
354e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), size, isES2Context(context.getType()))
355e5c31af7Sopenharmony_ci	, m_glTexture		(0)
356e5c31af7Sopenharmony_ci{
357e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
358e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
359e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
360e5c31af7Sopenharmony_ci}
361e5c31af7Sopenharmony_ci
362e5c31af7Sopenharmony_ciTextureCube::TextureCube (const RenderContext& context, deUint32 internalFormat, int size)
363e5c31af7Sopenharmony_ci	: m_context			(context)
364e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
365e5c31af7Sopenharmony_ci	, m_format			(internalFormat)
366e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(internalFormat), size, isES2Context(context.getType()))
367e5c31af7Sopenharmony_ci	, m_glTexture		(0)
368e5c31af7Sopenharmony_ci{
369e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
370e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
371e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
372e5c31af7Sopenharmony_ci}
373e5c31af7Sopenharmony_ci
374e5c31af7Sopenharmony_ciTextureCube::~TextureCube (void)
375e5c31af7Sopenharmony_ci{
376e5c31af7Sopenharmony_ci	if (m_glTexture)
377e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
378e5c31af7Sopenharmony_ci}
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_civoid TextureCube::upload (void)
381e5c31af7Sopenharmony_ci{
382e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	DE_ASSERT(!m_isCompressed);
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
387e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
388e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
389e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ci	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
394e5c31af7Sopenharmony_ci	{
395e5c31af7Sopenharmony_ci		for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
396e5c31af7Sopenharmony_ci		{
397e5c31af7Sopenharmony_ci			if (m_refTexture.isLevelEmpty((tcu::CubeFace)face, levelNdx))
398e5c31af7Sopenharmony_ci				continue; // Don't upload.
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ci			tcu::ConstPixelBufferAccess access = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
401e5c31af7Sopenharmony_ci			DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
402e5c31af7Sopenharmony_ci			gl.texImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
403e5c31af7Sopenharmony_ci		}
404e5c31af7Sopenharmony_ci	}
405e5c31af7Sopenharmony_ci
406e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
407e5c31af7Sopenharmony_ci}
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_civoid TextureCube::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
410e5c31af7Sopenharmony_ci{
411e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getFunctions();
412e5c31af7Sopenharmony_ci	deUint32				compressedFormat	= getGLFormat(levels[0].getFormat());
413e5c31af7Sopenharmony_ci
414e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
415e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
416e5c31af7Sopenharmony_ci
417e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
418e5c31af7Sopenharmony_ci	{
419e5c31af7Sopenharmony_ci		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
420e5c31af7Sopenharmony_ci		{
421e5c31af7Sopenharmony_ci			const tcu::CompressedTexture& level = levels[levelNdx*tcu::CUBEFACE_LAST + face];
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ci			// Decompress to reference texture.
424e5c31af7Sopenharmony_ci			m_refTexture.allocLevel((tcu::CubeFace)face, levelNdx);
425e5c31af7Sopenharmony_ci			tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
426e5c31af7Sopenharmony_ci			TCU_CHECK(level.getWidth()	== refLevelAccess.getWidth() &&
427e5c31af7Sopenharmony_ci					  level.getHeight()	== refLevelAccess.getHeight());
428e5c31af7Sopenharmony_ci			level.decompress(refLevelAccess, decompressionParams);
429e5c31af7Sopenharmony_ci
430e5c31af7Sopenharmony_ci			// Upload to GL texture in compressed form.
431e5c31af7Sopenharmony_ci			gl.compressedTexImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, compressedFormat,
432e5c31af7Sopenharmony_ci									level.getWidth(), level.getHeight(), 0 /* border */, level.getDataSize(), level.getData());
433e5c31af7Sopenharmony_ci		}
434e5c31af7Sopenharmony_ci	}
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
437e5c31af7Sopenharmony_ci}
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ciTextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const char* const* filenames)
440e5c31af7Sopenharmony_ci{
441e5c31af7Sopenharmony_ci	DE_ASSERT(numLevels > 0);
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	std::string ext = de::FilePath(filenames[0]).getFileExtension();
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_ci	// \todo [2011-11-21 pyry] Support PNG images.
446e5c31af7Sopenharmony_ci	if (ext == "pkm")
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		// Compressed texture.
449e5c31af7Sopenharmony_ci		int								numImages	= numLevels*tcu::CUBEFACE_LAST;
450e5c31af7Sopenharmony_ci		vector<tcu::CompressedTexture>	levels		(numImages);
451e5c31af7Sopenharmony_ci
452e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < numImages; ndx++)
453e5c31af7Sopenharmony_ci			tcu::ImageIO::loadPKM(levels[ndx], archive, filenames[ndx]);
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci		return new TextureCube(context, contextInfo, numLevels, &levels[0]);
456e5c31af7Sopenharmony_ci	}
457e5c31af7Sopenharmony_ci	else
458e5c31af7Sopenharmony_ci		TCU_FAIL("Unsupported file format");
459e5c31af7Sopenharmony_ci}
460e5c31af7Sopenharmony_ci
461e5c31af7Sopenharmony_ciTextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const std::vector<std::string>& filenames)
462e5c31af7Sopenharmony_ci{
463e5c31af7Sopenharmony_ci	DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
464e5c31af7Sopenharmony_ci	TCU_CHECK(numLevels*tcu::CUBEFACE_LAST == (int)filenames.size());
465e5c31af7Sopenharmony_ci
466e5c31af7Sopenharmony_ci	std::vector<const char*> charPtrs(filenames.size());
467e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)filenames.size(); ndx++)
468e5c31af7Sopenharmony_ci		charPtrs[ndx] = filenames[ndx].c_str();
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci	return TextureCube::create(context, contextInfo, archive, numLevels, &charPtrs[0]);
471e5c31af7Sopenharmony_ci}
472e5c31af7Sopenharmony_ci
473e5c31af7Sopenharmony_ci// Texture1DArray
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ciTexture1DArray::Texture1DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int numLevels)
476e5c31af7Sopenharmony_ci	: m_context			(context)
477e5c31af7Sopenharmony_ci	, m_format			(format)
478e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), width, numLevels)
479e5c31af7Sopenharmony_ci	, m_glTexture		(0)
480e5c31af7Sopenharmony_ci{
481e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
482e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
483e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
484e5c31af7Sopenharmony_ci}
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_ciTexture1DArray::Texture1DArray (const RenderContext& context, deUint32 sizedFormat, int width, int numLevels)
487e5c31af7Sopenharmony_ci	: m_context			(context)
488e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
489e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), width, numLevels)
490e5c31af7Sopenharmony_ci	, m_glTexture		(0)
491e5c31af7Sopenharmony_ci{
492e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
493e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
494e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
495e5c31af7Sopenharmony_ci}
496e5c31af7Sopenharmony_ci
497e5c31af7Sopenharmony_ciTexture1DArray::~Texture1DArray (void)
498e5c31af7Sopenharmony_ci{
499e5c31af7Sopenharmony_ci	if (m_glTexture)
500e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
501e5c31af7Sopenharmony_ci}
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_civoid Texture1DArray::upload (void)
504e5c31af7Sopenharmony_ci{
505e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
508e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_1D_ARRAY, m_glTexture);
509e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
510e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
511e5c31af7Sopenharmony_ci
512e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
515e5c31af7Sopenharmony_ci	{
516e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
517e5c31af7Sopenharmony_ci			continue; // Don't upload.
518e5c31af7Sopenharmony_ci
519e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
520e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
521e5c31af7Sopenharmony_ci		gl.texImage2D(GL_TEXTURE_1D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
522e5c31af7Sopenharmony_ci	}
523e5c31af7Sopenharmony_ci
524e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
525e5c31af7Sopenharmony_ci}
526e5c31af7Sopenharmony_ci
527e5c31af7Sopenharmony_ci// Texture2DArray
528e5c31af7Sopenharmony_ci
529e5c31af7Sopenharmony_ciTexture2DArray::Texture2DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int numLevels)
530e5c31af7Sopenharmony_ci	: m_context			(context)
531e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
532e5c31af7Sopenharmony_ci	, m_format			(format)
533e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), width, height, numLevels)
534e5c31af7Sopenharmony_ci	, m_glTexture		(0)
535e5c31af7Sopenharmony_ci{
536e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
537e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
538e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
539e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
540e5c31af7Sopenharmony_ci}
541e5c31af7Sopenharmony_ci
542e5c31af7Sopenharmony_ciTexture2DArray::Texture2DArray (const RenderContext& context, deUint32 sizedFormat, int width, int height, int numLevels)
543e5c31af7Sopenharmony_ci	: m_context			(context)
544e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
545e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
546e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), width, height, numLevels)
547e5c31af7Sopenharmony_ci	, m_glTexture		(0)
548e5c31af7Sopenharmony_ci{
549e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
550e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
551e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
552e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
553e5c31af7Sopenharmony_ci}
554e5c31af7Sopenharmony_ci
555e5c31af7Sopenharmony_ciTexture2DArray::Texture2DArray (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
556e5c31af7Sopenharmony_ci	: m_context			(context)
557e5c31af7Sopenharmony_ci	, m_isCompressed	(true)
558e5c31af7Sopenharmony_ci	, m_format			(getGLFormat(levels[0].getFormat()))
559e5c31af7Sopenharmony_ci	, m_refTexture		(getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
560e5c31af7Sopenharmony_ci	, m_glTexture		(0)
561e5c31af7Sopenharmony_ci{
562e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
563e5c31af7Sopenharmony_ci
564e5c31af7Sopenharmony_ci	if (!contextInfo.isCompressedTextureFormatSupported(m_format))
565e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
566e5c31af7Sopenharmony_ci
567e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
568e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_ci	try
571e5c31af7Sopenharmony_ci	{
572e5c31af7Sopenharmony_ci		loadCompressed(numLevels, levels, decompressionParams);
573e5c31af7Sopenharmony_ci	}
574e5c31af7Sopenharmony_ci	catch (const std::exception&)
575e5c31af7Sopenharmony_ci	{
576e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &m_glTexture);
577e5c31af7Sopenharmony_ci		throw;
578e5c31af7Sopenharmony_ci	}
579e5c31af7Sopenharmony_ci}
580e5c31af7Sopenharmony_ci
581e5c31af7Sopenharmony_ciTexture2DArray::~Texture2DArray (void)
582e5c31af7Sopenharmony_ci{
583e5c31af7Sopenharmony_ci	if (m_glTexture)
584e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
585e5c31af7Sopenharmony_ci}
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_civoid Texture2DArray::upload (void)
588e5c31af7Sopenharmony_ci{
589e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
590e5c31af7Sopenharmony_ci
591e5c31af7Sopenharmony_ci	if (!gl.texImage3D)
592e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("glTexImage3D() is not supported");
593e5c31af7Sopenharmony_ci
594e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
595e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
596e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
597e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
598e5c31af7Sopenharmony_ci
599e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
600e5c31af7Sopenharmony_ci
601e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
602e5c31af7Sopenharmony_ci	{
603e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
604e5c31af7Sopenharmony_ci			continue; // Don't upload.
605e5c31af7Sopenharmony_ci
606e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
607e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
608e5c31af7Sopenharmony_ci		DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
609e5c31af7Sopenharmony_ci		gl.texImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
610e5c31af7Sopenharmony_ci	}
611e5c31af7Sopenharmony_ci
612e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
613e5c31af7Sopenharmony_ci}
614e5c31af7Sopenharmony_ci
615e5c31af7Sopenharmony_civoid Texture2DArray::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
616e5c31af7Sopenharmony_ci{
617e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getFunctions();
618e5c31af7Sopenharmony_ci	deUint32				compressedFormat	= getGLFormat(levels[0].getFormat());
619e5c31af7Sopenharmony_ci
620e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
621e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
622e5c31af7Sopenharmony_ci
623e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
624e5c31af7Sopenharmony_ci	{
625e5c31af7Sopenharmony_ci		const tcu::CompressedTexture& level = levels[levelNdx];
626e5c31af7Sopenharmony_ci
627e5c31af7Sopenharmony_ci		// Decompress to reference texture.
628e5c31af7Sopenharmony_ci		m_refTexture.allocLevel(levelNdx);
629e5c31af7Sopenharmony_ci		tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
630e5c31af7Sopenharmony_ci		TCU_CHECK(level.getWidth()	== refLevelAccess.getWidth() &&
631e5c31af7Sopenharmony_ci				  level.getHeight()	== refLevelAccess.getHeight() &&
632e5c31af7Sopenharmony_ci				  level.getDepth()	== refLevelAccess.getDepth());
633e5c31af7Sopenharmony_ci		level.decompress(refLevelAccess, decompressionParams);
634e5c31af7Sopenharmony_ci
635e5c31af7Sopenharmony_ci		// Upload to GL texture in compressed form.
636e5c31af7Sopenharmony_ci		gl.compressedTexImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, compressedFormat,
637e5c31af7Sopenharmony_ci								level.getWidth(), level.getHeight(), m_refTexture.getLevel(levelNdx).getDepth(), 0 /* border */, level.getDataSize(), level.getData());
638e5c31af7Sopenharmony_ci	}
639e5c31af7Sopenharmony_ci
640e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
641e5c31af7Sopenharmony_ci}
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci// Texture3D
644e5c31af7Sopenharmony_ci
645e5c31af7Sopenharmony_ciTexture3D::Texture3D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int depth)
646e5c31af7Sopenharmony_ci	: m_context			(context)
647e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
648e5c31af7Sopenharmony_ci	, m_format			(format)
649e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), width, height, depth)
650e5c31af7Sopenharmony_ci	, m_glTexture		(0)
651e5c31af7Sopenharmony_ci{
652e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
653e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
654e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
655e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
656e5c31af7Sopenharmony_ci}
657e5c31af7Sopenharmony_ci
658e5c31af7Sopenharmony_ciTexture3D::Texture3D (const RenderContext& context, deUint32 sizedFormat, int width, int height, int depth)
659e5c31af7Sopenharmony_ci	: m_context			(context)
660e5c31af7Sopenharmony_ci	, m_isCompressed	(false)
661e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
662e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), width, height, depth)
663e5c31af7Sopenharmony_ci	, m_glTexture		(0)
664e5c31af7Sopenharmony_ci{
665e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
666e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
667e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
668e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
669e5c31af7Sopenharmony_ci}
670e5c31af7Sopenharmony_ci
671e5c31af7Sopenharmony_ciTexture3D::Texture3D (const RenderContext&					context,
672e5c31af7Sopenharmony_ci					  const ContextInfo&					contextInfo,
673e5c31af7Sopenharmony_ci					  int									numLevels,
674e5c31af7Sopenharmony_ci					  const tcu::CompressedTexture*			levels,
675e5c31af7Sopenharmony_ci					  const tcu::TexDecompressionParams&	decompressionParams)
676e5c31af7Sopenharmony_ci	: m_context			(context)
677e5c31af7Sopenharmony_ci	, m_isCompressed	(true)
678e5c31af7Sopenharmony_ci	, m_format			(getGLFormat(levels[0].getFormat()))
679e5c31af7Sopenharmony_ci	, m_refTexture		(getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
680e5c31af7Sopenharmony_ci	, m_glTexture		(0)
681e5c31af7Sopenharmony_ci{
682e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getFunctions();
683e5c31af7Sopenharmony_ci
684e5c31af7Sopenharmony_ci	if (!contextInfo.isCompressedTextureFormatSupported(m_format))
685e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
686e5c31af7Sopenharmony_ci
687e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
688e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci	try
691e5c31af7Sopenharmony_ci	{
692e5c31af7Sopenharmony_ci		loadCompressed(numLevels, levels, decompressionParams);
693e5c31af7Sopenharmony_ci	}
694e5c31af7Sopenharmony_ci	catch (const std::exception&)
695e5c31af7Sopenharmony_ci	{
696e5c31af7Sopenharmony_ci		gl.deleteTextures(1, &m_glTexture);
697e5c31af7Sopenharmony_ci		throw;
698e5c31af7Sopenharmony_ci	}
699e5c31af7Sopenharmony_ci}
700e5c31af7Sopenharmony_ci
701e5c31af7Sopenharmony_ciTexture3D::~Texture3D (void)
702e5c31af7Sopenharmony_ci{
703e5c31af7Sopenharmony_ci	if (m_glTexture)
704e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
705e5c31af7Sopenharmony_ci}
706e5c31af7Sopenharmony_ci
707e5c31af7Sopenharmony_civoid Texture3D::upload (void)
708e5c31af7Sopenharmony_ci{
709e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
710e5c31af7Sopenharmony_ci
711e5c31af7Sopenharmony_ci	DE_ASSERT(!m_isCompressed);
712e5c31af7Sopenharmony_ci
713e5c31af7Sopenharmony_ci	if (!gl.texImage3D)
714e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("glTexImage3D() is not supported");
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
717e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
718e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
719e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
720e5c31af7Sopenharmony_ci
721e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
722e5c31af7Sopenharmony_ci
723e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
724e5c31af7Sopenharmony_ci	{
725e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
726e5c31af7Sopenharmony_ci			continue; // Don't upload.
727e5c31af7Sopenharmony_ci
728e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
729e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
730e5c31af7Sopenharmony_ci		DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
731e5c31af7Sopenharmony_ci		gl.texImage3D(GL_TEXTURE_3D, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
732e5c31af7Sopenharmony_ci	}
733e5c31af7Sopenharmony_ci
734e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
735e5c31af7Sopenharmony_ci}
736e5c31af7Sopenharmony_ci
737e5c31af7Sopenharmony_civoid Texture3D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
738e5c31af7Sopenharmony_ci{
739e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getFunctions();
740e5c31af7Sopenharmony_ci	deUint32				compressedFormat	= getGLFormat(levels[0].getFormat());
741e5c31af7Sopenharmony_ci
742e5c31af7Sopenharmony_ci	if (!gl.compressedTexImage3D)
743e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("glCompressedTexImage3D() is not supported");
744e5c31af7Sopenharmony_ci
745e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
746e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
747e5c31af7Sopenharmony_ci
748e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
749e5c31af7Sopenharmony_ci	{
750e5c31af7Sopenharmony_ci		const tcu::CompressedTexture& level = levels[levelNdx];
751e5c31af7Sopenharmony_ci
752e5c31af7Sopenharmony_ci		// Decompress to reference texture.
753e5c31af7Sopenharmony_ci		m_refTexture.allocLevel(levelNdx);
754e5c31af7Sopenharmony_ci		tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
755e5c31af7Sopenharmony_ci		TCU_CHECK(level.getWidth()	== refLevelAccess.getWidth() &&
756e5c31af7Sopenharmony_ci				  level.getHeight()	== refLevelAccess.getHeight() &&
757e5c31af7Sopenharmony_ci				  level.getDepth()	== refLevelAccess.getDepth());
758e5c31af7Sopenharmony_ci		level.decompress(refLevelAccess, decompressionParams);
759e5c31af7Sopenharmony_ci
760e5c31af7Sopenharmony_ci		// Upload to GL texture in compressed form.
761e5c31af7Sopenharmony_ci		gl.compressedTexImage3D(GL_TEXTURE_3D, levelNdx, compressedFormat,
762e5c31af7Sopenharmony_ci								level.getWidth(), level.getHeight(), level.getDepth(), 0 /* border */, level.getDataSize(), level.getData());
763e5c31af7Sopenharmony_ci	}
764e5c31af7Sopenharmony_ci
765e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
766e5c31af7Sopenharmony_ci}
767e5c31af7Sopenharmony_ci
768e5c31af7Sopenharmony_ci// TextureCubeArray
769e5c31af7Sopenharmony_ci
770e5c31af7Sopenharmony_ciTextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 format, deUint32 dataType, int size, int numLayers)
771e5c31af7Sopenharmony_ci	: m_context			(context)
772e5c31af7Sopenharmony_ci	, m_format			(format)
773e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLTransferFormat(format, dataType), size, numLayers)
774e5c31af7Sopenharmony_ci	, m_glTexture		(0)
775e5c31af7Sopenharmony_ci{
776e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
777e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
778e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
779e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
780e5c31af7Sopenharmony_ci}
781e5c31af7Sopenharmony_ci
782e5c31af7Sopenharmony_ciTextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 sizedFormat, int size, int numLayers)
783e5c31af7Sopenharmony_ci	: m_context			(context)
784e5c31af7Sopenharmony_ci	, m_format			(sizedFormat)
785e5c31af7Sopenharmony_ci	, m_refTexture		(mapGLInternalFormat(sizedFormat), size, numLayers)
786e5c31af7Sopenharmony_ci	, m_glTexture		(0)
787e5c31af7Sopenharmony_ci{
788e5c31af7Sopenharmony_ci	// \todo [2013-04-08 pyry] Check support here.
789e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
790e5c31af7Sopenharmony_ci	gl.genTextures(1, &m_glTexture);
791e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
792e5c31af7Sopenharmony_ci}
793e5c31af7Sopenharmony_ci
794e5c31af7Sopenharmony_ciTextureCubeArray::~TextureCubeArray (void)
795e5c31af7Sopenharmony_ci{
796e5c31af7Sopenharmony_ci	if (m_glTexture)
797e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
798e5c31af7Sopenharmony_ci}
799e5c31af7Sopenharmony_ci
800e5c31af7Sopenharmony_civoid TextureCubeArray::upload (void)
801e5c31af7Sopenharmony_ci{
802e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
803e5c31af7Sopenharmony_ci
804e5c31af7Sopenharmony_ci	if (!gl.texImage3D)
805e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("glTexImage3D() is not supported");
806e5c31af7Sopenharmony_ci
807e5c31af7Sopenharmony_ci	TCU_CHECK(m_glTexture);
808e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_glTexture);
809e5c31af7Sopenharmony_ci	gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
810e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
811e5c31af7Sopenharmony_ci
812e5c31af7Sopenharmony_ci	TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
813e5c31af7Sopenharmony_ci
814e5c31af7Sopenharmony_ci	for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
815e5c31af7Sopenharmony_ci	{
816e5c31af7Sopenharmony_ci		if (m_refTexture.isLevelEmpty(levelNdx))
817e5c31af7Sopenharmony_ci			continue; // Don't upload.
818e5c31af7Sopenharmony_ci
819e5c31af7Sopenharmony_ci		tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
820e5c31af7Sopenharmony_ci		DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
821e5c31af7Sopenharmony_ci		DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
822e5c31af7Sopenharmony_ci		gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
823e5c31af7Sopenharmony_ci	}
824e5c31af7Sopenharmony_ci
825e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
826e5c31af7Sopenharmony_ci}
827e5c31af7Sopenharmony_ci
828e5c31af7Sopenharmony_ci// TextureBuffer
829e5c31af7Sopenharmony_ci
830e5c31af7Sopenharmony_ciTextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize)
831e5c31af7Sopenharmony_ci	: m_context			(context)
832e5c31af7Sopenharmony_ci	, m_format			(0)
833e5c31af7Sopenharmony_ci	, m_offset			(0)
834e5c31af7Sopenharmony_ci	, m_size			(0)
835e5c31af7Sopenharmony_ci	, m_glTexture		(0)
836e5c31af7Sopenharmony_ci	, m_glBuffer		(0)
837e5c31af7Sopenharmony_ci{
838e5c31af7Sopenharmony_ci	init(internalFormat, bufferSize, 0, 0, DE_NULL);
839e5c31af7Sopenharmony_ci}
840e5c31af7Sopenharmony_ci
841e5c31af7Sopenharmony_ciTextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
842e5c31af7Sopenharmony_ci	: m_context			(context)
843e5c31af7Sopenharmony_ci	, m_format			(0)
844e5c31af7Sopenharmony_ci	, m_offset			(0)
845e5c31af7Sopenharmony_ci	, m_size			(0)
846e5c31af7Sopenharmony_ci	, m_glTexture		(0)
847e5c31af7Sopenharmony_ci	, m_glBuffer		(0)
848e5c31af7Sopenharmony_ci{
849e5c31af7Sopenharmony_ci	init(internalFormat, bufferSize, offset, size, data);
850e5c31af7Sopenharmony_ci}
851e5c31af7Sopenharmony_ci
852e5c31af7Sopenharmony_civoid TextureBuffer::init (deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
853e5c31af7Sopenharmony_ci{
854e5c31af7Sopenharmony_ci	const glw::Functions&		gl		= m_context.getFunctions();
855e5c31af7Sopenharmony_ci	de::UniquePtr<ContextInfo>	info	(ContextInfo::create(m_context));
856e5c31af7Sopenharmony_ci
857e5c31af7Sopenharmony_ci	if (offset != 0 || size != 0)
858e5c31af7Sopenharmony_ci	{
859e5c31af7Sopenharmony_ci		if (!(contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE)) && info->isExtensionSupported("GL_ARB_texture_buffer_range"))
860e5c31af7Sopenharmony_ci			&& !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
861e5c31af7Sopenharmony_ci				&& info->isExtensionSupported("GL_EXT_texture_buffer")))
862e5c31af7Sopenharmony_ci		{
863e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Ranged texture buffers not supported", "", __FILE__, __LINE__);
864e5c31af7Sopenharmony_ci		}
865e5c31af7Sopenharmony_ci	}
866e5c31af7Sopenharmony_ci	else
867e5c31af7Sopenharmony_ci	{
868e5c31af7Sopenharmony_ci		if (!contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE))
869e5c31af7Sopenharmony_ci			&& !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
870e5c31af7Sopenharmony_ci				&& info->isExtensionSupported("GL_EXT_texture_buffer")))
871e5c31af7Sopenharmony_ci		{
872e5c31af7Sopenharmony_ci			throw tcu::NotSupportedError("Texture buffers not supported", "", __FILE__, __LINE__);
873e5c31af7Sopenharmony_ci		}
874e5c31af7Sopenharmony_ci	}
875e5c31af7Sopenharmony_ci
876e5c31af7Sopenharmony_ci	m_refBuffer.setStorage(bufferSize);
877e5c31af7Sopenharmony_ci	if (data)
878e5c31af7Sopenharmony_ci		deMemcpy(m_refBuffer.getPtr(), data, (int)bufferSize);
879e5c31af7Sopenharmony_ci
880e5c31af7Sopenharmony_ci	m_format	= internalFormat;
881e5c31af7Sopenharmony_ci	m_offset	= offset;
882e5c31af7Sopenharmony_ci	m_size		= size;
883e5c31af7Sopenharmony_ci
884e5c31af7Sopenharmony_ci	DE_ASSERT(size != 0 || offset == 0);
885e5c31af7Sopenharmony_ci
886e5c31af7Sopenharmony_ci	{
887e5c31af7Sopenharmony_ci		gl.genTextures(1, &m_glTexture);
888e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
889e5c31af7Sopenharmony_ci
890e5c31af7Sopenharmony_ci		gl.genBuffers(1, &m_glBuffer);
891e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
892e5c31af7Sopenharmony_ci
893e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
894e5c31af7Sopenharmony_ci		gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), data, GL_STATIC_DRAW);
895e5c31af7Sopenharmony_ci		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
896e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer");
897e5c31af7Sopenharmony_ci
898e5c31af7Sopenharmony_ci		gl.bindTexture(GL_TEXTURE_BUFFER, m_glTexture);
899e5c31af7Sopenharmony_ci
900e5c31af7Sopenharmony_ci		if (offset != 0 || size != 0)
901e5c31af7Sopenharmony_ci			gl.texBufferRange(GL_TEXTURE_BUFFER, m_format, m_glBuffer, (glw::GLintptr)m_offset, (glw::GLsizeiptr)m_size);
902e5c31af7Sopenharmony_ci		else
903e5c31af7Sopenharmony_ci			gl.texBuffer(GL_TEXTURE_BUFFER, m_format, m_glBuffer);
904e5c31af7Sopenharmony_ci
905e5c31af7Sopenharmony_ci		gl.bindTexture(GL_TEXTURE_BUFFER, 0);
906e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffer to texture");
907e5c31af7Sopenharmony_ci	}
908e5c31af7Sopenharmony_ci}
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ciTextureBuffer::~TextureBuffer (void)
911e5c31af7Sopenharmony_ci{
912e5c31af7Sopenharmony_ci	if (m_glTexture)
913e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteTextures(1, &m_glTexture);
914e5c31af7Sopenharmony_ci
915e5c31af7Sopenharmony_ci	if (m_glBuffer)
916e5c31af7Sopenharmony_ci		m_context.getFunctions().deleteBuffers(1, &m_glBuffer);
917e5c31af7Sopenharmony_ci}
918e5c31af7Sopenharmony_ci
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ciconst tcu::PixelBufferAccess TextureBuffer::getFullRefTexture (void)
921e5c31af7Sopenharmony_ci{
922e5c31af7Sopenharmony_ci	const tcu::TextureFormat	format				= mapGLInternalFormat(m_format);
923e5c31af7Sopenharmony_ci	const size_t				bufferLengthBytes	= (m_size != 0) ? (m_size) : (m_refBuffer.size());
924e5c31af7Sopenharmony_ci	const int					bufferLengthPixels	= (int)bufferLengthBytes / format.getPixelSize();
925e5c31af7Sopenharmony_ci
926e5c31af7Sopenharmony_ci	return tcu::PixelBufferAccess(format,
927e5c31af7Sopenharmony_ci								  tcu::IVec3(bufferLengthPixels, 1, 1),
928e5c31af7Sopenharmony_ci								  (deUint8*)m_refBuffer.getPtr() + m_offset);
929e5c31af7Sopenharmony_ci}
930e5c31af7Sopenharmony_ci
931e5c31af7Sopenharmony_ciconst tcu::ConstPixelBufferAccess TextureBuffer::getFullRefTexture (void) const
932e5c31af7Sopenharmony_ci{
933e5c31af7Sopenharmony_ci	return const_cast<TextureBuffer*>(this)->getFullRefTexture();
934e5c31af7Sopenharmony_ci}
935e5c31af7Sopenharmony_ci
936e5c31af7Sopenharmony_civoid TextureBuffer::upload (void)
937e5c31af7Sopenharmony_ci{
938e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getFunctions();
939e5c31af7Sopenharmony_ci
940e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
941e5c31af7Sopenharmony_ci	gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), m_refBuffer.getPtr(), GL_STATIC_DRAW);
942e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
943e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload buffer");
944e5c31af7Sopenharmony_ci}
945e5c31af7Sopenharmony_ci
946e5c31af7Sopenharmony_ci} // glu
947