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.
348 lines
13 KiB
348 lines
13 KiB
#ifndef _GLSLONGSTRESSCASE_HPP
|
|
#define _GLSLONGSTRESSCASE_HPP
|
|
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL (ES) 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 Parametrized, long-running stress case.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "tcuDefs.hpp"
|
|
#include "tcuTestCase.hpp"
|
|
#include "tcuTexture.hpp"
|
|
#include "tcuMatrix.hpp"
|
|
#include "gluRenderContext.hpp"
|
|
#include "gluShaderUtil.hpp"
|
|
#include "glsTextureTestUtil.hpp"
|
|
#include "deRandom.hpp"
|
|
#include "deSharedPtr.hpp"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gls
|
|
{
|
|
|
|
namespace LongStressCaseInternal
|
|
{
|
|
|
|
template <typename T> class GLObjectManager;
|
|
class Program;
|
|
class Buffer;
|
|
class Texture;
|
|
class DebugInfoRenderer;
|
|
|
|
}
|
|
|
|
struct VarSpec
|
|
{
|
|
union Value
|
|
{
|
|
float f[4*4]; // \note Matrices are stored in column major order.
|
|
int i[4];
|
|
};
|
|
|
|
std::string name;
|
|
glu::DataType type;
|
|
Value minValue;
|
|
Value maxValue;
|
|
|
|
template <typename T>
|
|
VarSpec (const std::string& name_, const T& minValue_, const T& maxValue_) : name(name_) { set(minValue_, maxValue_); }
|
|
|
|
template <typename T>
|
|
VarSpec (const std::string& name_, const T& value) : name(name_) { set(value, value); }
|
|
|
|
void set (float minValue_, float maxValue_)
|
|
{
|
|
type = glu::TYPE_FLOAT;
|
|
minValue.f[0] = minValue_;
|
|
maxValue.f[0] = maxValue_;
|
|
}
|
|
|
|
template <int ValSize>
|
|
void set (const tcu::Vector<float, ValSize>& minValue_, const tcu::Vector<float, ValSize>& maxValue_)
|
|
{
|
|
type = glu::getDataTypeFloatVec(ValSize);
|
|
vecToArr(minValue_, minValue.f);
|
|
vecToArr(maxValue_, maxValue.f);
|
|
}
|
|
|
|
template <int ValRows, int ValCols>
|
|
void set (const tcu::Matrix<float, ValRows, ValCols>& minValue_, const tcu::Matrix<float, ValRows, ValCols>& maxValue_)
|
|
{
|
|
type = glu::getDataTypeMatrix(ValCols, ValRows);
|
|
matToArr(minValue_, minValue.f);
|
|
matToArr(maxValue_, maxValue.f);
|
|
}
|
|
|
|
void set (int minValue_, int maxValue_)
|
|
{
|
|
type = glu::TYPE_INT;
|
|
minValue.i[0] = minValue_;
|
|
maxValue.i[0] = maxValue_;
|
|
}
|
|
|
|
template <int ValSize>
|
|
void set (const tcu::Vector<int, ValSize>& minValue_, const tcu::Vector<int, ValSize>& maxValue_)
|
|
{
|
|
type = glu::getDataTypeVector(glu::TYPE_INT, ValSize);
|
|
vecToArr(minValue_, minValue.i);
|
|
vecToArr(maxValue_, maxValue.i);
|
|
}
|
|
|
|
private:
|
|
template <typename T, int SrcSize, int DstSize>
|
|
static inline void vecToArr (const tcu::Vector<T, SrcSize>& src, T (&dst)[DstSize])
|
|
{
|
|
DE_STATIC_ASSERT(DstSize >= SrcSize);
|
|
for (int i = 0; i < SrcSize; i++)
|
|
dst[i] = src[i];
|
|
}
|
|
|
|
template <int ValRows, int ValCols, int DstSize>
|
|
static inline void matToArr (const tcu::Matrix<float, ValRows, ValCols>& src, float (&dst)[DstSize])
|
|
{
|
|
DE_STATIC_ASSERT(DstSize >= ValRows*ValCols);
|
|
tcu::Array<float, ValRows*ValCols> data = src.getColumnMajorData();
|
|
for (int i = 0; i < ValRows*ValCols; i++)
|
|
dst[i] = data[i];
|
|
}
|
|
};
|
|
|
|
struct TextureSpec
|
|
{
|
|
glu::TextureTestUtil::TextureType textureType;
|
|
deUint32 textureUnit;
|
|
int width;
|
|
int height;
|
|
deUint32 format;
|
|
deUint32 dataType;
|
|
deUint32 internalFormat;
|
|
bool useMipmap;
|
|
deUint32 minFilter;
|
|
deUint32 magFilter;
|
|
deUint32 sWrap;
|
|
deUint32 tWrap;
|
|
tcu::Vec4 minValue;
|
|
tcu::Vec4 maxValue;
|
|
|
|
TextureSpec (const glu::TextureTestUtil::TextureType texType,
|
|
const deUint32 unit,
|
|
const int width_,
|
|
const int height_,
|
|
const deUint32 format_,
|
|
const deUint32 dataType_,
|
|
const deUint32 internalFormat_,
|
|
const bool useMipmap_,
|
|
const deUint32 minFilter_,
|
|
const deUint32 magFilter_,
|
|
const deUint32 sWrap_,
|
|
const deUint32 tWrap_,
|
|
const tcu::Vec4& minValue_,
|
|
const tcu::Vec4& maxValue_)
|
|
: textureType (texType)
|
|
, textureUnit (unit)
|
|
, width (width_)
|
|
, height (height_)
|
|
, format (format_)
|
|
, dataType (dataType_)
|
|
, internalFormat (internalFormat_)
|
|
, useMipmap (useMipmap_)
|
|
, minFilter (minFilter_)
|
|
, magFilter (magFilter_)
|
|
, sWrap (sWrap_)
|
|
, tWrap (tWrap_)
|
|
, minValue (minValue_)
|
|
, maxValue (maxValue_)
|
|
{
|
|
}
|
|
};
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Struct for a shader program sources and related data
|
|
*
|
|
* A ProgramContext holds a program's vertex and fragment shader sources
|
|
* as well as specifications of its attributes, uniforms, and textures.
|
|
* When given to a StressCase, the string ${NS} is replaced by a magic
|
|
* number that varies between different compilations of the same program;
|
|
* the same replacement is done in attributes' and uniforms' names. This
|
|
* can be used to avoid shader caching by the GL, by e.g. suffixing each
|
|
* attribute, uniform and varying name with ${NS} in the shader source.
|
|
*//*--------------------------------------------------------------------*/
|
|
struct ProgramContext
|
|
{
|
|
std::string vertexSource;
|
|
std::string fragmentSource;
|
|
std::vector<VarSpec> attributes;
|
|
std::vector<VarSpec> uniforms;
|
|
|
|
std::vector<TextureSpec> textureSpecs; //!< \note If multiple textures have same unit, one of them is picked randomly.
|
|
|
|
std::string positionAttrName; //!< \note Position attribute may get a bit more careful handling than just complete random.
|
|
|
|
ProgramContext (const char* const vtxShaderSource_,
|
|
const char* const fragShaderSource_,
|
|
const char* const positionAttrName_)
|
|
: vertexSource (vtxShaderSource_)
|
|
, fragmentSource (fragShaderSource_)
|
|
, positionAttrName (positionAttrName_)
|
|
{
|
|
}
|
|
};
|
|
|
|
class LongStressCase : public tcu::TestCase
|
|
{
|
|
public:
|
|
//! Probabilities for actions that may be taken on each iteration. \note The texture and buffer specific actions are randomized per texture or buffer.
|
|
struct FeatureProbabilities
|
|
{
|
|
float rebuildProgram; //!< Rebuild program, with variable name-mangling.
|
|
float reuploadTexture; //!< Reupload texture, even if it already exists and has been uploaded.
|
|
float reuploadBuffer; //!< Reupload buffer, even if it already exists and has been uploaded.
|
|
float reuploadWithTexImage; //!< Use glTexImage*() when re-uploading texture, not glTexSubImage*().
|
|
float reuploadWithBufferData; //!< Use glBufferData() when re-uploading buffer, not glBufferSubData().
|
|
float deleteTexture; //!< Delete texture at end of iteration, even if we could re-use it.
|
|
float deleteBuffer; //!< Delete buffer at end of iteration, even if we could re-use it.
|
|
float wastefulTextureMemoryUsage; //!< Don't re-use a texture, and don't delete it until given memory limit is hit.
|
|
float wastefulBufferMemoryUsage; //!< Don't re-use a buffer, and don't delete it until given memory limit is hit.
|
|
float clientMemoryAttributeData; //!< Use client memory for vertex attribute data when drawing (instead of GL buffers).
|
|
float clientMemoryIndexData; //!< Use client memory for vertex indices when drawing (instead of GL buffers).
|
|
float randomBufferUploadTarget; //!< Use a random target when setting buffer data (i.e. not necessarily the one it'll be ultimately bound to).
|
|
float randomBufferUsage; //!< Use a random buffer usage parameter with glBufferData(), instead of the ones specified as params for the case.
|
|
float useDrawArrays; //!< Use glDrawArrays() instead of glDrawElements().
|
|
float separateAttributeBuffers; //!< Give each vertex attribute its own buffer.
|
|
|
|
// Named parameter idiom: helpers that can be used when making temporaries, e.g. FeatureProbabilities().pReuploadTexture(1.0f).pReuploadWithTexImage(1.0f)
|
|
FeatureProbabilities& pRebuildProgram (const float prob) { rebuildProgram = prob; return *this; }
|
|
FeatureProbabilities& pReuploadTexture (const float prob) { reuploadTexture = prob; return *this; }
|
|
FeatureProbabilities& pReuploadBuffer (const float prob) { reuploadBuffer = prob; return *this; }
|
|
FeatureProbabilities& pReuploadWithTexImage (const float prob) { reuploadWithTexImage = prob; return *this; }
|
|
FeatureProbabilities& pReuploadWithBufferData (const float prob) { reuploadWithBufferData = prob; return *this; }
|
|
FeatureProbabilities& pDeleteTexture (const float prob) { deleteTexture = prob; return *this; }
|
|
FeatureProbabilities& pDeleteBuffer (const float prob) { deleteBuffer = prob; return *this; }
|
|
FeatureProbabilities& pWastefulTextureMemoryUsage (const float prob) { wastefulTextureMemoryUsage = prob; return *this; }
|
|
FeatureProbabilities& pWastefulBufferMemoryUsage (const float prob) { wastefulBufferMemoryUsage = prob; return *this; }
|
|
FeatureProbabilities& pClientMemoryAttributeData (const float prob) { clientMemoryAttributeData = prob; return *this; }
|
|
FeatureProbabilities& pClientMemoryIndexData (const float prob) { clientMemoryIndexData = prob; return *this; }
|
|
FeatureProbabilities& pRandomBufferUploadTarget (const float prob) { randomBufferUploadTarget = prob; return *this; }
|
|
FeatureProbabilities& pRandomBufferUsage (const float prob) { randomBufferUsage = prob; return *this; }
|
|
FeatureProbabilities& pUseDrawArrays (const float prob) { useDrawArrays = prob; return *this; }
|
|
FeatureProbabilities& pSeparateAttribBuffers (const float prob) { separateAttributeBuffers = prob; return *this; }
|
|
|
|
FeatureProbabilities (void)
|
|
: rebuildProgram (0.0f)
|
|
, reuploadTexture (0.0f)
|
|
, reuploadBuffer (0.0f)
|
|
, reuploadWithTexImage (0.0f)
|
|
, reuploadWithBufferData (0.0f)
|
|
, deleteTexture (0.0f)
|
|
, deleteBuffer (0.0f)
|
|
, wastefulTextureMemoryUsage (0.0f)
|
|
, wastefulBufferMemoryUsage (0.0f)
|
|
, clientMemoryAttributeData (0.0f)
|
|
, clientMemoryIndexData (0.0f)
|
|
, randomBufferUploadTarget (0.0f)
|
|
, randomBufferUsage (0.0f)
|
|
, useDrawArrays (0.0f)
|
|
, separateAttributeBuffers (0.0f)
|
|
{
|
|
}
|
|
};
|
|
|
|
LongStressCase (tcu::TestContext& testCtx,
|
|
const glu::RenderContext& renderCtx,
|
|
const char* name,
|
|
const char* desc,
|
|
int maxTexMemoryUsageBytes, //!< Approximate upper bound on GL texture memory usage.
|
|
int maxBufMemoryUsageBytes, //!< Approximate upper bound on GL buffer memory usage.
|
|
int numDrawCallsPerIteration,
|
|
int numTrianglesPerDrawCall,
|
|
const std::vector<ProgramContext>& programContexts,
|
|
const FeatureProbabilities& probabilities,
|
|
deUint32 indexBufferUsage,
|
|
deUint32 attrBufferUsage,
|
|
int redundantBufferFactor = 1,
|
|
bool showDebugInfo = false);
|
|
|
|
~LongStressCase (void);
|
|
|
|
void init (void);
|
|
void deinit (void);
|
|
|
|
IterateResult iterate (void);
|
|
|
|
private:
|
|
LongStressCase (const LongStressCase&);
|
|
LongStressCase& operator= (const LongStressCase&);
|
|
|
|
const glu::RenderContext& m_renderCtx;
|
|
const int m_maxTexMemoryUsageBytes;
|
|
const int m_maxBufMemoryUsageBytes;
|
|
const int m_numDrawCallsPerIteration;
|
|
const int m_numTrianglesPerDrawCall;
|
|
const int m_numVerticesPerDrawCall;
|
|
const std::vector<ProgramContext> m_programContexts;
|
|
const FeatureProbabilities m_probabilities;
|
|
const deUint32 m_indexBufferUsage;
|
|
const deUint32 m_attrBufferUsage;
|
|
const int m_redundantBufferFactor; //!< By what factor we allocate redundant buffers. Default is 1, i.e. no redundancy.
|
|
const bool m_showDebugInfo;
|
|
|
|
const int m_numIterations;
|
|
const bool m_isGLES3;
|
|
|
|
int m_currentIteration;
|
|
deUint64 m_startTimeSeconds; //!< Set at beginning of first iteration.
|
|
deUint64 m_lastLogTime;
|
|
int m_lastLogIteration;
|
|
int m_currentLogEntryNdx;
|
|
|
|
de::Random m_rnd;
|
|
LongStressCaseInternal::GLObjectManager<
|
|
LongStressCaseInternal::Program>* m_programs;
|
|
LongStressCaseInternal::GLObjectManager<
|
|
LongStressCaseInternal::Buffer>* m_buffers;
|
|
LongStressCaseInternal::GLObjectManager<
|
|
LongStressCaseInternal::Texture>* m_textures;
|
|
std::vector<deUint16> m_vertexIndices;
|
|
|
|
struct ProgramResources
|
|
{
|
|
std::vector<deUint8> attrDataBuf;
|
|
std::vector<int> attrDataOffsets;
|
|
std::vector<int> attrDataSizes;
|
|
std::vector<de::SharedPtr<tcu::TextureLevel> > dummyTextures;
|
|
std::string shaderNameManglingSuffix;
|
|
};
|
|
|
|
std::vector<ProgramResources> m_programResources;
|
|
|
|
LongStressCaseInternal::DebugInfoRenderer* m_debugInfoRenderer;
|
|
};
|
|
|
|
|
|
} // gls
|
|
} // deqp
|
|
|
|
#endif // _GLSLONGSTRESSCASE_HPP
|