You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1108 lines
38 KiB
1108 lines
38 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.0 Module
|
|
* -------------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Texture specification tests.
|
|
*
|
|
* \todo [pyry] Following tests are missing:
|
|
* - Specify mipmap incomplete texture, use without mipmaps, re-specify
|
|
* as complete and render.
|
|
* - Randomly re-specify levels to eventually reach mipmap-complete texture.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es31fTextureSpecificationTests.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuImageCompare.hpp"
|
|
#include "tcuTextureUtil.hpp"
|
|
#include "tcuVectorUtil.hpp"
|
|
#include "gluStrUtil.hpp"
|
|
#include "gluTexture.hpp"
|
|
#include "gluTextureUtil.hpp"
|
|
#include "sglrContextUtil.hpp"
|
|
#include "sglrContextWrapper.hpp"
|
|
#include "sglrGLContext.hpp"
|
|
#include "sglrReferenceContext.hpp"
|
|
#include "glsTextureTestUtil.hpp"
|
|
#include "deRandom.hpp"
|
|
#include "deStringUtil.hpp"
|
|
|
|
// \todo [2012-04-29 pyry] Should be named SglrUtil
|
|
#include "es31fFboTestUtil.hpp"
|
|
|
|
#include "glwEnums.hpp"
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles31
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
using std::pair;
|
|
using tcu::TestLog;
|
|
using tcu::Vec4;
|
|
using tcu::IVec4;
|
|
using tcu::UVec4;
|
|
using namespace FboTestUtil;
|
|
|
|
enum
|
|
{
|
|
VIEWPORT_WIDTH = 256,
|
|
VIEWPORT_HEIGHT = 256
|
|
};
|
|
|
|
static inline int maxLevelCount (int size)
|
|
{
|
|
return (int)deLog2Floor32(size)+1;
|
|
}
|
|
|
|
template <int Size>
|
|
static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
|
|
{
|
|
tcu::Vector<float, Size> res;
|
|
for (int ndx = 0; ndx < Size; ndx++)
|
|
res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
|
|
return res;
|
|
}
|
|
|
|
static tcu::CubeFace getCubeFaceFromNdx (int ndx)
|
|
{
|
|
switch (ndx)
|
|
{
|
|
case 0: return tcu::CUBEFACE_POSITIVE_X;
|
|
case 1: return tcu::CUBEFACE_NEGATIVE_X;
|
|
case 2: return tcu::CUBEFACE_POSITIVE_Y;
|
|
case 3: return tcu::CUBEFACE_NEGATIVE_Y;
|
|
case 4: return tcu::CUBEFACE_POSITIVE_Z;
|
|
case 5: return tcu::CUBEFACE_NEGATIVE_Z;
|
|
default:
|
|
DE_ASSERT(false);
|
|
return tcu::CUBEFACE_LAST;
|
|
}
|
|
}
|
|
|
|
class TextureSpecCase : public TestCase, public sglr::ContextWrapper
|
|
{
|
|
public:
|
|
TextureSpecCase (Context& context, const char* name, const char* desc);
|
|
~TextureSpecCase (void);
|
|
|
|
IterateResult iterate (void);
|
|
|
|
protected:
|
|
virtual bool checkExtensionSupport (void) { return true; }
|
|
|
|
virtual void createTexture (void) = DE_NULL;
|
|
virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext) = DE_NULL;
|
|
|
|
// Utilities.
|
|
void renderTex (tcu::Surface& dst, deUint32 program, int width, int height);
|
|
void readPixels (tcu::Surface& dst, int x, int y, int width, int height);
|
|
|
|
private:
|
|
TextureSpecCase (const TextureSpecCase& other);
|
|
TextureSpecCase& operator= (const TextureSpecCase& other);
|
|
};
|
|
|
|
TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
|
|
: TestCase(context, name, desc)
|
|
{
|
|
}
|
|
|
|
TextureSpecCase::~TextureSpecCase (void)
|
|
{
|
|
}
|
|
|
|
TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
|
|
{
|
|
glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext();
|
|
const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
|
|
tcu::TestLog& log = m_testCtx.getLog();
|
|
|
|
if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
|
|
throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
|
|
|
|
if (!checkExtensionSupport())
|
|
throw tcu::NotSupportedError("Extension not supported", "", __FILE__, __LINE__);
|
|
|
|
// Context size, and viewport for GLES3.1
|
|
de::Random rnd (deStringHash(getName()));
|
|
int width = deMin32(renderTarget.getWidth(), VIEWPORT_WIDTH);
|
|
int height = deMin32(renderTarget.getHeight(), VIEWPORT_HEIGHT);
|
|
int x = rnd.getInt(0, renderTarget.getWidth() - width);
|
|
int y = rnd.getInt(0, renderTarget.getHeight() - height);
|
|
|
|
// Contexts.
|
|
sglr::GLContext gles31Context (renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
|
|
sglr::ReferenceContextBuffers refBuffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
|
|
sglr::ReferenceContext refContext (sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
|
|
|
|
// Clear color buffer.
|
|
for (int ndx = 0; ndx < 2; ndx++)
|
|
{
|
|
setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
|
|
glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
|
}
|
|
|
|
// Construct texture using both GLES3.1 and reference contexts.
|
|
for (int ndx = 0; ndx < 2; ndx++)
|
|
{
|
|
setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
|
|
createTexture();
|
|
TCU_CHECK(glGetError() == GL_NO_ERROR);
|
|
}
|
|
|
|
// Initialize case result to pass.
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
|
|
|
|
// Disable logging.
|
|
gles31Context.enableLogging(0);
|
|
|
|
// Verify results.
|
|
verifyTexture(gles31Context, refContext);
|
|
|
|
return STOP;
|
|
}
|
|
|
|
void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 program, int width, int height)
|
|
{
|
|
int targetW = getWidth();
|
|
int targetH = getHeight();
|
|
|
|
float w = (float)width / (float)targetW;
|
|
float h = (float)height / (float)targetH;
|
|
|
|
sglr::drawQuad(*getCurrentContext(), program, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
|
|
|
|
// Read pixels back.
|
|
readPixels(dst, 0, 0, width, height);
|
|
}
|
|
|
|
void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
|
|
{
|
|
dst.setSize(width, height);
|
|
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
|
|
}
|
|
|
|
class TextureCubeArraySpecCase : public TextureSpecCase
|
|
{
|
|
public:
|
|
TextureCubeArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels);
|
|
~TextureCubeArraySpecCase (void);
|
|
|
|
protected:
|
|
virtual bool checkExtensionSupport (void);
|
|
virtual void verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
|
|
|
|
tcu::TextureFormat m_texFormat;
|
|
tcu::TextureFormatInfo m_texFormatInfo;
|
|
int m_size;
|
|
int m_depth;
|
|
int m_numLevels;
|
|
};
|
|
|
|
TextureCubeArraySpecCase::TextureCubeArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels)
|
|
: TextureSpecCase (context, name, desc)
|
|
, m_texFormat (format)
|
|
, m_texFormatInfo (tcu::getTextureFormatInfo(format))
|
|
, m_size (size)
|
|
, m_depth (depth)
|
|
, m_numLevels (numLevels)
|
|
{
|
|
}
|
|
|
|
TextureCubeArraySpecCase::~TextureCubeArraySpecCase (void)
|
|
{
|
|
}
|
|
|
|
bool TextureCubeArraySpecCase::checkExtensionSupport (void)
|
|
{
|
|
glu::ContextType contextType = m_context.getRenderContext().getType();
|
|
const bool supportsES32orGL45 = glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
|
|
glu::contextSupports(contextType, glu::ApiType::core(4, 5));
|
|
return supportsES32orGL45 || m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_cube_map_array");
|
|
}
|
|
|
|
void TextureCubeArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
|
|
{
|
|
const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
|
|
TextureCubeArrayShader shader (glu::getSamplerCubeArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4, glslVersion);
|
|
deUint32 shaderIDgles = gles3Context.createProgram(&shader);
|
|
deUint32 shaderIDRef = refContext.createProgram(&shader);
|
|
|
|
shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
|
|
|
|
// Set state.
|
|
for (int ndx = 0; ndx < 2; ndx++)
|
|
{
|
|
sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
|
|
|
|
setContext(ctx);
|
|
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, m_numLevels-1);
|
|
}
|
|
|
|
for (int layerFaceNdx = 0; layerFaceNdx < m_depth; layerFaceNdx++)
|
|
{
|
|
const int layerNdx = layerFaceNdx / 6;
|
|
const tcu::CubeFace face = getCubeFaceFromNdx(layerFaceNdx % 6);
|
|
bool layerOk = true;
|
|
|
|
shader.setLayer(layerNdx);
|
|
shader.setFace(face);
|
|
|
|
for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
|
|
{
|
|
int levelSize = de::max(1, m_size >> levelNdx);
|
|
tcu::Surface reference;
|
|
tcu::Surface result;
|
|
|
|
if (levelSize <= 2)
|
|
continue; // Fuzzy compare doesn't work for images this small.
|
|
|
|
for (int ndx = 0; ndx < 2; ndx++)
|
|
{
|
|
tcu::Surface& dst = ndx ? reference : result;
|
|
sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
|
|
deUint32 shaderID = ndx ? shaderIDRef : shaderIDgles;
|
|
|
|
setContext(ctx);
|
|
shader.setUniforms(*ctx, shaderID);
|
|
renderTex(dst, shaderID, levelSize, levelSize);
|
|
}
|
|
|
|
const float threshold = 0.02f;
|
|
string levelStr = de::toString(levelNdx);
|
|
string layerFaceStr = de::toString(layerFaceNdx);
|
|
string name = string("LayerFace") + layerFaceStr + "Level" + levelStr;
|
|
string desc = string("Layer-face ") + layerFaceStr + ", Level " + levelStr;
|
|
bool isFaceOk = tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold,
|
|
(levelNdx == 0 && layerFaceNdx == 0) == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
|
|
|
|
if (!isFaceOk)
|
|
{
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
|
|
layerOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!layerOk)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Basic TexImage3D() with cube map array texture usage
|
|
class BasicTexImageCubeArrayCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
BasicTexImageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers)
|
|
: TextureCubeArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, maxLevelCount(size))
|
|
, m_internalFormat (internalFormat)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void createTexture (void)
|
|
{
|
|
deUint32 tex = 0;
|
|
de::Random rnd (deStringHash(getName()));
|
|
glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
|
|
tcu::TextureLevel levelData (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
for (int ndx = 0; ndx < m_numLevels; ndx++)
|
|
{
|
|
int levelW = de::max(1, m_size >> ndx);
|
|
Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
|
|
Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
|
|
|
|
levelData.setSize(levelW, levelW, m_depth);
|
|
tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
|
|
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
}
|
|
|
|
deUint32 m_internalFormat;
|
|
};
|
|
|
|
// Basic glTexStorage3D() with cube map array texture usage
|
|
class BasicTexStorageCubeArrayCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
BasicTexStorageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers, int numLevels)
|
|
: TextureCubeArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, numLevels)
|
|
, m_internalFormat (internalFormat)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void createTexture (void)
|
|
{
|
|
deUint32 tex = 0;
|
|
de::Random rnd (deStringHash(getName()));
|
|
glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
|
|
tcu::TextureLevel levelData (glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
|
|
|
|
glGenTextures (1, &tex);
|
|
glBindTexture (GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glTexStorage3D (GL_TEXTURE_CUBE_MAP_ARRAY, m_numLevels, m_internalFormat, m_size, m_size, m_depth);
|
|
|
|
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
|
|
|
for (int ndx = 0; ndx < m_numLevels; ndx++)
|
|
{
|
|
int levelW = de::max(1, m_size >> ndx);
|
|
Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
|
|
Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
|
|
|
|
levelData.setSize(levelW, levelW, m_depth);
|
|
tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
|
|
|
|
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, 0, 0, 0, levelW, levelW, m_depth, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
}
|
|
|
|
deUint32 m_internalFormat;
|
|
};
|
|
|
|
// Pixel buffer object cases.
|
|
|
|
// TexImage3D() cube map array from pixel buffer object.
|
|
class TexImageCubeArrayBufferCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
TexImageCubeArrayBufferCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 internalFormat,
|
|
int size,
|
|
int depth,
|
|
int imageHeight,
|
|
int rowLength,
|
|
int skipImages,
|
|
int skipRows,
|
|
int skipPixels,
|
|
int alignment,
|
|
int offset)
|
|
: TextureCubeArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
|
|
, m_internalFormat (internalFormat)
|
|
, m_imageHeight (imageHeight)
|
|
, m_rowLength (rowLength)
|
|
, m_skipImages (skipImages)
|
|
, m_skipRows (skipRows)
|
|
, m_skipPixels (skipPixels)
|
|
, m_alignment (alignment)
|
|
, m_offset (offset)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void createTexture (void)
|
|
{
|
|
glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
|
|
int pixelSize = m_texFormat.getPixelSize();
|
|
int rowLength = m_rowLength > 0 ? m_rowLength : m_size;
|
|
int rowPitch = deAlign32(rowLength*pixelSize, m_alignment);
|
|
int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_size;
|
|
int slicePitch = imageHeight*rowPitch;
|
|
deUint32 tex = 0;
|
|
deUint32 buf = 0;
|
|
vector<deUint8> data;
|
|
|
|
DE_ASSERT(m_numLevels == 1);
|
|
|
|
// Fill data with grid.
|
|
data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
|
|
{
|
|
Vec4 cScale = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
|
|
Vec4 cBias = m_texFormatInfo.valueMin;
|
|
Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
|
|
Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
|
|
|
|
tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
|
|
}
|
|
|
|
glGenBuffers(1, &buf);
|
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
|
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
|
|
|
|
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_imageHeight);
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength);
|
|
glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skipImages);
|
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows);
|
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
|
|
}
|
|
|
|
deUint32 m_internalFormat;
|
|
int m_imageHeight;
|
|
int m_rowLength;
|
|
int m_skipImages;
|
|
int m_skipRows;
|
|
int m_skipPixels;
|
|
int m_alignment;
|
|
int m_offset;
|
|
};
|
|
|
|
// TexSubImage3D() cube map array PBO case.
|
|
class TexSubImageCubeArrayBufferCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
TexSubImageCubeArrayBufferCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 internalFormat,
|
|
int size,
|
|
int depth,
|
|
int subX,
|
|
int subY,
|
|
int subZ,
|
|
int subW,
|
|
int subH,
|
|
int subD,
|
|
int imageHeight,
|
|
int rowLength,
|
|
int skipImages,
|
|
int skipRows,
|
|
int skipPixels,
|
|
int alignment,
|
|
int offset)
|
|
: TextureCubeArraySpecCase (context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
|
|
, m_internalFormat (internalFormat)
|
|
, m_subX (subX)
|
|
, m_subY (subY)
|
|
, m_subZ (subZ)
|
|
, m_subW (subW)
|
|
, m_subH (subH)
|
|
, m_subD (subD)
|
|
, m_imageHeight (imageHeight)
|
|
, m_rowLength (rowLength)
|
|
, m_skipImages (skipImages)
|
|
, m_skipRows (skipRows)
|
|
, m_skipPixels (skipPixels)
|
|
, m_alignment (alignment)
|
|
, m_offset (offset)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void createTexture (void)
|
|
{
|
|
glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
|
|
int pixelSize = m_texFormat.getPixelSize();
|
|
deUint32 tex = 0;
|
|
deUint32 buf = 0;
|
|
vector<deUint8> data;
|
|
|
|
DE_ASSERT(m_numLevels == 1);
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
|
|
// Fill with gradient.
|
|
{
|
|
int rowPitch = deAlign32(pixelSize*m_size, 4);
|
|
int slicePitch = rowPitch*m_size;
|
|
|
|
data.resize(slicePitch*m_depth);
|
|
tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
|
|
}
|
|
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
|
|
|
|
// Fill data with grid.
|
|
{
|
|
int rowLength = m_rowLength > 0 ? m_rowLength : m_subW;
|
|
int rowPitch = deAlign32(rowLength*pixelSize, m_alignment);
|
|
int imageHeight = m_imageHeight > 0 ? m_imageHeight : m_subH;
|
|
int slicePitch = imageHeight*rowPitch;
|
|
Vec4 cScale = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
|
|
Vec4 cBias = m_texFormatInfo.valueMin;
|
|
Vec4 colorA = Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
|
|
Vec4 colorB = Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
|
|
|
|
data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
|
|
tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
|
|
}
|
|
|
|
glGenBuffers(1, &buf);
|
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
|
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
|
|
|
|
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_imageHeight);
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_rowLength);
|
|
glPixelStorei(GL_UNPACK_SKIP_IMAGES, m_skipImages);
|
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, m_skipRows);
|
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, m_skipPixels);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
|
|
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
|
|
}
|
|
|
|
deUint32 m_internalFormat;
|
|
int m_subX;
|
|
int m_subY;
|
|
int m_subZ;
|
|
int m_subW;
|
|
int m_subH;
|
|
int m_subD;
|
|
int m_imageHeight;
|
|
int m_rowLength;
|
|
int m_skipImages;
|
|
int m_skipRows;
|
|
int m_skipPixels;
|
|
int m_alignment;
|
|
int m_offset;
|
|
};
|
|
|
|
// TexImage3D() depth case.
|
|
class TexImageCubeArrayDepthCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
TexImageCubeArrayDepthCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 internalFormat,
|
|
int imageSize,
|
|
int numLayers)
|
|
: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
|
|
, m_internalFormat (internalFormat)
|
|
{
|
|
// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
|
|
m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
|
|
m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
|
|
}
|
|
|
|
void createTexture (void)
|
|
{
|
|
glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
|
|
deUint32 tex = 0;
|
|
tcu::TextureLevel levelData (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
GLU_CHECK();
|
|
|
|
for (int ndx = 0; ndx < m_numLevels; ndx++)
|
|
{
|
|
const int levelW = de::max(1, m_size >> ndx);
|
|
const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
|
|
const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
|
|
|
|
levelData.setSize(levelW, levelW, m_depth);
|
|
tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
|
|
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
}
|
|
|
|
const deUint32 m_internalFormat;
|
|
};
|
|
|
|
// TexSubImage3D() depth case.
|
|
class TexSubImageCubeArrayDepthCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
TexSubImageCubeArrayDepthCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 internalFormat,
|
|
int imageSize,
|
|
int numLayers)
|
|
: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
|
|
, m_internalFormat (internalFormat)
|
|
{
|
|
// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
|
|
m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
|
|
m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
|
|
}
|
|
|
|
void createTexture (void)
|
|
{
|
|
glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
|
|
de::Random rnd (deStringHash(getName()));
|
|
deUint32 tex = 0;
|
|
tcu::TextureLevel levelData (glu::mapGLTransferFormat(fmt.format, fmt.dataType));
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
GLU_CHECK();
|
|
|
|
// First specify full texture.
|
|
for (int ndx = 0; ndx < m_numLevels; ndx++)
|
|
{
|
|
const int levelW = de::max(1, m_size >> ndx);
|
|
const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
|
|
const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
|
|
|
|
levelData.setSize(levelW, levelW, m_depth);
|
|
tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
|
|
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
|
|
// Re-specify parts of each level.
|
|
for (int ndx = 0; ndx < m_numLevels; ndx++)
|
|
{
|
|
const int levelW = de::max(1, m_size >> ndx);
|
|
|
|
const int w = rnd.getInt(1, levelW);
|
|
const int h = rnd.getInt(1, levelW);
|
|
const int d = rnd.getInt(1, m_depth);
|
|
const int x = rnd.getInt(0, levelW-w);
|
|
const int y = rnd.getInt(0, levelW-h);
|
|
const int z = rnd.getInt(0, m_depth-d);
|
|
|
|
const Vec4 colorA = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
|
|
const Vec4 colorB = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
|
|
const int cellSize = rnd.getInt(2, 16);
|
|
|
|
levelData.setSize(w, h, d);
|
|
tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
|
|
|
|
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
|
|
}
|
|
}
|
|
|
|
const deUint32 m_internalFormat;
|
|
};
|
|
|
|
// TexImage3D() depth case with pbo.
|
|
class TexImageCubeArrayDepthBufferCase : public TextureCubeArraySpecCase
|
|
{
|
|
public:
|
|
TexImageCubeArrayDepthBufferCase (Context& context,
|
|
const char* name,
|
|
const char* desc,
|
|
deUint32 internalFormat,
|
|
int imageSize,
|
|
int numLayers)
|
|
: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, 1)
|
|
, m_internalFormat (internalFormat)
|
|
{
|
|
// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
|
|
m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
|
|
m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
|
|
}
|
|
|
|
void createTexture (void)
|
|
{
|
|
glu::TransferFormat transferFmt = glu::getTransferFormat(m_texFormat);
|
|
int pixelSize = m_texFormat.getPixelSize();
|
|
int rowLength = m_size;
|
|
int alignment = 4;
|
|
int rowPitch = deAlign32(rowLength*pixelSize, alignment);
|
|
int imageHeight = m_size;
|
|
int slicePitch = imageHeight*rowPitch;
|
|
deUint32 tex = 0;
|
|
deUint32 buf = 0;
|
|
vector<deUint8> data;
|
|
|
|
DE_ASSERT(m_numLevels == 1);
|
|
|
|
// Fill data with grid.
|
|
data.resize(slicePitch*m_depth);
|
|
{
|
|
const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
|
|
const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
|
|
|
|
tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), gMin, gMax);
|
|
}
|
|
|
|
glGenBuffers(1, &buf);
|
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
|
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
|
|
|
|
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, imageHeight);
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength);
|
|
glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
|
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
|
|
|
glGenTextures(1, &tex);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
|
|
glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
|
|
glDeleteBuffers(1, &buf);
|
|
}
|
|
|
|
const deUint32 m_internalFormat;
|
|
};
|
|
|
|
TextureSpecificationTests::TextureSpecificationTests (Context& context)
|
|
: TestCaseGroup(context, "specification", "Texture Specification Tests")
|
|
{
|
|
}
|
|
|
|
TextureSpecificationTests::~TextureSpecificationTests (void)
|
|
{
|
|
}
|
|
|
|
void TextureSpecificationTests::init (void)
|
|
{
|
|
struct
|
|
{
|
|
const char* name;
|
|
deUint32 internalFormat;
|
|
} colorFormats[] =
|
|
{
|
|
{ "rgba32f", GL_RGBA32F, },
|
|
{ "rgba32i", GL_RGBA32I, },
|
|
{ "rgba32ui", GL_RGBA32UI, },
|
|
{ "rgba16f", GL_RGBA16F, },
|
|
{ "rgba16i", GL_RGBA16I, },
|
|
{ "rgba16ui", GL_RGBA16UI, },
|
|
{ "rgba8", GL_RGBA8, },
|
|
{ "rgba8i", GL_RGBA8I, },
|
|
{ "rgba8ui", GL_RGBA8UI, },
|
|
{ "srgb8_alpha8", GL_SRGB8_ALPHA8, },
|
|
{ "rgb10_a2", GL_RGB10_A2, },
|
|
{ "rgb10_a2ui", GL_RGB10_A2UI, },
|
|
{ "rgba4", GL_RGBA4, },
|
|
{ "rgb5_a1", GL_RGB5_A1, },
|
|
{ "rgba8_snorm", GL_RGBA8_SNORM, },
|
|
{ "rgb8", GL_RGB8, },
|
|
{ "rgb565", GL_RGB565, },
|
|
{ "r11f_g11f_b10f", GL_R11F_G11F_B10F, },
|
|
{ "rgb32f", GL_RGB32F, },
|
|
{ "rgb32i", GL_RGB32I, },
|
|
{ "rgb32ui", GL_RGB32UI, },
|
|
{ "rgb16f", GL_RGB16F, },
|
|
{ "rgb16i", GL_RGB16I, },
|
|
{ "rgb16ui", GL_RGB16UI, },
|
|
{ "rgb8_snorm", GL_RGB8_SNORM, },
|
|
{ "rgb8i", GL_RGB8I, },
|
|
{ "rgb8ui", GL_RGB8UI, },
|
|
{ "srgb8", GL_SRGB8, },
|
|
{ "rgb9_e5", GL_RGB9_E5, },
|
|
{ "rg32f", GL_RG32F, },
|
|
{ "rg32i", GL_RG32I, },
|
|
{ "rg32ui", GL_RG32UI, },
|
|
{ "rg16f", GL_RG16F, },
|
|
{ "rg16i", GL_RG16I, },
|
|
{ "rg16ui", GL_RG16UI, },
|
|
{ "rg8", GL_RG8, },
|
|
{ "rg8i", GL_RG8I, },
|
|
{ "rg8ui", GL_RG8UI, },
|
|
{ "rg8_snorm", GL_RG8_SNORM, },
|
|
{ "r32f", GL_R32F, },
|
|
{ "r32i", GL_R32I, },
|
|
{ "r32ui", GL_R32UI, },
|
|
{ "r16f", GL_R16F, },
|
|
{ "r16i", GL_R16I, },
|
|
{ "r16ui", GL_R16UI, },
|
|
{ "r8", GL_R8, },
|
|
{ "r8i", GL_R8I, },
|
|
{ "r8ui", GL_R8UI, },
|
|
{ "r8_snorm", GL_R8_SNORM, }
|
|
};
|
|
|
|
static const struct
|
|
{
|
|
const char* name;
|
|
deUint32 internalFormat;
|
|
} depthStencilFormats[] =
|
|
{
|
|
// Depth and stencil formats
|
|
{ "depth_component32f", GL_DEPTH_COMPONENT32F },
|
|
{ "depth_component24", GL_DEPTH_COMPONENT24 },
|
|
{ "depth_component16", GL_DEPTH_COMPONENT16 },
|
|
{ "depth32f_stencil8", GL_DEPTH32F_STENCIL8 },
|
|
{ "depth24_stencil8", GL_DEPTH24_STENCIL8 }
|
|
};
|
|
|
|
// Basic TexImage3D usage.
|
|
{
|
|
tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
|
|
addChild(basicTexImageGroup);
|
|
for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
|
|
{
|
|
const char* fmtName = colorFormats[formatNdx].name;
|
|
deUint32 format = colorFormats[formatNdx].internalFormat;
|
|
const int texCubeArraySize = 64;
|
|
const int texCubeArrayLayers = 6;
|
|
|
|
basicTexImageGroup->addChild(new BasicTexImageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", format, texCubeArraySize, texCubeArrayLayers));
|
|
}
|
|
}
|
|
|
|
// glTexImage3D() pbo cases.
|
|
{
|
|
tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
|
|
addChild(pboGroup);
|
|
|
|
// Parameter cases
|
|
static const struct
|
|
{
|
|
const char* name;
|
|
deUint32 format;
|
|
int size;
|
|
int depth;
|
|
int imageHeight;
|
|
int rowLength;
|
|
int skipImages;
|
|
int skipRows;
|
|
int skipPixels;
|
|
int alignment;
|
|
int offset;
|
|
} parameterCases[] =
|
|
{
|
|
{ "rgb8_offset", GL_RGB8, 23, 6, 0, 0, 0, 0, 0, 1, 67 },
|
|
{ "rgb8_alignment", GL_RGB8, 23, 6, 0, 0, 0, 0, 0, 2, 0 },
|
|
{ "rgb8_image_height", GL_RGB8, 23, 6, 26, 0, 0, 0, 0, 4, 0 },
|
|
{ "rgb8_row_length", GL_RGB8, 23, 6, 0, 27, 0, 0, 0, 4, 0 },
|
|
{ "rgb8_skip_images", GL_RGB8, 23, 6, 0, 0, 3, 0, 0, 4, 0 },
|
|
{ "rgb8_skip_rows", GL_RGB8, 23, 6, 26, 0, 0, 3, 0, 4, 0 },
|
|
{ "rgb8_skip_pixels", GL_RGB8, 23, 6, 0, 25, 0, 0, 2, 4, 0 }
|
|
};
|
|
|
|
for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
|
|
{
|
|
const string fmtName = colorFormats[formatNdx].name;
|
|
const deUint32 format = colorFormats[formatNdx].internalFormat;
|
|
const int texCubeArraySize = 20;
|
|
const int texCubeDepth = 6;
|
|
|
|
pboGroup->addChild(new TexImageCubeArrayBufferCase (m_context, (fmtName + "_cube_array").c_str(), "", format, texCubeArraySize, texCubeDepth, 0, 0, 0, 0, 0, 4, 0));
|
|
}
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
|
|
{
|
|
pboGroup->addChild(new TexImageCubeArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube_array").c_str(), "",
|
|
parameterCases[ndx].format,
|
|
parameterCases[ndx].size,
|
|
parameterCases[ndx].depth,
|
|
parameterCases[ndx].imageHeight,
|
|
parameterCases[ndx].rowLength,
|
|
parameterCases[ndx].skipImages,
|
|
parameterCases[ndx].skipRows,
|
|
parameterCases[ndx].skipPixels,
|
|
parameterCases[ndx].alignment,
|
|
parameterCases[ndx].offset));
|
|
}
|
|
}
|
|
|
|
// glTexImage3D() depth cases.
|
|
{
|
|
tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
|
|
addChild(shadow3dGroup);
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
|
|
{
|
|
const int texCubeArraySize = 64;
|
|
const int texCubeArrayDepth = 6;
|
|
|
|
shadow3dGroup->addChild(new TexImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
|
|
}
|
|
}
|
|
|
|
// glTexImage3D() depth cases with pbo.
|
|
{
|
|
tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
|
|
addChild(shadow3dGroup);
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
|
|
{
|
|
const int texCubeArraySize = 64;
|
|
const int texCubeArrayDepth = 6;
|
|
|
|
shadow3dGroup->addChild(new TexImageCubeArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
|
|
}
|
|
}
|
|
|
|
// glTexSubImage3D() PBO cases.
|
|
{
|
|
tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
|
|
addChild(pboGroup);
|
|
|
|
static const struct
|
|
{
|
|
const char* name;
|
|
deUint32 format;
|
|
int size;
|
|
int depth;
|
|
int subX;
|
|
int subY;
|
|
int subZ;
|
|
int subW;
|
|
int subH;
|
|
int subD;
|
|
int imageHeight;
|
|
int rowLength;
|
|
int skipImages;
|
|
int skipRows;
|
|
int skipPixels;
|
|
int alignment;
|
|
int offset;
|
|
} paramCases[] =
|
|
{
|
|
{ "rgb8_offset", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 0, 0, 0, 0, 4, 67 },
|
|
{ "rgb8_image_height", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 26, 0, 0, 0, 0, 4, 0 },
|
|
{ "rgb8_row_length", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 27, 0, 0, 0, 4, 0 },
|
|
{ "rgb8_skip_images", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 0, 3, 0, 0, 4, 0 },
|
|
{ "rgb8_skip_rows", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 22, 0, 0, 3, 0, 4, 0 },
|
|
{ "rgb8_skip_pixels", GL_RGB8, 26, 12, 1, 2, 1, 23, 19, 8, 0, 25, 0, 0, 2, 4, 0 }
|
|
};
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
|
|
{
|
|
pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube_array").c_str(), "",
|
|
colorFormats[ndx].internalFormat,
|
|
26, // Size
|
|
12, // Depth
|
|
1, // Sub X
|
|
2, // Sub Y
|
|
0, // Sub Z
|
|
23, // Sub W
|
|
19, // Sub H
|
|
8, // Sub D
|
|
0, // Image height
|
|
0, // Row length
|
|
0, // Skip images
|
|
0, // Skip rows
|
|
0, // Skip pixels
|
|
4, // Alignment
|
|
0 /* offset */));
|
|
}
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
|
|
{
|
|
pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube_array").c_str(), "",
|
|
paramCases[ndx].format,
|
|
paramCases[ndx].size,
|
|
paramCases[ndx].depth,
|
|
paramCases[ndx].subX,
|
|
paramCases[ndx].subY,
|
|
paramCases[ndx].subZ,
|
|
paramCases[ndx].subW,
|
|
paramCases[ndx].subH,
|
|
paramCases[ndx].subD,
|
|
paramCases[ndx].imageHeight,
|
|
paramCases[ndx].rowLength,
|
|
paramCases[ndx].skipImages,
|
|
paramCases[ndx].skipRows,
|
|
paramCases[ndx].skipPixels,
|
|
paramCases[ndx].alignment,
|
|
paramCases[ndx].offset));
|
|
}
|
|
}
|
|
|
|
// glTexSubImage3D() depth cases.
|
|
{
|
|
tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
|
|
addChild(shadow3dGroup);
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
|
|
{
|
|
const int texCubeArraySize = 57;
|
|
const int texCubeArrayLayers = 6;
|
|
|
|
shadow3dGroup->addChild(new TexSubImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayLayers));
|
|
}
|
|
}
|
|
|
|
// glTexStorage3D() cases.
|
|
{
|
|
tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
|
|
addChild(texStorageGroup);
|
|
|
|
// All formats.
|
|
tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
|
|
texStorageGroup->addChild(formatGroup);
|
|
|
|
// Color formats.
|
|
for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
|
|
{
|
|
const char* fmtName = colorFormats[formatNdx].name;
|
|
deUint32 internalFormat = colorFormats[formatNdx].internalFormat;
|
|
const int texCubeArraySize = 57;
|
|
const int texCubeArrayLayers = 6;
|
|
int texCubeArrayLevels = maxLevelCount(texCubeArraySize);
|
|
|
|
formatGroup->addChild(new BasicTexStorageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
|
|
}
|
|
|
|
// Depth/stencil formats (only 2D texture array is supported).
|
|
for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
|
|
{
|
|
const char* fmtName = depthStencilFormats[formatNdx].name;
|
|
deUint32 internalFormat = depthStencilFormats[formatNdx].internalFormat;
|
|
const int texCubeArraySize = 57;
|
|
const int texCubeArrayLayers = 6;
|
|
int texCubeArrayLevels = maxLevelCount(texCubeArraySize);
|
|
|
|
formatGroup->addChild(new BasicTexStorageCubeArrayCase (m_context, (string(fmtName) + "_cube_array").c_str(), "", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
|
|
}
|
|
|
|
// Sizes.
|
|
static const struct
|
|
{
|
|
int size;
|
|
int layers;
|
|
int levels;
|
|
} texCubeArraySizes[] =
|
|
{
|
|
// Sz La Le
|
|
{ 1, 6, 1 },
|
|
{ 2, 6, 2 },
|
|
{ 32, 6, 3 },
|
|
{ 64, 6, 4 },
|
|
{ 57, 12, 1 },
|
|
{ 57, 12, 2 },
|
|
{ 57, 12, 6 }
|
|
};
|
|
|
|
tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage3D() with various sizes");
|
|
texStorageGroup->addChild(sizeGroup);
|
|
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(texCubeArraySizes); ndx++)
|
|
{
|
|
const deUint32 format = GL_RGBA8;
|
|
int size = texCubeArraySizes[ndx].size;
|
|
int layers = texCubeArraySizes[ndx].layers;
|
|
int levels = texCubeArraySizes[ndx].levels;
|
|
string name = string("cube_array_") + de::toString(size) + "x" + de::toString(size) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
|
|
|
|
sizeGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, name.c_str(), "", format, size, layers, levels));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // Functional
|
|
} // gles3
|
|
} // deqp
|