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