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]);
288 TextureCube::TextureCube (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
289 : m_context (context)
290 , m_isCompressed (true)
291 , m_format (getGLFormat(levels[0].getFormat()))
292 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth())
295 const glw::Functions& gl = m_context.getFunctions();
297 TCU_CHECK_INTERNAL(levels[0].getWidth() == levels[0].getHeight());
299 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
300 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
302 gl.genTextures(1, &m_glTexture);
303 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
307 loadCompressed(numLevels, levels, decompressionParams);
309 catch (const std::exception&)
311 gl.deleteTextures(1, &m_glTexture);
316 TextureCube::TextureCube (const RenderContext& context, deUint32 format, deUint32 dataType, int size)
317 : m_context (context)
318 , m_isCompressed (false)
320 , m_refTexture (mapGLTransferFormat(format, dataType), size)
323 const glw::Functions& gl = m_context.getFunctions();
324 gl.genTextures(1, &m_glTexture);
325 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
328 TextureCube::TextureCube (const RenderContext& context, deUint32 internalFormat, int size)
329 : m_context (context)
330 , m_isCompressed (false)
331 , m_format (internalFormat)
332 , m_refTexture (mapGLInternalFormat(internalFormat), size)
335 const glw::Functions& gl = m_context.getFunctions();
336 gl.genTextures(1, &m_glTexture);
337 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
340 TextureCube::~TextureCube (void)
343 m_context.getFunctions().deleteTextures(1, &m_glTexture);
346 void TextureCube::upload (void)
348 const glw::Functions& gl = m_context.getFunctions();
350 DE_ASSERT(!m_isCompressed);
352 TCU_CHECK(m_glTexture);
353 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
354 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
355 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
357 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
359 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
361 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
363 if (m_refTexture.isLevelEmpty((tcu::CubeFace)face, levelNdx))
364 continue; // Don't upload.
366 tcu::ConstPixelBufferAccess access = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
367 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
368 gl.texImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
372 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
375 void TextureCube::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
377 const glw::Functions& gl = m_context.getFunctions();
378 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
380 TCU_CHECK(m_glTexture);
381 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_glTexture);
383 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
385 for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
387 const tcu::CompressedTexture& level = levels[levelNdx*tcu::CUBEFACE_LAST + face];
389 // Decompress to reference texture.
390 m_refTexture.allocLevel((tcu::CubeFace)face, levelNdx);
391 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevelFace(levelNdx, (tcu::CubeFace)face);
392 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
393 level.getHeight() == refLevelAccess.getHeight());
394 level.decompress(refLevelAccess, decompressionParams);
396 // Upload to GL texture in compressed form.
397 gl.compressedTexImage2D(getGLCubeFace((tcu::CubeFace)face), levelNdx, compressedFormat,
398 level.getWidth(), level.getHeight(), 0 /* border */, level.getDataSize(), level.getData());
402 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
405 TextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const char* const* filenames)
407 DE_ASSERT(numLevels > 0);
409 std::string ext = de::FilePath(filenames[0]).getFileExtension();
411 // \todo [2011-11-21 pyry] Support PNG images.
414 // Compressed texture.
415 int numImages = numLevels*tcu::CUBEFACE_LAST;
416 vector<tcu::CompressedTexture> levels (numImages);
418 for (int ndx = 0; ndx < numImages; ndx++)
419 tcu::ImageIO::loadPKM(levels[ndx], archive, filenames[ndx]);
421 return new TextureCube(context, contextInfo, numLevels, &levels[0]);
424 TCU_FAIL("Unsupported file format");
427 TextureCube* TextureCube::create (const RenderContext& context, const ContextInfo& contextInfo, const tcu::Archive& archive, int numLevels, const std::vector<std::string>& filenames)
429 DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
430 TCU_CHECK(numLevels*tcu::CUBEFACE_LAST == (int)filenames.size());
432 std::vector<const char*> charPtrs(filenames.size());
433 for (int ndx = 0; ndx < (int)filenames.size(); ndx++)
434 charPtrs[ndx] = filenames[ndx].c_str();
436 return TextureCube::create(context, contextInfo, archive, numLevels, &charPtrs[0]);
441 Texture1DArray::Texture1DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int numLevels)
442 : m_context (context)
444 , m_refTexture (mapGLTransferFormat(format, dataType), width, numLevels)
447 const glw::Functions& gl = m_context.getFunctions();
448 gl.genTextures(1, &m_glTexture);
449 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
452 Texture1DArray::Texture1DArray (const RenderContext& context, deUint32 sizedFormat, int width, int numLevels)
453 : m_context (context)
454 , m_format (sizedFormat)
455 , m_refTexture (mapGLInternalFormat(sizedFormat), width, numLevels)
458 const glw::Functions& gl = m_context.getFunctions();
459 gl.genTextures(1, &m_glTexture);
460 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
463 Texture1DArray::~Texture1DArray (void)
466 m_context.getFunctions().deleteTextures(1, &m_glTexture);
469 void Texture1DArray::upload (void)
471 const glw::Functions& gl = m_context.getFunctions();
473 TCU_CHECK(m_glTexture);
474 gl.bindTexture(GL_TEXTURE_1D_ARRAY, m_glTexture);
475 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
476 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
478 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
480 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
482 if (m_refTexture.isLevelEmpty(levelNdx))
483 continue; // Don't upload.
485 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
486 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
487 gl.texImage2D(GL_TEXTURE_1D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
490 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
495 Texture2DArray::Texture2DArray (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int numLevels)
496 : m_context (context)
497 , m_isCompressed (false)
499 , m_refTexture (mapGLTransferFormat(format, dataType), width, height, numLevels)
502 // \todo [2013-04-08 pyry] Check support here.
503 const glw::Functions& gl = m_context.getFunctions();
504 gl.genTextures(1, &m_glTexture);
505 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
508 Texture2DArray::Texture2DArray (const RenderContext& context, deUint32 sizedFormat, int width, int height, int numLevels)
509 : m_context (context)
510 , m_isCompressed (false)
511 , m_format (sizedFormat)
512 , m_refTexture (mapGLInternalFormat(sizedFormat), width, height, numLevels)
515 // \todo [2013-04-08 pyry] Check support here.
516 const glw::Functions& gl = m_context.getFunctions();
517 gl.genTextures(1, &m_glTexture);
518 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
521 Texture2DArray::Texture2DArray (const RenderContext& context, const ContextInfo& contextInfo, int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
522 : m_context (context)
523 , m_isCompressed (true)
524 , m_format (getGLFormat(levels[0].getFormat()))
525 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
528 const glw::Functions& gl = context.getFunctions();
530 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
531 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
533 gl.genTextures(1, &m_glTexture);
534 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
538 loadCompressed(numLevels, levels, decompressionParams);
540 catch (const std::exception&)
542 gl.deleteTextures(1, &m_glTexture);
547 Texture2DArray::~Texture2DArray (void)
550 m_context.getFunctions().deleteTextures(1, &m_glTexture);
553 void Texture2DArray::upload (void)
555 const glw::Functions& gl = m_context.getFunctions();
558 throw tcu::NotSupportedError("glTexImage3D() is not supported");
560 TCU_CHECK(m_glTexture);
561 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
562 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
563 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
565 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
567 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
569 if (m_refTexture.isLevelEmpty(levelNdx))
570 continue; // Don't upload.
572 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
573 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
574 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
575 gl.texImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
578 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
581 void Texture2DArray::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
583 const glw::Functions& gl = m_context.getFunctions();
584 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
586 TCU_CHECK(m_glTexture);
587 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_glTexture);
589 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
591 const tcu::CompressedTexture& level = levels[levelNdx];
593 // Decompress to reference texture.
594 m_refTexture.allocLevel(levelNdx);
595 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
596 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
597 level.getHeight() == refLevelAccess.getHeight() &&
598 level.getDepth() == refLevelAccess.getDepth());
599 level.decompress(refLevelAccess, decompressionParams);
601 // Upload to GL texture in compressed form.
602 gl.compressedTexImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, compressedFormat,
603 level.getWidth(), level.getHeight(), m_refTexture.getLevel(levelNdx).getDepth(), 0 /* border */, level.getDataSize(), level.getData());
606 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
611 Texture3D::Texture3D (const RenderContext& context, deUint32 format, deUint32 dataType, int width, int height, int depth)
612 : m_context (context)
613 , m_isCompressed (false)
615 , m_refTexture (mapGLTransferFormat(format, dataType), width, height, depth)
618 // \todo [2013-04-08 pyry] Check support here.
619 const glw::Functions& gl = m_context.getFunctions();
620 gl.genTextures(1, &m_glTexture);
621 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
624 Texture3D::Texture3D (const RenderContext& context, deUint32 sizedFormat, int width, int height, int depth)
625 : m_context (context)
626 , m_isCompressed (false)
627 , m_format (sizedFormat)
628 , m_refTexture (mapGLInternalFormat(sizedFormat), width, height, depth)
631 // \todo [2013-04-08 pyry] Check support here.
632 const glw::Functions& gl = m_context.getFunctions();
633 gl.genTextures(1, &m_glTexture);
634 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
637 Texture3D::Texture3D (const RenderContext& context,
638 const ContextInfo& contextInfo,
640 const tcu::CompressedTexture* levels,
641 const tcu::TexDecompressionParams& decompressionParams)
642 : m_context (context)
643 , m_isCompressed (true)
644 , m_format (getGLFormat(levels[0].getFormat()))
645 , m_refTexture (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight(), levels[0].getDepth())
648 const glw::Functions& gl = context.getFunctions();
650 if (!contextInfo.isCompressedTextureFormatSupported(m_format))
651 throw tcu::NotSupportedError("Compressed texture format not supported", "", __FILE__, __LINE__);
653 gl.genTextures(1, &m_glTexture);
654 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
658 loadCompressed(numLevels, levels, decompressionParams);
660 catch (const std::exception&)
662 gl.deleteTextures(1, &m_glTexture);
667 Texture3D::~Texture3D (void)
670 m_context.getFunctions().deleteTextures(1, &m_glTexture);
673 void Texture3D::upload (void)
675 const glw::Functions& gl = m_context.getFunctions();
677 DE_ASSERT(!m_isCompressed);
680 throw tcu::NotSupportedError("glTexImage3D() is not supported");
682 TCU_CHECK(m_glTexture);
683 gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
684 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
685 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
687 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
689 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
691 if (m_refTexture.isLevelEmpty(levelNdx))
692 continue; // Don't upload.
694 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
695 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
696 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
697 gl.texImage3D(GL_TEXTURE_3D, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
700 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
703 void Texture3D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
705 const glw::Functions& gl = m_context.getFunctions();
706 deUint32 compressedFormat = getGLFormat(levels[0].getFormat());
708 if (!gl.compressedTexImage3D)
709 throw tcu::NotSupportedError("glCompressedTexImage3D() is not supported");
711 TCU_CHECK(m_glTexture);
712 gl.bindTexture(GL_TEXTURE_3D, m_glTexture);
714 for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
716 const tcu::CompressedTexture& level = levels[levelNdx];
718 // Decompress to reference texture.
719 m_refTexture.allocLevel(levelNdx);
720 tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
721 TCU_CHECK(level.getWidth() == refLevelAccess.getWidth() &&
722 level.getHeight() == refLevelAccess.getHeight() &&
723 level.getDepth() == refLevelAccess.getDepth());
724 level.decompress(refLevelAccess, decompressionParams);
726 // Upload to GL texture in compressed form.
727 gl.compressedTexImage3D(GL_TEXTURE_3D, levelNdx, compressedFormat,
728 level.getWidth(), level.getHeight(), level.getDepth(), 0 /* border */, level.getDataSize(), level.getData());
731 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
736 TextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 format, deUint32 dataType, int size, int numLayers)
737 : m_context (context)
739 , m_refTexture (mapGLTransferFormat(format, dataType), size, numLayers)
742 // \todo [2013-04-08 pyry] Check support here.
743 const glw::Functions& gl = m_context.getFunctions();
744 gl.genTextures(1, &m_glTexture);
745 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
748 TextureCubeArray::TextureCubeArray (const RenderContext& context, deUint32 sizedFormat, int size, int numLayers)
749 : m_context (context)
750 , m_format (sizedFormat)
751 , m_refTexture (mapGLInternalFormat(sizedFormat), size, numLayers)
754 // \todo [2013-04-08 pyry] Check support here.
755 const glw::Functions& gl = m_context.getFunctions();
756 gl.genTextures(1, &m_glTexture);
757 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
760 TextureCubeArray::~TextureCubeArray (void)
763 m_context.getFunctions().deleteTextures(1, &m_glTexture);
766 void TextureCubeArray::upload (void)
768 const glw::Functions& gl = m_context.getFunctions();
771 throw tcu::NotSupportedError("glTexImage3D() is not supported");
773 TCU_CHECK(m_glTexture);
774 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_glTexture);
775 gl.pixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(m_refTexture.getFormat()));
776 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
778 TransferFormat transferFormat = getTransferFormat(m_refTexture.getFormat());
780 for (int levelNdx = 0; levelNdx < m_refTexture.getNumLevels(); levelNdx++)
782 if (m_refTexture.isLevelEmpty(levelNdx))
783 continue; // Don't upload.
785 tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(levelNdx);
786 DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*access.getWidth());
787 DE_ASSERT(access.getSlicePitch() == access.getFormat().getPixelSize()*access.getWidth()*access.getHeight());
788 gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, levelNdx, m_format, access.getWidth(), access.getHeight(), access.getDepth(), 0 /* border */, transferFormat.format, transferFormat.dataType, access.getDataPtr());
791 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture upload failed");
796 TextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize)
797 : m_context (context)
804 init(internalFormat, bufferSize, 0, 0, DE_NULL);
807 TextureBuffer::TextureBuffer (const RenderContext& context, deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
808 : m_context (context)
815 init(internalFormat, bufferSize, offset, size, data);
818 void TextureBuffer::init (deUint32 internalFormat, size_t bufferSize, size_t offset, size_t size, const void* data)
820 const glw::Functions& gl = m_context.getFunctions();
821 de::UniquePtr<ContextInfo> info (ContextInfo::create(m_context));
823 if (offset != 0 || size != 0)
825 if (!(contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE)) && info->isExtensionSupported("GL_ARB_texture_buffer_range"))
826 && !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
827 && info->isExtensionSupported("GL_EXT_texture_buffer")))
829 throw tcu::NotSupportedError("Ranged texture buffers not supported", "", __FILE__, __LINE__);
834 if (!contextSupports(m_context.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE))
835 && !(contextSupports(m_context.getType(), glu::ApiType(3, 1, glu::PROFILE_ES))
836 && info->isExtensionSupported("GL_EXT_texture_buffer")))
838 throw tcu::NotSupportedError("Texture buffers not supported", "", __FILE__, __LINE__);
842 m_refBuffer.setStorage(bufferSize);
844 deMemcpy(m_refBuffer.getPtr(), data, (int)bufferSize);
846 m_format = internalFormat;
850 DE_ASSERT(size != 0 || offset == 0);
853 gl.genTextures(1, &m_glTexture);
854 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
856 gl.genBuffers(1, &m_glBuffer);
857 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed");
859 gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
860 gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), data, GL_STATIC_DRAW);
861 gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
862 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create buffer");
864 gl.bindTexture(GL_TEXTURE_BUFFER, m_glTexture);
866 if (offset != 0 || size != 0)
867 gl.texBufferRange(GL_TEXTURE_BUFFER, m_format, m_glBuffer, (glw::GLintptr)m_offset, (glw::GLsizeiptr)m_size);
869 gl.texBuffer(GL_TEXTURE_BUFFER, m_format, m_glBuffer);
871 gl.bindTexture(GL_TEXTURE_BUFFER, 0);
872 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffer to texture");
876 TextureBuffer::~TextureBuffer (void)
879 m_context.getFunctions().deleteTextures(1, &m_glTexture);
882 m_context.getFunctions().deleteBuffers(1, &m_glBuffer);
886 const tcu::PixelBufferAccess TextureBuffer::getFullRefTexture (void)
888 const tcu::TextureFormat format = mapGLInternalFormat(m_format);
889 const size_t bufferLengthBytes = (m_size != 0) ? (m_size) : (m_refBuffer.size());
890 const int bufferLengthPixels = (int)bufferLengthBytes / format.getPixelSize();
892 return tcu::PixelBufferAccess(format,
893 tcu::IVec3(bufferLengthPixels, 1, 1),
894 (deUint8*)m_refBuffer.getPtr() + m_offset);
897 const tcu::ConstPixelBufferAccess TextureBuffer::getFullRefTexture (void) const
899 return const_cast<TextureBuffer*>(this)->getFullRefTexture();
902 void TextureBuffer::upload (void)
904 const glw::Functions& gl = m_context.getFunctions();
906 gl.bindBuffer(GL_TEXTURE_BUFFER, m_glBuffer);
907 gl.bufferData(GL_TEXTURE_BUFFER, (glw::GLsizei)m_refBuffer.size(), m_refBuffer.getPtr(), GL_STATIC_DRAW);
908 gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
909 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload buffer");