1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Texture classes.
22 *//*--------------------------------------------------------------------*/
24 #include "gluTexture.hpp"
25 #include "gluTextureUtil.hpp"
26 #include "deFilePath.hpp"
27 #include "tcuImageIO.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
31 #include "glwFunctions.hpp"
32 #include "glwEnums.hpp"
34 #include "deUniquePtr.hpp"
41 static inline int computePixelStore (const tcu::TextureFormat& format)
43 int pixelSize = format.getPixelSize();
44 if (deIsPowerOfTwo32(pixelSize))
45 return de::min(pixelSize, 8);
52 Texture1D::Texture1D (const RenderContext& context, deUint32 format, deUint32 dataType, int width)
55 , m_refTexture (mapGLTransferFormat(format, dataType), width)
58 const glw::Functions& gl = context.getFunctions();
59 gl.genTextures(1, &m_glTexture);
60 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
63 Texture1D::Texture1D (const RenderContext& context, deUint32 sizedFormat, int width)
65 , m_format (sizedFormat)
66 , m_refTexture (mapGLInternalFormat(sizedFormat), width)
69 const glw::Functions& gl = context.getFunctions();
70 gl.genTextures(1, &m_glTexture);
71 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
74 Texture1D::~Texture1D (void)
77 m_context.getFunctions().deleteTextures(1, &m_glTexture);
80 void Texture1D::upload (void)
82 const glw::Functions& gl = m_context.getFunctions();
84 TCU_CHECK(m_glTexture);
85 gl.bindTexture(GL_TEXTURE_1D, m_glTexture);
86 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
87 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
89 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
91 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
93 if (m_refTexture.isLevelEmpty(levelNdx))
94 continue; // Don't upload.
96 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
97 gl.texImage1D(GL_TEXTURE_1D, levelNdx, m_format, access.getWidth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
100 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
105 Texture2D::Texture2D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height)
106 : m_context (context)
107 , m_isCompressed (false)
109 , m_refTexture (mapGLTransferFormat(format, dataType), width, height)
112 const glw::Functions& gl = context.getFunctions();
113 gl.genTextures(1, &m_glTexture);
114 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
117 Texture2D::Texture2D (const RenderContext& context, deUint32 sizedFormat, int width, int height)
118 : m_context (context)
119 , m_isCompressed (false)
120 , m_format (sizedFormat)
121 , m_refTexture (mapGLInternalFormat(sizedFormat), width, height)
124 const glw::Functions& gl = context.getFunctions();
125 gl.genTextures(1, &m_glTexture);
126 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
129 Texture2D::Texture2D (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
130 : m_context (context)
131 , m_isCompressed (true)
132 , m_format (getGLFormat(levels[0].getFormat()))
133 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight())
136 const glw::Functions& gl = context.getFunctions();
138 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
139 TCU_THROW(NotSupportedError, "Compressed texture format not supported");
141 gl.genTextures(1, &m_glTexture);
142 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
146 loadCompressed(numLevels, levels, decompressionParams);
148 catch (const std::exception&)
150 gl.deleteTextures(1, &m_glTexture);
155 Texture2D::~Texture2D (void)
158 m_context.getFunctions().deleteTextures(1, &m_glTexture);
161 void Texture2D::upload (void)
163 const glw::Functions& gl = m_context.getFunctions();
165 DE_ASSERT(!m_isCompressed);
167 TCU_CHECK(m_glTexture);
168 gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
169 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
170 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
172 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
174 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
176 if (m_refTexture.isLevelEmpty(levelNdx))
177 continue; // Don't upload.
179 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
180 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
181 gl.texImage2D(GL_TEXTURE_2D, levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
184 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
187 void Texture2D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
189 const glw::Functions& gl = m_context.getFunctions();
190 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
192 TCU_CHECK(m_glTexture);
193 gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
195 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
197 const tcu::CompressedTexture& level = levels[levelNdx];
199 // Decompress to reference texture.
200 m_refTexture.allocLevel(levelNdx);
201 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
202 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
203 level.getHeight() == refLevelAccess.getHeight());
204 level.decompress(refLevelAccess, decompressionParams);
206 // Upload to GL texture in compressed form.
207 gl.compressedTexImage2D(GL_TEXTURE_2D, levelNdx, compressedFormat,
208 level.getWidth(), level.getHeight(), 0 /* border */, level.getDataSize(), level.getData());
211 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
214 Texture2D* Texture2D::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const char* const* levelFileNames)
216 DE_ASSERT(numLevels > 0);
218 std::string ext = de::FilePath(levelFileNames[0]).getFileExtension();
222 // Uncompressed texture.
224 tcu::TextureLevel level;
227 tcu::ImageIO::loadPNG(level, archive, levelFileNames[0]);
229 TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
230 level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
232 bool isRGBA = level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
233 Texture2D* texture = new Texture2D(context, isRGBA ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, level.getWidth(), level.getHeight());
238 texture->getRefTexture().allocLevel(0);
239 tcu::copy(texture->getRefTexture().getLevel(0), level.getAccess());
241 // Fill remaining levels.
242 for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
244 tcu::ImageIO::loadPNG(level, archive, levelFileNames[levelNdx]);
246 texture->getRefTexture().allocLevel(levelNdx);
247 tcu::copy(texture->getRefTexture().getLevel(levelNdx), level.getAccess());
253 catch (const std::exception&)
261 else if (ext == "pkm")
263 // Compressed texture.
264 vector<tcu::CompressedTexture> levels(numLevels);
266 for (int ndx = 0; ndx < numLevels; ndx++)
267 tcu::ImageIO::loadPKM(levels[ndx], archive, levelFileNames[ndx]);
269 return new Texture2D(context, contextInfo, numLevels, &levels[0]);
272 TCU_FAIL("Unsupported file format");
275 Texture2D* Texture2D::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const std::vector<std::string>& filenames)
277 TCU_CHECK(numLevels == (int)filenames.size());
279 std::vector<const char*> charPtrs(filenames.size());
280 for (int ndx = 0; ndx < (int)filenames.size(); ndx++)
281 charPtrs[ndx] = filenames[ndx].c_str();
283 return Texture2D::create(context, contextInfo, archive, numLevels, &charPtrs[0]);
286 // ImmutableTexture2D
288 ImmutableTexture2D::ImmutableTexture2D (const RenderContext& context, deUint32 sizedFormat, int width, int height)
289 : Texture2D(context, sizedFormat, width, height)
293 void ImmutableTexture2D::upload (void)
295 const glw::Functions& gl = m_context.getFunctions();
297 DE_ASSERT(!m_isCompressed);
299 TCU_CHECK(m_glTexture);
300 gl.bindTexture(GL_TEXTURE_2D, m_glTexture);
301 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
302 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
304 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
306 gl.texStorage2D(GL_TEXTURE_2D, m_refTexture.getNumLevels(), m_format, m_refTexture.getWidth(), m_refTexture.getHeight());
307 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
309 if (m_refTexture.isLevelEmpty(levelNdx))
310 continue; // Don't upload.
312 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
313 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
314 gl.texSubImage2D(GL_TEXTURE_2D, levelNdx, 0, 0, access.getWidth(), access.getHeight(), transferFormat.format, transferFormat.dataType, access.getDataPtr());
317 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
322 TextureCube::TextureCube (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
323 : m_context (context)
324 , m_isCompressed (true)
325 , m_format (getGLFormat(levels[0].getFormat()))
326 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth())
329 const glw::Functions& gl = m_context.getFunctions();
331 TCU_CHECK_INTERNAL(levels[0].getWidth() == levels[0].getHeight());
333 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
334 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
336 gl.genTextures(1, &m_glTexture);
337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
341 loadCompressed(numLevels, levels, decompressionParams);
343 catch (const std::exception&)
345 gl.deleteTextures(1, &m_glTexture);
350 TextureCube::TextureCube (const RenderContext& context, deUint32 format, deUint32 dataType, int size)
351 : m_context (context)
352 , m_isCompressed (false)
354 , m_refTexture (mapGLTransferFormat(format, dataType), size)
357 const glw::Functions& gl = m_context.getFunctions();
358 gl.genTextures(1, &m_glTexture);
359 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
362 TextureCube::TextureCube (const RenderContext& context, deUint32 internalFormat, int size)
363 : m_context (context)
364 , m_isCompressed (false)
365 , m_format (internalFormat)
366 , m_refTexture (mapGLInternalFormat(internalFormat), size)
369 const glw::Functions& gl = m_context.getFunctions();
370 gl.genTextures(1, &m_glTexture);
371 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
374 TextureCube::~TextureCube (void)
377 m_context.getFunctions().deleteTextures(1, &m_glTexture);
380 void TextureCube::upload (void)
382 const glw::Functions& gl = m_context.getFunctions();
384 DE_ASSERT(!m_isCompressed);
386 TCU_CHECK(m_glTexture);
387 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
388 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
389 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
391 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
393 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
395 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
397 if (m_refTexture.isLevelEmpty((tcu::CubeFace)face, levelNdx))
398 continue; // Don't upload.
400 tcu::ConstPixelBufferAccess access = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
401 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
402 gl.texImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
406 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
409 void TextureCube::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
411 const glw::Functions& gl = m_context.getFunctions();
412 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
414 TCU_CHECK(m_glTexture);
415 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
417 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
419 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
421 const tcu::CompressedTexture& level = levels[levelNdx*tcu::CUBEFACE_LAST + face];
423 // Decompress to reference texture.
424 m_refTexture.allocLevel((tcu::CubeFace)face, levelNdx);
425 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
426 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
427 level.getHeight() == refLevelAccess.getHeight());
428 level.decompress(refLevelAccess, decompressionParams);
430 // Upload to GL texture in compressed form.
431 gl.compressedTexImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, compressedFormat,
432 level.getWidth(), level.getHeight(), 0 /* border */, level.getDataSize(), level.getData());
436 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
439 TextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const char* const* filenames)
441 DE_ASSERT(numLevels > 0);
443 std::string ext = de::FilePath(filenames[0]).getFileExtension();
445 // \todo [2011-11-21 pyry] Support PNG images.
448 // Compressed texture.
449 int numImages = numLevels*tcu::CUBEFACE_LAST;
450 vector<tcu::CompressedTexture> levels (numImages);
452 for (int ndx = 0; ndx < numImages; ndx++)
453 tcu::ImageIO::loadPKM(levels[ndx], archive, filenames[ndx]);
455 return new TextureCube(context, contextInfo, numLevels, &levels[0]);
458 TCU_FAIL("Unsupported file format");
461 TextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const std::vector<std::string>& filenames)
463 DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
464 TCU_CHECK(numLevels*tcu::CUBEFACE_LAST == (int)filenames.size());
466 std::vector<const char*> charPtrs(filenames.size());
467 for (int ndx = 0; ndx < (int)filenames.size(); ndx++)
468 charPtrs[ndx] = filenames[ndx].c_str();
470 return TextureCube::create(context, contextInfo, archive, numLevels, &charPtrs[0]);
475 Texture1DArray::Texture1DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int numLevels)
476 : m_context (context)
478 , m_refTexture (mapGLTransferFormat(format, dataType), width, numLevels)
481 const glw::Functions& gl = m_context.getFunctions();
482 gl.genTextures(1, &m_glTexture);
483 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
486 Texture1DArray::Texture1DArray (const RenderContext& context, deUint32 sizedFormat, int width, int numLevels)
487 : m_context (context)
488 , m_format (sizedFormat)
489 , m_refTexture (mapGLInternalFormat(sizedFormat), width, numLevels)
492 const glw::Functions& gl = m_context.getFunctions();
493 gl.genTextures(1, &m_glTexture);
494 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
497 Texture1DArray::~Texture1DArray (void)
500 m_context.getFunctions().deleteTextures(1, &m_glTexture);
503 void Texture1DArray::upload (void)
505 const glw::Functions& gl = m_context.getFunctions();
507 TCU_CHECK(m_glTexture);
508 gl.bindTexture(GL_TEXTURE_1D_ARRAY, m_glTexture);
509 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
510 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
512 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
514 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
516 if (m_refTexture.isLevelEmpty(levelNdx))
517 continue; // Don't upload.
519 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
520 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
521 gl.texImage2D(GL_TEXTURE_1D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
524 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
529 Texture2DArray::Texture2DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int numLevels)
530 : m_context (context)
531 , m_isCompressed (false)
533 , m_refTexture (mapGLTransferFormat(format, dataType), width, height, numLevels)
536 // \todo [2013-04-08 pyry] Check support here.
537 const glw::Functions& gl = m_context.getFunctions();
538 gl.genTextures(1, &m_glTexture);
539 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
542 Texture2DArray::Texture2DArray (const RenderContext& context, deUint32 sizedFormat, int width, int height, int numLevels)
543 : m_context (context)
544 , m_isCompressed (false)
545 , m_format (sizedFormat)
546 , m_refTexture (mapGLInternalFormat(sizedFormat), width, height, numLevels)
549 // \todo [2013-04-08 pyry] Check support here.
550 const glw::Functions& gl = m_context.getFunctions();
551 gl.genTextures(1, &m_glTexture);
552 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
555 Texture2DArray::Texture2DArray (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
556 : m_context (context)
557 , m_isCompressed (true)
558 , m_format (getGLFormat(levels[0].getFormat()))
559 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
562 const glw::Functions& gl = context.getFunctions();
564 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
565 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
567 gl.genTextures(1, &m_glTexture);
568 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
572 loadCompressed(numLevels, levels, decompressionParams);
574 catch (const std::exception&)
576 gl.deleteTextures(1, &m_glTexture);
581 Texture2DArray::~Texture2DArray (void)
584 m_context.getFunctions().deleteTextures(1, &m_glTexture);
587 void Texture2DArray::upload (void)
589 const glw::Functions& gl = m_context.getFunctions();
592 throw tcu::NotSupportedError("glTexImage3D() is not supported");
594 TCU_CHECK(m_glTexture);
595 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
596 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
597 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
599 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
601 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
603 if (m_refTexture.isLevelEmpty(levelNdx))
604 continue; // Don't upload.
606 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
607 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
608 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
609 gl.texImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
612 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
615 void Texture2DArray::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
617 const glw::Functions& gl = m_context.getFunctions();
618 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
620 TCU_CHECK(m_glTexture);
621 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
623 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
625 const tcu::CompressedTexture& level = levels[levelNdx];
627 // Decompress to reference texture.
628 m_refTexture.allocLevel(levelNdx);
629 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
630 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
631 level.getHeight() == refLevelAccess.getHeight() &&
632 level.getDepth() == refLevelAccess.getDepth());
633 level.decompress(refLevelAccess, decompressionParams);
635 // Upload to GL texture in compressed form.
636 gl.compressedTexImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, compressedFormat,
637 level.getWidth(), level.getHeight(), m_refTexture.getLevel(levelNdx).getDepth(), 0 /* border */, level.getDataSize(), level.getData());
640 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
645 Texture3D::Texture3D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int depth)
646 : m_context (context)
647 , m_isCompressed (false)
649 , m_refTexture (mapGLTransferFormat(format, dataType), width, height, depth)
652 // \todo [2013-04-08 pyry] Check support here.
653 const glw::Functions& gl = m_context.getFunctions();
654 gl.genTextures(1, &m_glTexture);
655 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
658 Texture3D::Texture3D (const RenderContext& context, deUint32 sizedFormat, int width, int height, int depth)
659 : m_context (context)
660 , m_isCompressed (false)
661 , m_format (sizedFormat)
662 , m_refTexture (mapGLInternalFormat(sizedFormat), width, height, depth)
665 // \todo [2013-04-08 pyry] Check support here.
666 const glw::Functions& gl = m_context.getFunctions();
667 gl.genTextures(1, &m_glTexture);
668 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
671 Texture3D::Texture3D (const RenderContext& context,
672 const ContextInfo& contextInfo,
674 const tcu::CompressedTexture* levels,
675 const tcu::TexDecompressionParams& decompressionParams)
676 : m_context (context)
677 , m_isCompressed (true)
678 , m_format (getGLFormat(levels[0].getFormat()))
679 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
682 const glw::Functions& gl = context.getFunctions();
684 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
685 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
687 gl.genTextures(1, &m_glTexture);
688 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
692 loadCompressed(numLevels, levels, decompressionParams);
694 catch (const std::exception&)
696 gl.deleteTextures(1, &m_glTexture);
701 Texture3D::~Texture3D (void)
704 m_context.getFunctions().deleteTextures(1, &m_glTexture);
707 void Texture3D::upload (void)
709 const glw::Functions& gl = m_context.getFunctions();
711 DE_ASSERT(!m_isCompressed);
714 throw tcu::NotSupportedError("glTexImage3D() is not supported");
716 TCU_CHECK(m_glTexture);
717 gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
718 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
719 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
721 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
723 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
725 if (m_refTexture.isLevelEmpty(levelNdx))
726 continue; // Don't upload.
728 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
729 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
730 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
731 gl.texImage3D(GL_TEXTURE_3D, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
734 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
737 void Texture3D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
739 const glw::Functions& gl = m_context.getFunctions();
740 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
742 if (!gl.compressedTexImage3D)
743 throw tcu::NotSupportedError("glCompressedTexImage3D() is not supported");
745 TCU_CHECK(m_glTexture);
746 gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
748 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
750 const tcu::CompressedTexture& level = levels[levelNdx];
752 // Decompress to reference texture.
753 m_refTexture.allocLevel(levelNdx);
754 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
755 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
756 level.getHeight() == refLevelAccess.getHeight() &&
757 level.getDepth() == refLevelAccess.getDepth());
758 level.decompress(refLevelAccess, decompressionParams);
760 // Upload to GL texture in compressed form.
761 gl.compressedTexImage3D(GL_TEXTURE_3D, levelNdx, compressedFormat,
762 level.getWidth(), level.getHeight(), level.getDepth(), 0 /* border */, level.getDataSize(), level.getData());
765 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
770 TextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 format, deUint32 dataType, int size, int numLayers)
771 : m_context (context)
773 , m_refTexture (mapGLTransferFormat(format, dataType), size, numLayers)
776 // \todo [2013-04-08 pyry] Check support here.
777 const glw::Functions& gl = m_context.getFunctions();
778 gl.genTextures(1, &m_glTexture);
779 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
782 TextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 sizedFormat, int size, int numLayers)
783 : m_context (context)
784 , m_format (sizedFormat)
785 , m_refTexture (mapGLInternalFormat(sizedFormat), size, numLayers)
788 // \todo [2013-04-08 pyry] Check support here.
789 const glw::Functions& gl = m_context.getFunctions();
790 gl.genTextures(1, &m_glTexture);
791 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
794 TextureCubeArray::~TextureCubeArray (void)
797 m_context.getFunctions().deleteTextures(1, &m_glTexture);
800 void TextureCubeArray::upload (void)
802 const glw::Functions& gl = m_context.getFunctions();
805 throw tcu::NotSupportedError("glTexImage3D() is not supported");
807 TCU_CHECK(m_glTexture);
808 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_glTexture);
809 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
810 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
812 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
814 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
816 if (m_refTexture.isLevelEmpty(levelNdx))
817 continue; // Don't upload.
819 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
820 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
821 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
822 gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
825 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
830 TextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize)
831 : m_context (context)
838 init(internalFormat, bufferSize, 0, 0, DE_NULL);
841 TextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
842 : m_context (context)
849 init(internalFormat, bufferSize, offset, size, data);
852 void TextureBuffer::init (deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
854 const glw::Functions& gl = m_context.getFunctions();
855 de::UniquePtr<ContextInfo> info (ContextInfo::create(m_context));
857 if (offset != 0 || size != 0)
859 if (!(contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE)) && info->isExtensionSupported("GL_ARB_texture_buffer_range"))
860 && !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
861 && info->isExtensionSupported("GL_EXT_texture_buffer")))
863 throw tcu::NotSupportedError("Ranged texture buffers not supported", "", __FILE__, __LINE__);
868 if (!contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE))
869 && !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
870 && info->isExtensionSupported("GL_EXT_texture_buffer")))
872 throw tcu::NotSupportedError("Texture buffers not supported", "", __FILE__, __LINE__);
876 m_refBuffer.setStorage(bufferSize);
878 deMemcpy(m_refBuffer.getPtr(), data, (int)bufferSize);
880 m_format = internalFormat;
884 DE_ASSERT(size != 0 || offset == 0);
887 gl.genTextures(1, &m_glTexture);
888 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
890 gl.genBuffers(1, &m_glBuffer);
891 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
893 gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
894 gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), data, GL_STATIC_DRAW);
895 gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
896 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer");
898 gl.bindTexture(GL_TEXTURE_BUFFER, m_glTexture);
900 if (offset != 0 || size != 0)
901 gl.texBufferRange(GL_TEXTURE_BUFFER, m_format, m_glBuffer, (glw::GLintptr)m_offset, (glw::GLsizeiptr)m_size);
903 gl.texBuffer(GL_TEXTURE_BUFFER, m_format, m_glBuffer);
905 gl.bindTexture(GL_TEXTURE_BUFFER, 0);
906 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffer to texture");
910 TextureBuffer::~TextureBuffer (void)
913 m_context.getFunctions().deleteTextures(1, &m_glTexture);
916 m_context.getFunctions().deleteBuffers(1, &m_glBuffer);
920 const tcu::PixelBufferAccess TextureBuffer::getFullRefTexture (void)
922 const tcu::TextureFormat format = mapGLInternalFormat(m_format);
923 const size_t bufferLengthBytes = (m_size != 0) ? (m_size) : (m_refBuffer.size());
924 const int bufferLengthPixels = (int)bufferLengthBytes / format.getPixelSize();
926 return tcu::PixelBufferAccess(format,
927 tcu::IVec3(bufferLengthPixels, 1, 1),
928 (deUint8*)m_refBuffer.getPtr() + m_offset);
931 const tcu::ConstPixelBufferAccess TextureBuffer::getFullRefTexture (void) const
933 return const_cast<TextureBuffer*>(this)->getFullRefTexture();
936 void TextureBuffer::upload (void)
938 const glw::Functions& gl = m_context.getFunctions();
940 gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
941 gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), m_refBuffer.getPtr(), GL_STATIC_DRAW);
942 gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
943 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload buffer");