blob: 569a355356efc12999cf980f0fb2f7a2f68063ca [file] [log] [blame]
#ifndef _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_HPP
#define _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_HPP
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2014-2016 The Khronos Group Inc.
*
* 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
*/ /*-------------------------------------------------------------------*/
/*!
* \file esextcGPUShader5TextureGatherOffset.hpp
* \brief gpu_shader5 extension - texture gather offset tests (Test 9 and 10)
*/ /*-------------------------------------------------------------------*/
#include "../esextcTestCaseBase.hpp"
#include <string>
#include <vector>
namespace glcts
{
/** Base class for texture gather offset tests (9, 10 and 11)
*
**/
class GPUShader5TextureGatherOffsetTestBase : public TestCaseBase
{
public:
/* Public methods */
virtual void deinit(void);
virtual IterateResult iterate(void);
protected:
/* Protected types */
struct VertexBufferInfo
{
const glw::GLchar* attribute_name;
glw::GLuint n_components;
glw::GLenum type;
glw::GLvoid* data;
glw::GLuint data_size;
};
/* Protected methods */
GPUShader5TextureGatherOffsetTestBase(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GPUShader5TextureGatherOffsetTestBase(void)
{
}
virtual void initTest(void);
/* To be implemented by inheriting classes */
virtual void getBorderColor(glw::GLfloat out_color[4]) = 0;
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts) = 0;
virtual void getTextureInfo(glw::GLuint& out_width, glw::GLenum& out_texture_internal_format,
glw::GLenum& out_texture_format, glw::GLenum& out_texture_type,
glw::GLuint& out_bytes_per_pixel) = 0;
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode) = 0;
virtual void getTransformFeedBackDetails(glw::GLuint& buffer_size,
std::vector<const glw::GLchar*>& captured_varyings) = 0;
virtual void isTextureArray(bool& out_is_texture_array) = 0;
virtual void prepareTextureData(glw::GLubyte* data) = 0;
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos) = 0;
virtual bool verifyResult(const void* result_data) = 0;
/* Utilities */
void logArray(const glw::GLint* data, unsigned int length, const char* description);
void logCoordinates(unsigned int index);
/* Protected fields */
/* GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET and GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET pname values */
glw::GLint m_min_texture_gather_offset;
glw::GLint m_max_texture_gather_offset;
/* Number of drawn vertices */
static const unsigned int m_n_vertices;
/* Number of components in captured varyings */
static const unsigned int m_n_components_per_varying;
private:
/* Private methods */
void prepareProgramInput();
void prepareTexture();
void prepareVertexBufferInfoForCoordinates();
void setCoordinatesData(glw::GLfloat x, glw::GLfloat y, unsigned int index);
void setCoordinatesData(glw::GLfloat x, glw::GLfloat y, glw::GLfloat z, unsigned int index);
/* Private fields */
/* Program and shader ids */
glw::GLuint m_fragment_shader_id;
glw::GLuint m_program_object_id;
glw::GLuint m_vertex_shader_id;
/* Vertex array object */
glw::GLuint m_vertex_array_object_id;
/* Texture id */
glw::GLuint m_texture_object_id;
/* Sampler id */
glw::GLuint m_sampler_object_id;
/* Shaders' code */
static const glw::GLchar* const m_fragment_shader_code;
std::vector<const glw::GLchar*> m_vertex_shader_parts;
/* Name of uniforms */
static const glw::GLchar* const m_sampler_uniform_name;
static const glw::GLchar* const m_reference_sampler_uniform_name;
/* Vertex buffer infos */
std::vector<VertexBufferInfo> m_vertex_buffer_infos;
std::vector<glw::GLuint> m_vertex_buffer_ids;
/* Texture info */
bool m_is_texture_array;
glw::GLuint m_texture_bytes_per_pixel;
glw::GLenum m_texture_format;
glw::GLenum m_texture_internal_format;
glw::GLenum m_texture_type;
glw::GLuint m_texture_size;
glw::GLenum m_texture_wrap_mode;
/* Texture array length */
static const unsigned int m_n_texture_array_length;
/* Name of varyings */
std::vector<const glw::GLchar*> m_captured_varying_names;
/* Size of buffer used for transform feedback */
glw::GLuint m_transform_feedback_buffer_size;
/* Buffer object used in transform feedback */
glw::GLuint m_transform_feedback_buffer_object_id;
/* Storage for texture coordinates */
std::vector<glw::GLfloat> m_coordinates_buffer_data;
/* Number of texture coordinates per vertex */
unsigned int m_n_coordinates_components;
/* Name of texture coordinate attribute */
static const glw::GLchar* const m_coordinates_attribute_name;
/* Configuration of texture coordinate values generation */
static const int m_max_coordinate_value;
static const int m_min_coordinate_value;
static const int m_coordinate_resolution;
};
/** Base class for test 9 and 11
*
**/
class GPUShader5TextureGatherOffsetColorTestBase : public GPUShader5TextureGatherOffsetTestBase
{
protected:
/* Protected types */
struct CapturedVaryings
{
glw::GLint without_offset_0[4];
glw::GLint without_offset_1[4];
glw::GLint without_offset_2[4];
glw::GLint without_offset_3[4];
glw::GLint with_offset_0[4];
glw::GLint with_offset_1[4];
glw::GLint with_offset_2[4];
glw::GLint with_offset_3[4];
};
/* Protected methods */
GPUShader5TextureGatherOffsetColorTestBase(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GPUShader5TextureGatherOffsetColorTestBase(void)
{
}
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getBorderColor(glw::GLfloat out_color[4]);
virtual void getTextureInfo(glw::GLuint& out_size, glw::GLenum& out_texture_internal_format,
glw::GLenum& out_texture_format, glw::GLenum& out_texture_type,
glw::GLuint& out_bytes_per_pixel);
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getTransformFeedBackDetails(glw::GLuint& out_buffer_size,
std::vector<const glw::GLchar*>& out_captured_varyings);
virtual void isTextureArray(bool& out_is_texture_array);
virtual void prepareTextureData(glw::GLubyte* data);
virtual bool verifyResult(const void* result_data);
/* Methods to be implemented by child classes */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index,
unsigned int m_texture_size) = 0;
/* Utilities */
void logVaryings(const CapturedVaryings& varyings);
private:
/* Texture size */
static const glw::GLuint m_texture_size;
/* Number of varyings captured per vertex */
unsigned int m_n_varyings_per_vertex;
};
/** Base class for test 10 and 11
*
**/
class GPUShader5TextureGatherOffsetDepthTestBase : public GPUShader5TextureGatherOffsetTestBase
{
protected:
/* Protected types */
struct CapturedVaryings
{
glw::GLint floor_tex_coord[4];
glw::GLint without_offset[4];
glw::GLint with_offset[4];
};
/* Protected methods */
GPUShader5TextureGatherOffsetDepthTestBase(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GPUShader5TextureGatherOffsetDepthTestBase(void)
{
}
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getBorderColor(glw::GLfloat out_color[4]);
virtual void getTextureInfo(glw::GLuint& out_width, glw::GLenum& out_texture_internal_format,
glw::GLenum& out_texture_format, glw::GLenum& out_texture_type,
glw::GLuint& out_bytes_per_pixel);
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getTransformFeedBackDetails(glw::GLuint& out_buffer_size,
std::vector<const glw::GLchar*>& out_captured_varyings);
virtual void isTextureArray(bool& out_is_texture_array);
virtual void prepareTextureData(glw::GLubyte* data);
virtual bool verifyResult(const void* result_data);
/* Methods to be implemented by child classes */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size) = 0;
virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings);
/* Utilities */
void logVaryings(const CapturedVaryings& varyings);
private:
/* Texture size */
static const glw::GLuint m_texture_size;
/* Number of varyings captured per vertex */
unsigned int m_n_varyings_per_vertex;
};
/** Implementation of "Test 9" from CTS_EXT_gpu_shader5. Test description follows:
*
* Test whether using non constant offsets in the textureGatherOffset
* and constant offsets in the textureGatherOffsets family of
* functions works as expected for sampler2D and sampler2DArray and
* GL_REPEAT wrap mode.
*
* Category: API,
* Functional Test.
*
* Create a 64 x 64 texture with internal format GL_RGBA32I.
*
* Set both GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER to GL_NEAREST.
*
* Set both GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_REPEAT.
*
* Fill the 4 components of each texel with values corresponding to texel
* row and column number (x,y) -> (x,y,x,y)
*
* Write a vertex shader that defines:
*
* uniform isampler2D sampler;
*
* in ivec2 tgoOffset;
* in vec2 texCoords;
*
* out ivec4 withoutOffset0;
* out ivec4 withOffset0;
*
* out ivec4 withoutOffset1;
* out ivec4 withOffset1;
*
* out ivec4 withoutOffset2;
* out ivec4 withOffset2;
*
* out ivec4 withoutOffset3;
* out ivec4 withOffset3;
*
* Bind the sampler to texture unit the texture we created is assigned to.
*
* Initialize a buffer object to be assigned as input attribute tgoOffset
* data source. The buffer object should hold 128 integer tuples. Fill it
* with some random integer values but falling into a range of
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,
* MAX_PROGRAM_TEXTURE_GATHER_OFFSET).
*
* Initialize a buffer object to be assigned as input attribute texCoords
* data source. The buffer object should hold 128 elements. Fill the first
* 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the
* rest with some random float values in the range [-8.0..8.0].
*
* In the vertex shader perform the following operation:
*
* withoutOffset0 = textureGather(sampler, texCoords, 0);
* withOffset0 = textureGatherOffset(sampler, texCoords, tgoOffset, 0);
*
* withoutOffset1 = textureGather(sampler, texCoords, 1);
* withOffset1 = textureGatherOffset(sampler, texCoords, tgoOffset, 1);
*
* withoutOffset2 = textureGather(sampler, texCoords, 2);
* withOffset2 = textureGatherOffset(sampler, texCoords, tgoOffset, 2);
*
* withoutOffset3 = textureGather(sampler, texCoords, 3);
* withOffset3 = textureGatherOffset(sampler, texCoords, tgoOffset, 3);
*
* Configure transform feedback to capture the values of withoutOffset*
* and withOffset*.
*
* Write a boilerplate fragment shader.
*
* Create a program from the above vertex shader and fragment shader
* and use it.
*
* Execute a draw call glDrawArrays(GL_POINTS, 0, 128).
*
* Copy the captured results from the buffer objects bound to transform
* feedback binding points.
*
* Using the captured values for each of the 128 results compute
*
* (Pseudocode)
*
* i = 0...127
*
* ivec2 referenceOffset = offsets[i];
*
* if(referenceOffset[0] < 0 )
* {
* referenceOffset[0] = sizeX - (referenceOffset[0] % sizeX);
* }
* if(referenceOffset[1] < 0 )
* {
* referenceOffset[1] = sizeY - (referenceOffset[1] % sizeY);
* }
*
* for(int tNr = 0 tNr < 4; ++tNr)
* {
* ivec2 referenceTexelValue01 = ivec2(
* ((tgoResults[i].withoutOffset0[tNr] + referenceOffset[0]) % sizeX),
* ((tgoResults[i].withoutOffset1[tNr] + referenceOffset[1]) % sizeY));
*
* ivec2 referenceTexelValue23 = ivec2(
* ((tgoResults[i].withoutOffset2[tNr] + referenceOffset[0]) % sizeX),
* ((tgoResults[i].withoutOffset3[tNr] + referenceOffset[1]) % sizeY));
*
* ivec2 texelValue01 = ivec2(
* tgoResults[i].withOffset0[tNr], tgoResults[i].withOffset1[tNr]);
*
* ivec2 texelValue23 = ivec2(
* tgoResults[i].withOffset2[tNr], tgoResults[i].withOffset3[tNr]);
* }
*
* The test passes if in all cases we have
* referenceTexelValue01 == texelValue01 and
* referenceTexelValue23 == texelValue23.
*
* Repeat the same type of test for sampler2DArray.
*
* Repeat the same type of test using textureGatherOffsets instead of
* textureGatherOffset inputing constant offsets
* offsets[4] = {
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, MIN_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET, MAX_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MAX_PROGRAM_TEXTURE_GATHER_OFFSET, MIN_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MAX_PROGRAM_TEXTURE_GATHER_OFFSET, MAX_PROGRAM_TEXTURE_GATHER_OFFSET)
* };
**/
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2D, function textureGatherOffset
*/
class GPUShader5TextureGatherOffsetColor2DRepeatCaseTest : public GPUShader5TextureGatherOffsetColorTestBase
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos);
/* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
/* Utilities */
void getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset, unsigned int index);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
/* Number of offsets per vertex */
static const unsigned int m_n_offsets_components;
/* Name of offset attribute */
static const glw::GLchar* const m_offsets_attribute_name;
/* Storage for offsets */
std::vector<glw::GLint> m_offsets_buffer_data;
};
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2DArray, function textureGatherOffset
*/
class GPUShader5TextureGatherOffsetColor2DArrayCaseTest : public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetColor2DArrayCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetColor2DArrayCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void isTextureArray(bool& out_is_texture_array);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2D, function textureGatherOffsets
*/
class GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest : public GPUShader5TextureGatherOffsetColorTestBase
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos);
/* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code_preamble;
static const glw::GLchar* const m_vertex_shader_code_body;
/* String used for definition of constant offsets */
std::string m_vertex_shader_code_offsets;
};
/** Implementation of "Test 10" from CTS_EXT_gpu_shader5. Test description follows:
*
* Test whether using non constant offsets in the textureGatherOffset
* and constant offsets in the textureGatherOffsets family of
* functions works as expected for sampler2DShadow
* and sampler2DArrayShadow and GL_REPEAT wrap mode.
*
* Category: API,
* Functional Test.
*
* Create a 64 x 64 texture with internal format GL_DEPTH_COMPONENT and
* type GL_FLOAT.
*
* Set both GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER to GL_NEAREST.
*
* Set both GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_REPEAT.
*
* Setup the texture parameters
*
* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
* COMPARE_REF_TO_TEXTURE);
*
* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
*
* Fill each texel with depth value corresponding to its position
* in the texture for the X axis: (x, y) -> (x / sizeX);
*
* Write a vertex shader that defines:
*
* uniform sampler2DShadow sampler;
*
* in ivec2 tgoOffset;
* in vec2 texCoords;
*
* out ivec4 withoutOffset;
* out ivec4 withOffset;
*
* Bind the sampler to texture unit the texture we created is assigned to.
*
* Initialize a buffer object to be assigned as input attribute tgoOffset
* data source. The buffer object should hold 128 integer tuples. Fill it
* with some random integer values but falling into a range of
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,
* MAX_PROGRAM_TEXTURE_GATHER_OFFSET).
*
* Initialize a buffer object to be assigned as input attribute texCoords
* data source. The buffer object should hold 128 elements. Fill the first
* 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the
* rest with some random float values in the range [-8.0..8.0].
*
* In the vertex shader perform the following operation:
*
* withoutOffset = ivec4(0,0,0,0);
* withOffset = ivec4(0,0,0,0);
*
* ivec2 texSize = textureSize2D(sampler, 0);
*
* for(int texelNr = 0 texelNr < texSize.x; ++texelNr)
* {
* float refZ = float(texelNr) / float(texSize.x);
*
* withoutOffset += textureGather( sampler, texCoords, refZ );
* withOffset += textureGatherOffset(sampler,texCoords,offset,refZ);
* }
*
* Configure transform feedback to capture the values of withoutOffset
* and withOffset.
*
* Write a boilerplate fragment shader.
*
* Create a program from the above vertex shader and fragment shader
* and use it.
*
* Execute a draw call glDrawArrays(GL_POINTS, 0, 128).
*
* Copy the captured results from the buffer objects bound to transform
* feedback binding points.
*
* Using the captured values for each of the 128 results compute
*
* (Pseudocode)
*
* i = 0...127
*
* int referenceOffsetX = offsets[i].x;
*
* if(referenceOffsetX < 0 )
* {
* referenceOffsetX = sizeX - (referenceOffsetX % sizeX);
* }
*
* for(int tNr = 0 tNr < 4; ++tNr)
* {
* int referenceTexelValueX =
* (tgoResults[i].withoutOffset[tNr] + referenceOffsetX) % sizeX;
*
* int texelValueX = tgoResults[i].withOffset[tNr];
* }
*
* The test passes if in all cases we have
* referenceTexelValueX == texelValueX.
*
* Repeat the same test for Y axis.
*
* Repeat the same type of test for sampler2DArrayShadow.
*
* Repeat the same type of test using textureGatherOffsets instead of
* textureGatherOffset inputting constant offsets
* offsets[4] = {
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,MIN_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,MAX_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MAX_PROGRAM_TEXTURE_GATHER_OFFSET,MIN_PROGRAM_TEXTURE_GATHER_OFFSET),
* (MAX_PROGRAM_TEXTURE_GATHER_OFFSET,MAX_PROGRAM_TEXTURE_GATHER_OFFSET)
* };
*
**/
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffset, axis X
*/
class GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest : public GPUShader5TextureGatherOffsetDepthTestBase
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos);
/* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
/* Utilities */
void getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset, unsigned int index);
/* Number of offsets per vertex */
static const unsigned int m_n_offsets_components;
/* Name of offset attribute */
static const glw::GLchar* const m_offsets_attribute_name;
/* Storage for offsets */
std::vector<glw::GLint> m_offsets_buffer_data;
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffset, axis Y
*/
class GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareTextureData(glw::GLubyte* data);
/* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadowArray, function textureGatherOffset, axis X
*/
class GPUShader5TextureGatherOffsetDepth2DArrayCaseTest : public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void isTextureArray(bool& out_is_texture_array);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_REPEAT, sampler isampler2DShadow, function textureGatherOffsets, axis X
*/
class GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest : public GPUShader5TextureGatherOffsetDepthTestBase
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos);
/* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code_preamble;
static const glw::GLchar* const m_vertex_shader_code_body;
/* String used for definition of constant offsets */
std::string m_vertex_shader_code_offsets;
};
/** Implementation of "Test 11" from CTS_EXT_gpu_shader5. Test description follows:
*
* Test whether using non constant offsets in the textureGatherOffset
* function works as expected for sampler2D and CLAMP_TO_BORDER_EXT
* ( CLAMP_TO_EDGE ) wrap mode.
*
* Category: API,
* Functional Test,
* dependency with EXT_texture_border_clamp.
*
* Create two (lets name them A and B) 64 (texWidth) x 64 (texHeight)
* textures with internal format GL_RGBA32I.
*
* Bind texture A to texture unit 0.
* Bind texture B to texture unit 1.
*
* Set for both textures GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER
* to GL_NEAREST.
*
* For the A texture set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T
* to CLAMP_TO_BORDER_EXT.
* For the B texture set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T
* to CLAMP_TO_BORDER_EXT ( CLAMP TO EDGE ).
*
* For both textures fill the 4 components of each texel with values
* corresponding to texel row and column number (x,y) -> (x,y,x,y)
*
* Set the GL_TEXTURE_BORDER_COLOR_EXT to (-1,-1,-1,-1).
*
* Write a vertex shader that defines:
*
* uniform isampler2D samplerWithoutOffset;
* uniform isampler2D samplerWithOffset;
*
* in ivec2 tgoOffset;
* in vec2 texCoords;
*
* out ivec4 withoutOffset0;
* out ivec4 withoutOffset1;
* out ivec2 intFloorTexCoords;
*
* out ivec4 withOffset0;
* out ivec4 withOffset1;
* out ivec4 withOffset2;
* out ivec4 withOffset3;
*
* Bind samplerWithoutOffset to texture unit 0.
* Bind samplerWithOffset to texture unit 1.
*
* Initialize a buffer object to be assigned as input attribute tgoOffset
* data source. The buffer object should hold 128 integer tuples. Fill it
* with some random integer values but falling into a range of
* (MIN_PROGRAM_TEXTURE_GATHER_OFFSET,
* MAX_PROGRAM_TEXTURE_GATHER_OFFSET).
*
* Initialize a buffer object to be assigned as input attribute texCoords
* data source. The buffer object should hold 128 elements. Fill the first
* 4 tuples with (0.0, 0.0) , (0.0, 1.0), (1.0, 0.0), (1.0, 1.0) and the
* rest with some random float values in the range [-8.0..8.0].
*
* In the vertex shader perform the following operation:
*
* vec2 floorTexCoords = floor(texCoords);
* vec2 fractTexCoords = texCoords - floorTexCoords;
*
* withoutOffset0 = textureGather(samplerWithoutOffset,fractTexCoords, 0);
* withoutOffset1 = textureGather(samplerWithoutOffset,fractTexCoords, 1);
* intFloorTexCoords = ivec2(int(floorTexCoords.x),int(floorTexCoords.y));
*
* withOffset0 = textureGatherOffset(samplerWithOffset,
* texCoords, tgoOffset, 0);
* withOffset1 = textureGatherOffset(samplerWithOffset,
* texCoords, tgoOffset, 1);
* withOffset2 = textureGatherOffset(samplerWithOffset,
* texCoords, tgoOffset, 2);
* withOffset3 = textureGatherOffset(samplerWithOffset,
* texCoords, tgoOffset, 3);
*
* Configure transform feedback to capture the values of withoutOffset*,
* withOffset* and intFloorTexCoords.
*
* Write a boilerplate fragment shader.
*
* Create a program from the above vertex shader and fragment shader
* and use it.
*
* Execute a draw call glDrawArrays(GL_POINTS, 0, 128).
*
* Copy the captured results from the buffer objects bound to transform
* feedback binding points.
*
* Using the captured values for each of the 128 results perform
* the following algorithm:
*
* From the captured withoutOffset0 and withoutOffset1 variables extract
* 4 texelPos values
*
* (Pseudocode)
*
* texelPos[i] = ivec2( withoutOffset0[i] , withoutOffset1[i] );
*
* Find a texel that has not been clamped. It's value should be
* different than (texWidth, texHeight). Let's asume that the found
* texel has index 'foundIndex'.
*
* If we can't find such texel we must throw an exception, because it means
* that the sampling algorithm has failed.
*
* Extract the offset that has to be applied to the chosen texel to get it's
* absolute position (the one we would get if we haven't clamped the texture
* coordinates for textureGather to the range [0,1])
*
* (Pseudocode)
*
* ivec2 absoluteOffset = ivec2( intFloorTexCoords.x * texWidth ,
* intFloorTexCoords.y * texHeight );
*
* Next apply the offset to the texel position
*
* (Pseudocode)
*
* texelAbsolutePos[foundIndex] = texelPos[foundIndex] + absoluteOffset;
*
* Now we have to set the absolute positions of the remaining 3 texels.
* We can do this because the foundIndex gives us information which
* texel we are dealing with in a 2x2 texel matrix returned by
* textureGather. The remaining texels will have their absolute positions
* computed by adding or substacting 1 to their x and y components
* depending on their position in the matrix relative to foundIndex.
*
* In the next step we have to apply the offset used in
* textureGatherOffset function to each of the absolute positions.
*
* (Pseudocode)
*
* texelAbsolutePos[i] += tgoOffset;
*
* We have to examine each absolute position in order to know if it should
* been clamped or not.
*
* In case of CLAMP_TO_BORDER_EXT if the absolute position goes beyond the
* texture bounds set it to value of GL_TEXTURE_BORDER_COLOR_EXT -> (-1,-1)
*
* In case of CLAMP_TO_EDGE if the absolute position goes beyond the
* texture bounds we have to clamp the value of absolute position
* to the edge that has been crossed.
*
* The test passes for each of the 4 absolute positions we have
*
* (Pseudocode)
*
* texelAbsolutePos[i] == ivec2( withOffset0[i], withOffset1[i] ) and
* texelAbsolutePos[i] == ivec2( withOffset2[i], withOffset3[i] ).
**/
/** Test configuration: wrap mode GL_CLAMP_TO_BORDER_EXT, sampler isampler2D, function textureGatherOffset
*/
class GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest
: public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
/* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
virtual void initTest(void);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_CLAMP_TO_EDGE, sampler isampler2D, function textureGatherOffset
*/
class GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest
: public GPUShader5TextureGatherOffsetColor2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
/* Virtual methods from GPUShader5TextureGatherOffsetColorTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
virtual void initTest(void);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_CLAMP_TO_BORDER_EXT, sampler isampler2DShadow, function textureGatherOffset, axis X
*/
class GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest
: public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
virtual void prepareVertexBuffersData(std::vector<VertexBufferInfo>& vertex_buffer_infos);
/* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings);
virtual void initTest(void);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
/** Test configuration: wrap mode GL_CLAMP_TO_EDGE, sampler isampler2DShadow, function textureGatherOffset, axis X
*/
class GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest
: public GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest
{
public:
/* Public methods */
GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(void)
{
}
protected:
/* Protected methods */
/* Virtual methods from GPUShader5TextureGatherOffsetTestBase */
virtual void getTextureWrapMode(glw::GLenum& out_wrap_mode);
virtual void getShaderParts(std::vector<const glw::GLchar*>& out_vertex_shader_parts);
/* Virtual methods from GPUShader5TextureGatherOffsetDepthTestBase */
virtual bool checkResult(const CapturedVaryings& captured_data, unsigned int index, unsigned int texture_size);
virtual void getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings);
virtual void initTest(void);
private:
/* Private fields */
/* Vertex shader code */
static const glw::GLchar* const m_vertex_shader_code;
};
} /* glcts */
#endif // _ESEXTCGPUSHADER5TEXTUREGATHEROFFSET_HPP